OSDN Git Service

* config/i386/i386.c (x86_sse_partial_regs_for_cvtsd2ss): Remove.
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69
70    ; TLS support
71    (UNSPEC_TP                   15)
72    (UNSPEC_TLS_GD               16)
73    (UNSPEC_TLS_LD_BASE          17)
74
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_SIN                  21)
78    (UNSPEC_COS                  22)
79    (UNSPEC_FNSTSW               24)
80    (UNSPEC_SAHF                 25)
81    (UNSPEC_FSTCW                26)
82    (UNSPEC_ADD_CARRY            27)
83    (UNSPEC_FLDCW                28)
84
85    ; For SSE/MMX support:
86    (UNSPEC_FIX                  30)
87    (UNSPEC_MASKMOV              32)
88    (UNSPEC_MOVMSK               33)
89    (UNSPEC_MOVNT                34)
90    (UNSPEC_MOVA                 38)
91    (UNSPEC_MOVU                 39)
92    (UNSPEC_SHUFFLE              41)
93    (UNSPEC_RCP                  42)
94    (UNSPEC_RSQRT                43)
95    (UNSPEC_SFENCE               44)
96    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
97    (UNSPEC_PAVGUSB              49)
98    (UNSPEC_PFRCP                50)
99    (UNSPEC_PFRCPIT1             51)
100    (UNSPEC_PFRCPIT2             52)
101    (UNSPEC_PFRSQRT              53)
102    (UNSPEC_PFRSQIT1             54)
103    (UNSPEC_PSHUFLW              55)
104    (UNSPEC_PSHUFHW              56)
105    (UNSPEC_MFENCE               59)
106    (UNSPEC_LFENCE               60)
107    (UNSPEC_PSADBW               61)
108    (UNSPEC_ADDSUB               71)
109    (UNSPEC_HADD                 72)
110    (UNSPEC_HSUB                 73)
111    (UNSPEC_MOVSHDUP             74)
112    (UNSPEC_MOVSLDUP             75)
113    (UNSPEC_LDQQU                76)
114    (UNSPEC_MOVDDUP              77)
115
116    ; x87 Floating point
117    (UNSPEC_FPATAN               65)
118    (UNSPEC_FYL2X                66)
119    (UNSPEC_FYL2XP1              67)
120    (UNSPEC_FRNDINT              68)
121    (UNSPEC_F2XM1                69)
122
123    ; x87 Double output FP
124    (UNSPEC_SINCOS_COS           80)
125    (UNSPEC_SINCOS_SIN           81)
126    (UNSPEC_TAN_ONE              82)
127    (UNSPEC_TAN_TAN              83)
128    (UNSPEC_XTRACT_FRACT         84)
129    (UNSPEC_XTRACT_EXP           85)
130    (UNSPEC_FSCALE_FRACT         86)
131    (UNSPEC_FSCALE_EXP           87)
132    (UNSPEC_FPREM_F              88)
133    (UNSPEC_FPREM_U              89)
134    (UNSPEC_FPREM1_F             90)
135    (UNSPEC_FPREM1_U             91)
136
137    ; x87 Rounding
138    (UNSPEC_FRNDINT_FLOOR        96)
139    (UNSPEC_FRNDINT_CEIL         97)
140    (UNSPEC_FRNDINT_TRUNC        98)
141    (UNSPEC_FRNDINT_MASK_PM      99)
142
143    ; REP instruction
144    (UNSPEC_REP                  75)
145
146    (UNSPEC_EH_RETURN            76)
147   ])
148
149 (define_constants
150   [(UNSPECV_BLOCKAGE            0)
151    (UNSPECV_STACK_PROBE         10)
152    (UNSPECV_EMMS                31)
153    (UNSPECV_LDMXCSR             37)
154    (UNSPECV_STMXCSR             40)
155    (UNSPECV_FEMMS               46)
156    (UNSPECV_CLFLUSH             57)
157    (UNSPECV_ALIGN               68)
158    (UNSPECV_MONITOR             69)
159    (UNSPECV_MWAIT               70)
160   ])
161
162 ;; Registers by name.
163 (define_constants
164   [(BP_REG                       6)
165    (SP_REG                       7)
166    (FLAGS_REG                   17)
167    (FPSR_REG                    18)
168    (DIRFLAG_REG                 19)
169   ])
170
171 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
172 ;; from i386.c.
173
174 ;; In C guard expressions, put expressions which may be compile-time
175 ;; constants first.  This allows for better optimization.  For
176 ;; example, write "TARGET_64BIT && reload_completed", not
177 ;; "reload_completed && TARGET_64BIT".
178
179 \f
180 ;; Processor type.  This attribute must exactly match the processor_type
181 ;; enumeration in i386.h.
182 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
183   (const (symbol_ref "ix86_tune")))
184
185 ;; A basic instruction type.  Refinements due to arguments to be
186 ;; provided in other attributes.
187 (define_attr "type"
188   "other,multi,
189    alu,alu1,negnot,imov,imovx,lea,
190    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
191    icmp,test,ibr,setcc,icmov,
192    push,pop,call,callv,leave,
193    str,cld,
194    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint,
195    sselog,sseiadd,sseishft,sseimul,
196    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
197    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
198   (const_string "other"))
199
200 ;; Main data type used by the insn
201 (define_attr "mode"
202   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
203   (const_string "unknown"))
204
205 ;; The CPU unit operations uses.
206 (define_attr "unit" "integer,i387,sse,mmx,unknown"
207   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint")
208            (const_string "i387")
209          (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
210                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
211            (const_string "sse")
212          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
213            (const_string "mmx")
214          (eq_attr "type" "other")
215            (const_string "unknown")]
216          (const_string "integer")))
217
218 ;; The (bounding maximum) length of an instruction immediate.
219 (define_attr "length_immediate" ""
220   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
221            (const_int 0)
222          (eq_attr "unit" "i387,sse,mmx")
223            (const_int 0)
224          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
225                           imul,icmp,push,pop")
226            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
227          (eq_attr "type" "imov,test")
228            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
229          (eq_attr "type" "call")
230            (if_then_else (match_operand 0 "constant_call_address_operand" "")
231              (const_int 4)
232              (const_int 0))
233          (eq_attr "type" "callv")
234            (if_then_else (match_operand 1 "constant_call_address_operand" "")
235              (const_int 4)
236              (const_int 0))
237          ;; We don't know the size before shorten_branches.  Expect
238          ;; the instruction to fit for better scheduling.
239          (eq_attr "type" "ibr")
240            (const_int 1)
241          ]
242          (symbol_ref "/* Update immediate_length and other attributes! */
243                       abort(),1")))
244
245 ;; The (bounding maximum) length of an instruction address.
246 (define_attr "length_address" ""
247   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
248            (const_int 0)
249          (and (eq_attr "type" "call")
250               (match_operand 0 "constant_call_address_operand" ""))
251              (const_int 0)
252          (and (eq_attr "type" "callv")
253               (match_operand 1 "constant_call_address_operand" ""))
254              (const_int 0)
255          ]
256          (symbol_ref "ix86_attr_length_address_default (insn)")))
257
258 ;; Set when length prefix is used.
259 (define_attr "prefix_data16" ""
260   (if_then_else (ior (eq_attr "mode" "HI")
261                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
262     (const_int 1)
263     (const_int 0)))
264
265 ;; Set when string REP prefix is used.
266 (define_attr "prefix_rep" "" 
267   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
268     (const_int 1)
269     (const_int 0)))
270
271 ;; Set when 0f opcode prefix is used.
272 (define_attr "prefix_0f" ""
273   (if_then_else 
274     (ior (eq_attr "type" "imovx,setcc,icmov")
275          (eq_attr "unit" "sse,mmx"))
276     (const_int 1)
277     (const_int 0)))
278
279 ;; Set when REX opcode prefix is used.
280 (define_attr "prefix_rex" ""
281   (cond [(and (eq_attr "mode" "DI")
282               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
283            (const_int 1)
284          (and (eq_attr "mode" "QI")
285               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
286                   (const_int 0)))
287            (const_int 1)
288          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
289              (const_int 0))
290            (const_int 1)
291         ]
292         (const_int 0)))
293
294 ;; Set when modrm byte is used.
295 (define_attr "modrm" ""
296   (cond [(eq_attr "type" "str,cld,leave")
297            (const_int 0)
298          (eq_attr "unit" "i387")
299            (const_int 0)
300          (and (eq_attr "type" "incdec")
301               (ior (match_operand:SI 1 "register_operand" "")
302                    (match_operand:HI 1 "register_operand" "")))
303            (const_int 0)
304          (and (eq_attr "type" "push")
305               (not (match_operand 1 "memory_operand" "")))
306            (const_int 0)
307          (and (eq_attr "type" "pop")
308               (not (match_operand 0 "memory_operand" "")))
309            (const_int 0)
310          (and (eq_attr "type" "imov")
311               (and (match_operand 0 "register_operand" "")
312                    (match_operand 1 "immediate_operand" "")))
313            (const_int 0)
314          (and (eq_attr "type" "call")
315               (match_operand 0 "constant_call_address_operand" ""))
316              (const_int 0)
317          (and (eq_attr "type" "callv")
318               (match_operand 1 "constant_call_address_operand" ""))
319              (const_int 0)
320          ]
321          (const_int 1)))
322
323 ;; The (bounding maximum) length of an instruction in bytes.
324 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
325 ;; Later we may want to split them and compute proper length as for
326 ;; other insns.
327 (define_attr "length" ""
328   (cond [(eq_attr "type" "other,multi,fistp,frndint")
329            (const_int 16)
330          (eq_attr "type" "fcmp")
331            (const_int 4)
332          (eq_attr "unit" "i387")
333            (plus (const_int 2)
334                  (plus (attr "prefix_data16")
335                        (attr "length_address")))]
336          (plus (plus (attr "modrm")
337                      (plus (attr "prefix_0f")
338                            (plus (attr "prefix_rex")
339                                  (const_int 1))))
340                (plus (attr "prefix_rep")
341                      (plus (attr "prefix_data16")
342                            (plus (attr "length_immediate")
343                                  (attr "length_address")))))))
344
345 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
346 ;; `store' if there is a simple memory reference therein, or `unknown'
347 ;; if the instruction is complex.
348
349 (define_attr "memory" "none,load,store,both,unknown"
350   (cond [(eq_attr "type" "other,multi,str")
351            (const_string "unknown")
352          (eq_attr "type" "lea,fcmov,fpspc,cld")
353            (const_string "none")
354          (eq_attr "type" "fistp,leave")
355            (const_string "both")
356          (eq_attr "type" "frndint")
357            (const_string "load")
358          (eq_attr "type" "push")
359            (if_then_else (match_operand 1 "memory_operand" "")
360              (const_string "both")
361              (const_string "store"))
362          (eq_attr "type" "pop")
363            (if_then_else (match_operand 0 "memory_operand" "")
364              (const_string "both")
365              (const_string "load"))
366          (eq_attr "type" "setcc")
367            (if_then_else (match_operand 0 "memory_operand" "")
368              (const_string "store")
369              (const_string "none"))
370          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
371            (if_then_else (ior (match_operand 0 "memory_operand" "")
372                               (match_operand 1 "memory_operand" ""))
373              (const_string "load")
374              (const_string "none"))
375          (eq_attr "type" "ibr")
376            (if_then_else (match_operand 0 "memory_operand" "")
377              (const_string "load")
378              (const_string "none"))
379          (eq_attr "type" "call")
380            (if_then_else (match_operand 0 "constant_call_address_operand" "")
381              (const_string "none")
382              (const_string "load"))
383          (eq_attr "type" "callv")
384            (if_then_else (match_operand 1 "constant_call_address_operand" "")
385              (const_string "none")
386              (const_string "load"))
387          (and (eq_attr "type" "alu1,negnot,ishift1")
388               (match_operand 1 "memory_operand" ""))
389            (const_string "both")
390          (and (match_operand 0 "memory_operand" "")
391               (match_operand 1 "memory_operand" ""))
392            (const_string "both")
393          (match_operand 0 "memory_operand" "")
394            (const_string "store")
395          (match_operand 1 "memory_operand" "")
396            (const_string "load")
397          (and (eq_attr "type"
398                  "!alu1,negnot,ishift1,
399                    imov,imovx,icmp,test,
400                    fmov,fcmp,fsgn,
401                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
402                    mmx,mmxmov,mmxcmp,mmxcvt")
403               (match_operand 2 "memory_operand" ""))
404            (const_string "load")
405          (and (eq_attr "type" "icmov")
406               (match_operand 3 "memory_operand" ""))
407            (const_string "load")
408         ]
409         (const_string "none")))
410
411 ;; Indicates if an instruction has both an immediate and a displacement.
412
413 (define_attr "imm_disp" "false,true,unknown"
414   (cond [(eq_attr "type" "other,multi")
415            (const_string "unknown")
416          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
417               (and (match_operand 0 "memory_displacement_operand" "")
418                    (match_operand 1 "immediate_operand" "")))
419            (const_string "true")
420          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
421               (and (match_operand 0 "memory_displacement_operand" "")
422                    (match_operand 2 "immediate_operand" "")))
423            (const_string "true")
424         ]
425         (const_string "false")))
426
427 ;; Indicates if an FP operation has an integer source.
428
429 (define_attr "fp_int_src" "false,true"
430   (const_string "false"))
431
432 ;; Defines rounding mode of an FP operation.
433
434 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
435   (const_string "any"))
436
437 ;; Describe a user's asm statement.
438 (define_asm_attributes
439   [(set_attr "length" "128")
440    (set_attr "type" "multi")])
441 \f
442 ;; Scheduling descriptions
443
444 (include "pentium.md")
445 (include "ppro.md")
446 (include "k6.md")
447 (include "athlon.md")
448
449 \f
450 ;; Operand and operator predicates
451
452 (include "predicates.md")
453
454 \f
455 ;; Compare instructions.
456
457 ;; All compare insns have expanders that save the operands away without
458 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
459 ;; after the cmp) will actually emit the cmpM.
460
461 (define_expand "cmpdi"
462   [(set (reg:CC FLAGS_REG)
463         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
464                     (match_operand:DI 1 "x86_64_general_operand" "")))]
465   ""
466 {
467   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
468     operands[0] = force_reg (DImode, operands[0]);
469   ix86_compare_op0 = operands[0];
470   ix86_compare_op1 = operands[1];
471   DONE;
472 })
473
474 (define_expand "cmpsi"
475   [(set (reg:CC FLAGS_REG)
476         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
477                     (match_operand:SI 1 "general_operand" "")))]
478   ""
479 {
480   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
481     operands[0] = force_reg (SImode, operands[0]);
482   ix86_compare_op0 = operands[0];
483   ix86_compare_op1 = operands[1];
484   DONE;
485 })
486
487 (define_expand "cmphi"
488   [(set (reg:CC FLAGS_REG)
489         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
490                     (match_operand:HI 1 "general_operand" "")))]
491   ""
492 {
493   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494     operands[0] = force_reg (HImode, operands[0]);
495   ix86_compare_op0 = operands[0];
496   ix86_compare_op1 = operands[1];
497   DONE;
498 })
499
500 (define_expand "cmpqi"
501   [(set (reg:CC FLAGS_REG)
502         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
503                     (match_operand:QI 1 "general_operand" "")))]
504   "TARGET_QIMODE_MATH"
505 {
506   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
507     operands[0] = force_reg (QImode, operands[0]);
508   ix86_compare_op0 = operands[0];
509   ix86_compare_op1 = operands[1];
510   DONE;
511 })
512
513 (define_insn "cmpdi_ccno_1_rex64"
514   [(set (reg FLAGS_REG)
515         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
516                  (match_operand:DI 1 "const0_operand" "n,n")))]
517   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
518   "@
519    test{q}\t{%0, %0|%0, %0}
520    cmp{q}\t{%1, %0|%0, %1}"
521   [(set_attr "type" "test,icmp")
522    (set_attr "length_immediate" "0,1")
523    (set_attr "mode" "DI")])
524
525 (define_insn "*cmpdi_minus_1_rex64"
526   [(set (reg FLAGS_REG)
527         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
528                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
529                  (const_int 0)))]
530   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
531   "cmp{q}\t{%1, %0|%0, %1}"
532   [(set_attr "type" "icmp")
533    (set_attr "mode" "DI")])
534
535 (define_expand "cmpdi_1_rex64"
536   [(set (reg:CC FLAGS_REG)
537         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
538                     (match_operand:DI 1 "general_operand" "")))]
539   "TARGET_64BIT"
540   "")
541
542 (define_insn "cmpdi_1_insn_rex64"
543   [(set (reg FLAGS_REG)
544         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
545                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
546   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
547   "cmp{q}\t{%1, %0|%0, %1}"
548   [(set_attr "type" "icmp")
549    (set_attr "mode" "DI")])
550
551
552 (define_insn "*cmpsi_ccno_1"
553   [(set (reg FLAGS_REG)
554         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
555                  (match_operand:SI 1 "const0_operand" "n,n")))]
556   "ix86_match_ccmode (insn, CCNOmode)"
557   "@
558    test{l}\t{%0, %0|%0, %0}
559    cmp{l}\t{%1, %0|%0, %1}"
560   [(set_attr "type" "test,icmp")
561    (set_attr "length_immediate" "0,1")
562    (set_attr "mode" "SI")])
563
564 (define_insn "*cmpsi_minus_1"
565   [(set (reg FLAGS_REG)
566         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
567                            (match_operand:SI 1 "general_operand" "ri,mr"))
568                  (const_int 0)))]
569   "ix86_match_ccmode (insn, CCGOCmode)"
570   "cmp{l}\t{%1, %0|%0, %1}"
571   [(set_attr "type" "icmp")
572    (set_attr "mode" "SI")])
573
574 (define_expand "cmpsi_1"
575   [(set (reg:CC FLAGS_REG)
576         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
577                     (match_operand:SI 1 "general_operand" "ri,mr")))]
578   ""
579   "")
580
581 (define_insn "*cmpsi_1_insn"
582   [(set (reg FLAGS_REG)
583         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
584                  (match_operand:SI 1 "general_operand" "ri,mr")))]
585   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
586     && ix86_match_ccmode (insn, CCmode)"
587   "cmp{l}\t{%1, %0|%0, %1}"
588   [(set_attr "type" "icmp")
589    (set_attr "mode" "SI")])
590
591 (define_insn "*cmphi_ccno_1"
592   [(set (reg FLAGS_REG)
593         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
594                  (match_operand:HI 1 "const0_operand" "n,n")))]
595   "ix86_match_ccmode (insn, CCNOmode)"
596   "@
597    test{w}\t{%0, %0|%0, %0}
598    cmp{w}\t{%1, %0|%0, %1}"
599   [(set_attr "type" "test,icmp")
600    (set_attr "length_immediate" "0,1")
601    (set_attr "mode" "HI")])
602
603 (define_insn "*cmphi_minus_1"
604   [(set (reg FLAGS_REG)
605         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
606                            (match_operand:HI 1 "general_operand" "ri,mr"))
607                  (const_int 0)))]
608   "ix86_match_ccmode (insn, CCGOCmode)"
609   "cmp{w}\t{%1, %0|%0, %1}"
610   [(set_attr "type" "icmp")
611    (set_attr "mode" "HI")])
612
613 (define_insn "*cmphi_1"
614   [(set (reg FLAGS_REG)
615         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
616                  (match_operand:HI 1 "general_operand" "ri,mr")))]
617   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
618    && ix86_match_ccmode (insn, CCmode)"
619   "cmp{w}\t{%1, %0|%0, %1}"
620   [(set_attr "type" "icmp")
621    (set_attr "mode" "HI")])
622
623 (define_insn "*cmpqi_ccno_1"
624   [(set (reg FLAGS_REG)
625         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
626                  (match_operand:QI 1 "const0_operand" "n,n")))]
627   "ix86_match_ccmode (insn, CCNOmode)"
628   "@
629    test{b}\t{%0, %0|%0, %0}
630    cmp{b}\t{$0, %0|%0, 0}"
631   [(set_attr "type" "test,icmp")
632    (set_attr "length_immediate" "0,1")
633    (set_attr "mode" "QI")])
634
635 (define_insn "*cmpqi_1"
636   [(set (reg FLAGS_REG)
637         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
638                  (match_operand:QI 1 "general_operand" "qi,mq")))]
639   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
640     && ix86_match_ccmode (insn, CCmode)"
641   "cmp{b}\t{%1, %0|%0, %1}"
642   [(set_attr "type" "icmp")
643    (set_attr "mode" "QI")])
644
645 (define_insn "*cmpqi_minus_1"
646   [(set (reg FLAGS_REG)
647         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
648                            (match_operand:QI 1 "general_operand" "qi,mq"))
649                  (const_int 0)))]
650   "ix86_match_ccmode (insn, CCGOCmode)"
651   "cmp{b}\t{%1, %0|%0, %1}"
652   [(set_attr "type" "icmp")
653    (set_attr "mode" "QI")])
654
655 (define_insn "*cmpqi_ext_1"
656   [(set (reg FLAGS_REG)
657         (compare
658           (match_operand:QI 0 "general_operand" "Qm")
659           (subreg:QI
660             (zero_extract:SI
661               (match_operand 1 "ext_register_operand" "Q")
662               (const_int 8)
663               (const_int 8)) 0)))]
664   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
665   "cmp{b}\t{%h1, %0|%0, %h1}"
666   [(set_attr "type" "icmp")
667    (set_attr "mode" "QI")])
668
669 (define_insn "*cmpqi_ext_1_rex64"
670   [(set (reg FLAGS_REG)
671         (compare
672           (match_operand:QI 0 "register_operand" "Q")
673           (subreg:QI
674             (zero_extract:SI
675               (match_operand 1 "ext_register_operand" "Q")
676               (const_int 8)
677               (const_int 8)) 0)))]
678   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
679   "cmp{b}\t{%h1, %0|%0, %h1}"
680   [(set_attr "type" "icmp")
681    (set_attr "mode" "QI")])
682
683 (define_insn "*cmpqi_ext_2"
684   [(set (reg FLAGS_REG)
685         (compare
686           (subreg:QI
687             (zero_extract:SI
688               (match_operand 0 "ext_register_operand" "Q")
689               (const_int 8)
690               (const_int 8)) 0)
691           (match_operand:QI 1 "const0_operand" "n")))]
692   "ix86_match_ccmode (insn, CCNOmode)"
693   "test{b}\t%h0, %h0"
694   [(set_attr "type" "test")
695    (set_attr "length_immediate" "0")
696    (set_attr "mode" "QI")])
697
698 (define_expand "cmpqi_ext_3"
699   [(set (reg:CC FLAGS_REG)
700         (compare:CC
701           (subreg:QI
702             (zero_extract:SI
703               (match_operand 0 "ext_register_operand" "")
704               (const_int 8)
705               (const_int 8)) 0)
706           (match_operand:QI 1 "general_operand" "")))]
707   ""
708   "")
709
710 (define_insn "cmpqi_ext_3_insn"
711   [(set (reg FLAGS_REG)
712         (compare
713           (subreg:QI
714             (zero_extract:SI
715               (match_operand 0 "ext_register_operand" "Q")
716               (const_int 8)
717               (const_int 8)) 0)
718           (match_operand:QI 1 "general_operand" "Qmn")))]
719   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720   "cmp{b}\t{%1, %h0|%h0, %1}"
721   [(set_attr "type" "icmp")
722    (set_attr "mode" "QI")])
723
724 (define_insn "cmpqi_ext_3_insn_rex64"
725   [(set (reg FLAGS_REG)
726         (compare
727           (subreg:QI
728             (zero_extract:SI
729               (match_operand 0 "ext_register_operand" "Q")
730               (const_int 8)
731               (const_int 8)) 0)
732           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
733   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
734   "cmp{b}\t{%1, %h0|%h0, %1}"
735   [(set_attr "type" "icmp")
736    (set_attr "mode" "QI")])
737
738 (define_insn "*cmpqi_ext_4"
739   [(set (reg FLAGS_REG)
740         (compare
741           (subreg:QI
742             (zero_extract:SI
743               (match_operand 0 "ext_register_operand" "Q")
744               (const_int 8)
745               (const_int 8)) 0)
746           (subreg:QI
747             (zero_extract:SI
748               (match_operand 1 "ext_register_operand" "Q")
749               (const_int 8)
750               (const_int 8)) 0)))]
751   "ix86_match_ccmode (insn, CCmode)"
752   "cmp{b}\t{%h1, %h0|%h0, %h1}"
753   [(set_attr "type" "icmp")
754    (set_attr "mode" "QI")])
755
756 ;; These implement float point compares.
757 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
758 ;; which would allow mix and match FP modes on the compares.  Which is what
759 ;; the old patterns did, but with many more of them.
760
761 (define_expand "cmpxf"
762   [(set (reg:CC FLAGS_REG)
763         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
764                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
765   "TARGET_80387"
766 {
767   ix86_compare_op0 = operands[0];
768   ix86_compare_op1 = operands[1];
769   DONE;
770 })
771
772 (define_expand "cmpdf"
773   [(set (reg:CC FLAGS_REG)
774         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
775                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
776   "TARGET_80387 || TARGET_SSE2"
777 {
778   ix86_compare_op0 = operands[0];
779   ix86_compare_op1 = operands[1];
780   DONE;
781 })
782
783 (define_expand "cmpsf"
784   [(set (reg:CC FLAGS_REG)
785         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
786                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
787   "TARGET_80387 || TARGET_SSE"
788 {
789   ix86_compare_op0 = operands[0];
790   ix86_compare_op1 = operands[1];
791   DONE;
792 })
793
794 ;; FP compares, step 1:
795 ;; Set the FP condition codes.
796 ;;
797 ;; CCFPmode     compare with exceptions
798 ;; CCFPUmode    compare with no exceptions
799
800 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
801 ;; used to manage the reg stack popping would not be preserved.
802
803 (define_insn "*cmpfp_0_sf"
804   [(set (match_operand:HI 0 "register_operand" "=a")
805         (unspec:HI
806           [(compare:CCFP
807              (match_operand:SF 1 "register_operand" "f")
808              (match_operand:SF 2 "const0_operand" "X"))]
809         UNSPEC_FNSTSW))]
810   "TARGET_80387"
811   "* return output_fp_compare (insn, operands, 0, 0);"
812   [(set_attr "type" "multi")
813    (set_attr "mode" "SF")])
814
815 (define_insn "*cmpfp_0_df"
816   [(set (match_operand:HI 0 "register_operand" "=a")
817         (unspec:HI
818           [(compare:CCFP
819              (match_operand:DF 1 "register_operand" "f")
820              (match_operand:DF 2 "const0_operand" "X"))]
821         UNSPEC_FNSTSW))]
822   "TARGET_80387"
823   "* return output_fp_compare (insn, operands, 0, 0);"
824   [(set_attr "type" "multi")
825    (set_attr "mode" "DF")])
826
827 (define_insn "*cmpfp_0_xf"
828   [(set (match_operand:HI 0 "register_operand" "=a")
829         (unspec:HI
830           [(compare:CCFP
831              (match_operand:XF 1 "register_operand" "f")
832              (match_operand:XF 2 "const0_operand" "X"))]
833         UNSPEC_FNSTSW))]
834   "TARGET_80387"
835   "* return output_fp_compare (insn, operands, 0, 0);"
836   [(set_attr "type" "multi")
837    (set_attr "mode" "XF")])
838
839 (define_insn "*cmpfp_sf"
840   [(set (match_operand:HI 0 "register_operand" "=a")
841         (unspec:HI
842           [(compare:CCFP
843              (match_operand:SF 1 "register_operand" "f")
844              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
845           UNSPEC_FNSTSW))]
846   "TARGET_80387"
847   "* return output_fp_compare (insn, operands, 0, 0);"
848   [(set_attr "type" "multi")
849    (set_attr "mode" "SF")])
850
851 (define_insn "*cmpfp_df"
852   [(set (match_operand:HI 0 "register_operand" "=a")
853         (unspec:HI
854           [(compare:CCFP
855              (match_operand:DF 1 "register_operand" "f")
856              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
857           UNSPEC_FNSTSW))]
858   "TARGET_80387"
859   "* return output_fp_compare (insn, operands, 0, 0);"
860   [(set_attr "type" "multi")
861    (set_attr "mode" "DF")])
862
863 (define_insn "*cmpfp_xf"
864   [(set (match_operand:HI 0 "register_operand" "=a")
865         (unspec:HI
866           [(compare:CCFP
867              (match_operand:XF 1 "register_operand" "f")
868              (match_operand:XF 2 "register_operand" "f"))]
869           UNSPEC_FNSTSW))]
870   "TARGET_80387"
871   "* return output_fp_compare (insn, operands, 0, 0);"
872   [(set_attr "type" "multi")
873    (set_attr "mode" "XF")])
874
875 (define_insn "*cmpfp_u"
876   [(set (match_operand:HI 0 "register_operand" "=a")
877         (unspec:HI
878           [(compare:CCFPU
879              (match_operand 1 "register_operand" "f")
880              (match_operand 2 "register_operand" "f"))]
881           UNSPEC_FNSTSW))]
882   "TARGET_80387
883    && FLOAT_MODE_P (GET_MODE (operands[1]))
884    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
885   "* return output_fp_compare (insn, operands, 0, 1);"
886   [(set_attr "type" "multi")
887    (set (attr "mode")
888      (cond [(match_operand:SF 1 "" "")
889               (const_string "SF")
890             (match_operand:DF 1 "" "")
891               (const_string "DF")
892            ]
893            (const_string "XF")))])
894
895 (define_insn "*cmpfp_si"
896   [(set (match_operand:HI 0 "register_operand" "=a")
897         (unspec:HI
898           [(compare:CCFP
899              (match_operand 1 "register_operand" "f")
900              (match_operator 3 "float_operator"
901                [(match_operand:SI 2 "memory_operand" "m")]))]
902           UNSPEC_FNSTSW))]
903   "TARGET_80387 && TARGET_USE_FIOP
904    && FLOAT_MODE_P (GET_MODE (operands[1]))
905    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
906   "* return output_fp_compare (insn, operands, 0, 0);"
907   [(set_attr "type" "multi")
908    (set_attr "fp_int_src" "true")
909    (set_attr "mode" "SI")])
910
911 ;; FP compares, step 2
912 ;; Move the fpsw to ax.
913
914 (define_insn "x86_fnstsw_1"
915   [(set (match_operand:HI 0 "register_operand" "=a")
916         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
917   "TARGET_80387"
918   "fnstsw\t%0"
919   [(set_attr "length" "2")
920    (set_attr "mode" "SI")
921    (set_attr "unit" "i387")])
922
923 ;; FP compares, step 3
924 ;; Get ax into flags, general case.
925
926 (define_insn "x86_sahf_1"
927   [(set (reg:CC FLAGS_REG)
928         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
929   "!TARGET_64BIT"
930   "sahf"
931   [(set_attr "length" "1")
932    (set_attr "athlon_decode" "vector")
933    (set_attr "mode" "SI")])
934
935 ;; Pentium Pro can do steps 1 through 3 in one go.
936
937 (define_insn "*cmpfp_i"
938   [(set (reg:CCFP FLAGS_REG)
939         (compare:CCFP (match_operand 0 "register_operand" "f")
940                       (match_operand 1 "register_operand" "f")))]
941   "TARGET_80387 && TARGET_CMOVE
942    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
943    && FLOAT_MODE_P (GET_MODE (operands[0]))
944    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
945   "* return output_fp_compare (insn, operands, 1, 0);"
946   [(set_attr "type" "fcmp")
947    (set (attr "mode")
948      (cond [(match_operand:SF 1 "" "")
949               (const_string "SF")
950             (match_operand:DF 1 "" "")
951               (const_string "DF")
952            ]
953            (const_string "XF")))
954    (set_attr "athlon_decode" "vector")])
955
956 (define_insn "*cmpfp_i_sse"
957   [(set (reg:CCFP FLAGS_REG)
958         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
959                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
960   "TARGET_80387
961    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
962    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
963   "* return output_fp_compare (insn, operands, 1, 0);"
964   [(set_attr "type" "fcmp,ssecomi")
965    (set (attr "mode")
966      (if_then_else (match_operand:SF 1 "" "")
967         (const_string "SF")
968         (const_string "DF")))
969    (set_attr "athlon_decode" "vector")])
970
971 (define_insn "*cmpfp_i_sse_only"
972   [(set (reg:CCFP FLAGS_REG)
973         (compare:CCFP (match_operand 0 "register_operand" "x")
974                       (match_operand 1 "nonimmediate_operand" "xm")))]
975   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
976    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
977   "* return output_fp_compare (insn, operands, 1, 0);"
978   [(set_attr "type" "ssecomi")
979    (set (attr "mode")
980      (if_then_else (match_operand:SF 1 "" "")
981         (const_string "SF")
982         (const_string "DF")))
983    (set_attr "athlon_decode" "vector")])
984
985 (define_insn "*cmpfp_iu"
986   [(set (reg:CCFPU FLAGS_REG)
987         (compare:CCFPU (match_operand 0 "register_operand" "f")
988                        (match_operand 1 "register_operand" "f")))]
989   "TARGET_80387 && TARGET_CMOVE
990    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
991    && FLOAT_MODE_P (GET_MODE (operands[0]))
992    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
993   "* return output_fp_compare (insn, operands, 1, 1);"
994   [(set_attr "type" "fcmp")
995    (set (attr "mode")
996      (cond [(match_operand:SF 1 "" "")
997               (const_string "SF")
998             (match_operand:DF 1 "" "")
999               (const_string "DF")
1000            ]
1001            (const_string "XF")))
1002    (set_attr "athlon_decode" "vector")])
1003
1004 (define_insn "*cmpfp_iu_sse"
1005   [(set (reg:CCFPU FLAGS_REG)
1006         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1007                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1008   "TARGET_80387
1009    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1010    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1011   "* return output_fp_compare (insn, operands, 1, 1);"
1012   [(set_attr "type" "fcmp,ssecomi")
1013    (set (attr "mode")
1014      (if_then_else (match_operand:SF 1 "" "")
1015         (const_string "SF")
1016         (const_string "DF")))
1017    (set_attr "athlon_decode" "vector")])
1018
1019 (define_insn "*cmpfp_iu_sse_only"
1020   [(set (reg:CCFPU FLAGS_REG)
1021         (compare:CCFPU (match_operand 0 "register_operand" "x")
1022                        (match_operand 1 "nonimmediate_operand" "xm")))]
1023   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1024    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025   "* return output_fp_compare (insn, operands, 1, 1);"
1026   [(set_attr "type" "ssecomi")
1027    (set (attr "mode")
1028      (if_then_else (match_operand:SF 1 "" "")
1029         (const_string "SF")
1030         (const_string "DF")))
1031    (set_attr "athlon_decode" "vector")])
1032 \f
1033 ;; Move instructions.
1034
1035 ;; General case of fullword move.
1036
1037 (define_expand "movsi"
1038   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1039         (match_operand:SI 1 "general_operand" ""))]
1040   ""
1041   "ix86_expand_move (SImode, operands); DONE;")
1042
1043 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1044 ;; general_operand.
1045 ;;
1046 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1047 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1048 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1049 ;; targets without our curiosities, and it is just as easy to represent
1050 ;; this differently.
1051
1052 (define_insn "*pushsi2"
1053   [(set (match_operand:SI 0 "push_operand" "=<")
1054         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1055   "!TARGET_64BIT"
1056   "push{l}\t%1"
1057   [(set_attr "type" "push")
1058    (set_attr "mode" "SI")])
1059
1060 ;; For 64BIT abi we always round up to 8 bytes.
1061 (define_insn "*pushsi2_rex64"
1062   [(set (match_operand:SI 0 "push_operand" "=X")
1063         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1064   "TARGET_64BIT"
1065   "push{q}\t%q1"
1066   [(set_attr "type" "push")
1067    (set_attr "mode" "SI")])
1068
1069 (define_insn "*pushsi2_prologue"
1070   [(set (match_operand:SI 0 "push_operand" "=<")
1071         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1072    (clobber (mem:BLK (scratch)))]
1073   "!TARGET_64BIT"
1074   "push{l}\t%1"
1075   [(set_attr "type" "push")
1076    (set_attr "mode" "SI")])
1077
1078 (define_insn "*popsi1_epilogue"
1079   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1080         (mem:SI (reg:SI SP_REG)))
1081    (set (reg:SI SP_REG)
1082         (plus:SI (reg:SI SP_REG) (const_int 4)))
1083    (clobber (mem:BLK (scratch)))]
1084   "!TARGET_64BIT"
1085   "pop{l}\t%0"
1086   [(set_attr "type" "pop")
1087    (set_attr "mode" "SI")])
1088
1089 (define_insn "popsi1"
1090   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1091         (mem:SI (reg:SI SP_REG)))
1092    (set (reg:SI SP_REG)
1093         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1094   "!TARGET_64BIT"
1095   "pop{l}\t%0"
1096   [(set_attr "type" "pop")
1097    (set_attr "mode" "SI")])
1098
1099 (define_insn "*movsi_xor"
1100   [(set (match_operand:SI 0 "register_operand" "=r")
1101         (match_operand:SI 1 "const0_operand" "i"))
1102    (clobber (reg:CC FLAGS_REG))]
1103   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1104   "xor{l}\t{%0, %0|%0, %0}"
1105   [(set_attr "type" "alu1")
1106    (set_attr "mode" "SI")
1107    (set_attr "length_immediate" "0")])
1108  
1109 (define_insn "*movsi_or"
1110   [(set (match_operand:SI 0 "register_operand" "=r")
1111         (match_operand:SI 1 "immediate_operand" "i"))
1112    (clobber (reg:CC FLAGS_REG))]
1113   "reload_completed
1114    && operands[1] == constm1_rtx
1115    && (TARGET_PENTIUM || optimize_size)"
1116 {
1117   operands[1] = constm1_rtx;
1118   return "or{l}\t{%1, %0|%0, %1}";
1119 }
1120   [(set_attr "type" "alu1")
1121    (set_attr "mode" "SI")
1122    (set_attr "length_immediate" "1")])
1123
1124 (define_insn "*movsi_1"
1125   [(set (match_operand:SI 0 "nonimmediate_operand"
1126                         "=r  ,m  ,!*y,!rm,!*y,!*x,!rm,!*x")
1127         (match_operand:SI 1 "general_operand"
1128                         "rinm,rin,*y ,*y ,rm ,*x ,*x ,rm"))]
1129   "(TARGET_INTER_UNIT_MOVES || optimize_size)
1130    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1131 {
1132   switch (get_attr_type (insn))
1133     {
1134     case TYPE_SSEMOV:
1135       if (get_attr_mode (insn) == MODE_TI)
1136         return "movdqa\t{%1, %0|%0, %1}";
1137       return "movd\t{%1, %0|%0, %1}";
1138
1139     case TYPE_MMXMOV:
1140       if (get_attr_mode (insn) == MODE_DI)
1141         return "movq\t{%1, %0|%0, %1}";
1142       return "movd\t{%1, %0|%0, %1}";
1143
1144     case TYPE_LEA:
1145       return "lea{l}\t{%1, %0|%0, %1}";
1146
1147     default:
1148       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1149         abort();
1150       return "mov{l}\t{%1, %0|%0, %1}";
1151     }
1152 }
1153   [(set (attr "type")
1154      (cond [(eq_attr "alternative" "2,3,4")
1155               (const_string "mmxmov")
1156             (eq_attr "alternative" "5,6,7")
1157               (const_string "ssemov")
1158             (and (ne (symbol_ref "flag_pic") (const_int 0))
1159                  (match_operand:SI 1 "symbolic_operand" ""))
1160               (const_string "lea")
1161            ]
1162            (const_string "imov")))
1163    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1164
1165 (define_insn "*movsi_1_nointernunit"
1166   [(set (match_operand:SI 0 "nonimmediate_operand"
1167                         "=r  ,m  ,!*y,!m,!*y,!*x,!m,!*x")
1168         (match_operand:SI 1 "general_operand"
1169                         "rinm,rin,*y ,*y,m  ,*x ,*x,m"))]
1170   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1171    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1172 {
1173   switch (get_attr_type (insn))
1174     {
1175     case TYPE_SSEMOV:
1176       if (get_attr_mode (insn) == MODE_TI)
1177         return "movdqa\t{%1, %0|%0, %1}";
1178       return "movd\t{%1, %0|%0, %1}";
1179
1180     case TYPE_MMXMOV:
1181       if (get_attr_mode (insn) == MODE_DI)
1182         return "movq\t{%1, %0|%0, %1}";
1183       return "movd\t{%1, %0|%0, %1}";
1184
1185     case TYPE_LEA:
1186       return "lea{l}\t{%1, %0|%0, %1}";
1187
1188     default:
1189       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1190         abort();
1191       return "mov{l}\t{%1, %0|%0, %1}";
1192     }
1193 }
1194   [(set (attr "type")
1195      (cond [(eq_attr "alternative" "2,3,4")
1196               (const_string "mmxmov")
1197             (eq_attr "alternative" "5,6,7")
1198               (const_string "ssemov")
1199             (and (ne (symbol_ref "flag_pic") (const_int 0))
1200                  (match_operand:SI 1 "symbolic_operand" ""))
1201               (const_string "lea")
1202            ]
1203            (const_string "imov")))
1204    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1205
1206 ;; Stores and loads of ax to arbitrary constant address.
1207 ;; We fake an second form of instruction to force reload to load address
1208 ;; into register when rax is not available
1209 (define_insn "*movabssi_1_rex64"
1210   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1211         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1212   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1213   "@
1214    movabs{l}\t{%1, %P0|%P0, %1}
1215    mov{l}\t{%1, %a0|%a0, %1}"
1216   [(set_attr "type" "imov")
1217    (set_attr "modrm" "0,*")
1218    (set_attr "length_address" "8,0")
1219    (set_attr "length_immediate" "0,*")
1220    (set_attr "memory" "store")
1221    (set_attr "mode" "SI")])
1222
1223 (define_insn "*movabssi_2_rex64"
1224   [(set (match_operand:SI 0 "register_operand" "=a,r")
1225         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1226   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1227   "@
1228    movabs{l}\t{%P1, %0|%0, %P1}
1229    mov{l}\t{%a1, %0|%0, %a1}"
1230   [(set_attr "type" "imov")
1231    (set_attr "modrm" "0,*")
1232    (set_attr "length_address" "8,0")
1233    (set_attr "length_immediate" "0")
1234    (set_attr "memory" "load")
1235    (set_attr "mode" "SI")])
1236
1237 (define_insn "*swapsi"
1238   [(set (match_operand:SI 0 "register_operand" "+r")
1239         (match_operand:SI 1 "register_operand" "+r"))
1240    (set (match_dup 1)
1241         (match_dup 0))]
1242   ""
1243   "xchg{l}\t%1, %0"
1244   [(set_attr "type" "imov")
1245    (set_attr "mode" "SI")
1246    (set_attr "pent_pair" "np")
1247    (set_attr "athlon_decode" "vector")])
1248
1249 (define_expand "movhi"
1250   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1251         (match_operand:HI 1 "general_operand" ""))]
1252   ""
1253   "ix86_expand_move (HImode, operands); DONE;")
1254
1255 (define_insn "*pushhi2"
1256   [(set (match_operand:HI 0 "push_operand" "=<,<")
1257         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1258   "!TARGET_64BIT"
1259   "@
1260    push{w}\t{|WORD PTR }%1
1261    push{w}\t%1"
1262   [(set_attr "type" "push")
1263    (set_attr "mode" "HI")])
1264
1265 ;; For 64BIT abi we always round up to 8 bytes.
1266 (define_insn "*pushhi2_rex64"
1267   [(set (match_operand:HI 0 "push_operand" "=X")
1268         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1269   "TARGET_64BIT"
1270   "push{q}\t%q1"
1271   [(set_attr "type" "push")
1272    (set_attr "mode" "QI")])
1273
1274 (define_insn "*movhi_1"
1275   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1276         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1277   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1278 {
1279   switch (get_attr_type (insn))
1280     {
1281     case TYPE_IMOVX:
1282       /* movzwl is faster than movw on p2 due to partial word stalls,
1283          though not as fast as an aligned movl.  */
1284       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1285     default:
1286       if (get_attr_mode (insn) == MODE_SI)
1287         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1288       else
1289         return "mov{w}\t{%1, %0|%0, %1}";
1290     }
1291 }
1292   [(set (attr "type")
1293      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1294               (const_string "imov")
1295             (and (eq_attr "alternative" "0")
1296                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1297                           (const_int 0))
1298                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1299                           (const_int 0))))
1300               (const_string "imov")
1301             (and (eq_attr "alternative" "1,2")
1302                  (match_operand:HI 1 "aligned_operand" ""))
1303               (const_string "imov")
1304             (and (ne (symbol_ref "TARGET_MOVX")
1305                      (const_int 0))
1306                  (eq_attr "alternative" "0,2"))
1307               (const_string "imovx")
1308            ]
1309            (const_string "imov")))
1310     (set (attr "mode")
1311       (cond [(eq_attr "type" "imovx")
1312                (const_string "SI")
1313              (and (eq_attr "alternative" "1,2")
1314                   (match_operand:HI 1 "aligned_operand" ""))
1315                (const_string "SI")
1316              (and (eq_attr "alternative" "0")
1317                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1318                            (const_int 0))
1319                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1320                            (const_int 0))))
1321                (const_string "SI")
1322             ]
1323             (const_string "HI")))])
1324
1325 ;; Stores and loads of ax to arbitrary constant address.
1326 ;; We fake an second form of instruction to force reload to load address
1327 ;; into register when rax is not available
1328 (define_insn "*movabshi_1_rex64"
1329   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1330         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1331   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1332   "@
1333    movabs{w}\t{%1, %P0|%P0, %1}
1334    mov{w}\t{%1, %a0|%a0, %1}"
1335   [(set_attr "type" "imov")
1336    (set_attr "modrm" "0,*")
1337    (set_attr "length_address" "8,0")
1338    (set_attr "length_immediate" "0,*")
1339    (set_attr "memory" "store")
1340    (set_attr "mode" "HI")])
1341
1342 (define_insn "*movabshi_2_rex64"
1343   [(set (match_operand:HI 0 "register_operand" "=a,r")
1344         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1345   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1346   "@
1347    movabs{w}\t{%P1, %0|%0, %P1}
1348    mov{w}\t{%a1, %0|%0, %a1}"
1349   [(set_attr "type" "imov")
1350    (set_attr "modrm" "0,*")
1351    (set_attr "length_address" "8,0")
1352    (set_attr "length_immediate" "0")
1353    (set_attr "memory" "load")
1354    (set_attr "mode" "HI")])
1355
1356 (define_insn "*swaphi_1"
1357   [(set (match_operand:HI 0 "register_operand" "+r")
1358         (match_operand:HI 1 "register_operand" "+r"))
1359    (set (match_dup 1)
1360         (match_dup 0))]
1361   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1362   "xchg{l}\t%k1, %k0"
1363   [(set_attr "type" "imov")
1364    (set_attr "mode" "SI")
1365    (set_attr "pent_pair" "np")
1366    (set_attr "athlon_decode" "vector")])
1367
1368 (define_insn "*swaphi_2"
1369   [(set (match_operand:HI 0 "register_operand" "+r")
1370         (match_operand:HI 1 "register_operand" "+r"))
1371    (set (match_dup 1)
1372         (match_dup 0))]
1373   "TARGET_PARTIAL_REG_STALL"
1374   "xchg{w}\t%1, %0"
1375   [(set_attr "type" "imov")
1376    (set_attr "mode" "HI")
1377    (set_attr "pent_pair" "np")
1378    (set_attr "athlon_decode" "vector")])
1379
1380 (define_expand "movstricthi"
1381   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1382         (match_operand:HI 1 "general_operand" ""))]
1383   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1384 {
1385   /* Don't generate memory->memory moves, go through a register */
1386   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1387     operands[1] = force_reg (HImode, operands[1]);
1388 })
1389
1390 (define_insn "*movstricthi_1"
1391   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1392         (match_operand:HI 1 "general_operand" "rn,m"))]
1393   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1394    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1395   "mov{w}\t{%1, %0|%0, %1}"
1396   [(set_attr "type" "imov")
1397    (set_attr "mode" "HI")])
1398
1399 (define_insn "*movstricthi_xor"
1400   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1401         (match_operand:HI 1 "const0_operand" "i"))
1402    (clobber (reg:CC FLAGS_REG))]
1403   "reload_completed
1404    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1405   "xor{w}\t{%0, %0|%0, %0}"
1406   [(set_attr "type" "alu1")
1407    (set_attr "mode" "HI")
1408    (set_attr "length_immediate" "0")])
1409
1410 (define_expand "movqi"
1411   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1412         (match_operand:QI 1 "general_operand" ""))]
1413   ""
1414   "ix86_expand_move (QImode, operands); DONE;")
1415
1416 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1417 ;; "push a byte".  But actually we use pushw, which has the effect
1418 ;; of rounding the amount pushed up to a halfword.
1419
1420 (define_insn "*pushqi2"
1421   [(set (match_operand:QI 0 "push_operand" "=X,X")
1422         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1423   "!TARGET_64BIT"
1424   "@
1425    push{w}\t{|word ptr }%1
1426    push{w}\t%w1"
1427   [(set_attr "type" "push")
1428    (set_attr "mode" "HI")])
1429
1430 ;; For 64BIT abi we always round up to 8 bytes.
1431 (define_insn "*pushqi2_rex64"
1432   [(set (match_operand:QI 0 "push_operand" "=X")
1433         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1434   "TARGET_64BIT"
1435   "push{q}\t%q1"
1436   [(set_attr "type" "push")
1437    (set_attr "mode" "QI")])
1438
1439 ;; Situation is quite tricky about when to choose full sized (SImode) move
1440 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1441 ;; partial register dependency machines (such as AMD Athlon), where QImode
1442 ;; moves issue extra dependency and for partial register stalls machines
1443 ;; that don't use QImode patterns (and QImode move cause stall on the next
1444 ;; instruction).
1445 ;;
1446 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1447 ;; register stall machines with, where we use QImode instructions, since
1448 ;; partial register stall can be caused there.  Then we use movzx.
1449 (define_insn "*movqi_1"
1450   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1451         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1452   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1453 {
1454   switch (get_attr_type (insn))
1455     {
1456     case TYPE_IMOVX:
1457       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1458         abort ();
1459       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1460     default:
1461       if (get_attr_mode (insn) == MODE_SI)
1462         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1463       else
1464         return "mov{b}\t{%1, %0|%0, %1}";
1465     }
1466 }
1467   [(set (attr "type")
1468      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1469               (const_string "imov")
1470             (and (eq_attr "alternative" "3")
1471                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1472                           (const_int 0))
1473                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1474                           (const_int 0))))
1475               (const_string "imov")
1476             (eq_attr "alternative" "3,5")
1477               (const_string "imovx")
1478             (and (ne (symbol_ref "TARGET_MOVX")
1479                      (const_int 0))
1480                  (eq_attr "alternative" "2"))
1481               (const_string "imovx")
1482            ]
1483            (const_string "imov")))
1484    (set (attr "mode")
1485       (cond [(eq_attr "alternative" "3,4,5")
1486                (const_string "SI")
1487              (eq_attr "alternative" "6")
1488                (const_string "QI")
1489              (eq_attr "type" "imovx")
1490                (const_string "SI")
1491              (and (eq_attr "type" "imov")
1492                   (and (eq_attr "alternative" "0,1,2")
1493                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1494                            (const_int 0))))
1495                (const_string "SI")
1496              ;; Avoid partial register stalls when not using QImode arithmetic
1497              (and (eq_attr "type" "imov")
1498                   (and (eq_attr "alternative" "0,1,2")
1499                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1500                                 (const_int 0))
1501                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1502                                 (const_int 0)))))
1503                (const_string "SI")
1504            ]
1505            (const_string "QI")))])
1506
1507 (define_expand "reload_outqi"
1508   [(parallel [(match_operand:QI 0 "" "=m")
1509               (match_operand:QI 1 "register_operand" "r")
1510               (match_operand:QI 2 "register_operand" "=&q")])]
1511   ""
1512 {
1513   rtx op0, op1, op2;
1514   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1515
1516   if (reg_overlap_mentioned_p (op2, op0))
1517     abort ();
1518   if (! q_regs_operand (op1, QImode))
1519     {
1520       emit_insn (gen_movqi (op2, op1));
1521       op1 = op2;
1522     }
1523   emit_insn (gen_movqi (op0, op1));
1524   DONE;
1525 })
1526
1527 (define_insn "*swapqi_1"
1528   [(set (match_operand:QI 0 "register_operand" "+r")
1529         (match_operand:QI 1 "register_operand" "+r"))
1530    (set (match_dup 1)
1531         (match_dup 0))]
1532   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1533   "xchg{l}\t%k1, %k0"
1534   [(set_attr "type" "imov")
1535    (set_attr "mode" "SI")
1536    (set_attr "pent_pair" "np")
1537    (set_attr "athlon_decode" "vector")])
1538
1539 (define_insn "*swapqi_2"
1540   [(set (match_operand:QI 0 "register_operand" "+q")
1541         (match_operand:QI 1 "register_operand" "+q"))
1542    (set (match_dup 1)
1543         (match_dup 0))]
1544   "TARGET_PARTIAL_REG_STALL"
1545   "xchg{b}\t%1, %0"
1546   [(set_attr "type" "imov")
1547    (set_attr "mode" "QI")
1548    (set_attr "pent_pair" "np")
1549    (set_attr "athlon_decode" "vector")])
1550
1551 (define_expand "movstrictqi"
1552   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1553         (match_operand:QI 1 "general_operand" ""))]
1554   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1555 {
1556   /* Don't generate memory->memory moves, go through a register.  */
1557   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1558     operands[1] = force_reg (QImode, operands[1]);
1559 })
1560
1561 (define_insn "*movstrictqi_1"
1562   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1563         (match_operand:QI 1 "general_operand" "*qn,m"))]
1564   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1565    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1566   "mov{b}\t{%1, %0|%0, %1}"
1567   [(set_attr "type" "imov")
1568    (set_attr "mode" "QI")])
1569
1570 (define_insn "*movstrictqi_xor"
1571   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1572         (match_operand:QI 1 "const0_operand" "i"))
1573    (clobber (reg:CC FLAGS_REG))]
1574   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1575   "xor{b}\t{%0, %0|%0, %0}"
1576   [(set_attr "type" "alu1")
1577    (set_attr "mode" "QI")
1578    (set_attr "length_immediate" "0")])
1579
1580 (define_insn "*movsi_extv_1"
1581   [(set (match_operand:SI 0 "register_operand" "=R")
1582         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1583                          (const_int 8)
1584                          (const_int 8)))]
1585   ""
1586   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1587   [(set_attr "type" "imovx")
1588    (set_attr "mode" "SI")])
1589
1590 (define_insn "*movhi_extv_1"
1591   [(set (match_operand:HI 0 "register_operand" "=R")
1592         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1593                          (const_int 8)
1594                          (const_int 8)))]
1595   ""
1596   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1597   [(set_attr "type" "imovx")
1598    (set_attr "mode" "SI")])
1599
1600 (define_insn "*movqi_extv_1"
1601   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1602         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1603                          (const_int 8)
1604                          (const_int 8)))]
1605   "!TARGET_64BIT"
1606 {
1607   switch (get_attr_type (insn))
1608     {
1609     case TYPE_IMOVX:
1610       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1611     default:
1612       return "mov{b}\t{%h1, %0|%0, %h1}";
1613     }
1614 }
1615   [(set (attr "type")
1616      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1617                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1618                              (ne (symbol_ref "TARGET_MOVX")
1619                                  (const_int 0))))
1620         (const_string "imovx")
1621         (const_string "imov")))
1622    (set (attr "mode")
1623      (if_then_else (eq_attr "type" "imovx")
1624         (const_string "SI")
1625         (const_string "QI")))])
1626
1627 (define_insn "*movqi_extv_1_rex64"
1628   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1629         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1630                          (const_int 8)
1631                          (const_int 8)))]
1632   "TARGET_64BIT"
1633 {
1634   switch (get_attr_type (insn))
1635     {
1636     case TYPE_IMOVX:
1637       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1638     default:
1639       return "mov{b}\t{%h1, %0|%0, %h1}";
1640     }
1641 }
1642   [(set (attr "type")
1643      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1644                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1645                              (ne (symbol_ref "TARGET_MOVX")
1646                                  (const_int 0))))
1647         (const_string "imovx")
1648         (const_string "imov")))
1649    (set (attr "mode")
1650      (if_then_else (eq_attr "type" "imovx")
1651         (const_string "SI")
1652         (const_string "QI")))])
1653
1654 ;; Stores and loads of ax to arbitrary constant address.
1655 ;; We fake an second form of instruction to force reload to load address
1656 ;; into register when rax is not available
1657 (define_insn "*movabsqi_1_rex64"
1658   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1659         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1660   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1661   "@
1662    movabs{b}\t{%1, %P0|%P0, %1}
1663    mov{b}\t{%1, %a0|%a0, %1}"
1664   [(set_attr "type" "imov")
1665    (set_attr "modrm" "0,*")
1666    (set_attr "length_address" "8,0")
1667    (set_attr "length_immediate" "0,*")
1668    (set_attr "memory" "store")
1669    (set_attr "mode" "QI")])
1670
1671 (define_insn "*movabsqi_2_rex64"
1672   [(set (match_operand:QI 0 "register_operand" "=a,r")
1673         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1674   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1675   "@
1676    movabs{b}\t{%P1, %0|%0, %P1}
1677    mov{b}\t{%a1, %0|%0, %a1}"
1678   [(set_attr "type" "imov")
1679    (set_attr "modrm" "0,*")
1680    (set_attr "length_address" "8,0")
1681    (set_attr "length_immediate" "0")
1682    (set_attr "memory" "load")
1683    (set_attr "mode" "QI")])
1684
1685 (define_insn "*movsi_extzv_1"
1686   [(set (match_operand:SI 0 "register_operand" "=R")
1687         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1688                          (const_int 8)
1689                          (const_int 8)))]
1690   ""
1691   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1692   [(set_attr "type" "imovx")
1693    (set_attr "mode" "SI")])
1694
1695 (define_insn "*movqi_extzv_2"
1696   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1697         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1698                                     (const_int 8)
1699                                     (const_int 8)) 0))]
1700   "!TARGET_64BIT"
1701 {
1702   switch (get_attr_type (insn))
1703     {
1704     case TYPE_IMOVX:
1705       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1706     default:
1707       return "mov{b}\t{%h1, %0|%0, %h1}";
1708     }
1709 }
1710   [(set (attr "type")
1711      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1712                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1713                              (ne (symbol_ref "TARGET_MOVX")
1714                                  (const_int 0))))
1715         (const_string "imovx")
1716         (const_string "imov")))
1717    (set (attr "mode")
1718      (if_then_else (eq_attr "type" "imovx")
1719         (const_string "SI")
1720         (const_string "QI")))])
1721
1722 (define_insn "*movqi_extzv_2_rex64"
1723   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1724         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1725                                     (const_int 8)
1726                                     (const_int 8)) 0))]
1727   "TARGET_64BIT"
1728 {
1729   switch (get_attr_type (insn))
1730     {
1731     case TYPE_IMOVX:
1732       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1733     default:
1734       return "mov{b}\t{%h1, %0|%0, %h1}";
1735     }
1736 }
1737   [(set (attr "type")
1738      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1739                         (ne (symbol_ref "TARGET_MOVX")
1740                             (const_int 0)))
1741         (const_string "imovx")
1742         (const_string "imov")))
1743    (set (attr "mode")
1744      (if_then_else (eq_attr "type" "imovx")
1745         (const_string "SI")
1746         (const_string "QI")))])
1747
1748 (define_insn "movsi_insv_1"
1749   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1750                          (const_int 8)
1751                          (const_int 8))
1752         (match_operand:SI 1 "general_operand" "Qmn"))]
1753   "!TARGET_64BIT"
1754   "mov{b}\t{%b1, %h0|%h0, %b1}"
1755   [(set_attr "type" "imov")
1756    (set_attr "mode" "QI")])
1757
1758 (define_insn "movdi_insv_1_rex64"
1759   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1760                          (const_int 8)
1761                          (const_int 8))
1762         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1763   "TARGET_64BIT"
1764   "mov{b}\t{%b1, %h0|%h0, %b1}"
1765   [(set_attr "type" "imov")
1766    (set_attr "mode" "QI")])
1767
1768 (define_insn "*movqi_insv_2"
1769   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1770                          (const_int 8)
1771                          (const_int 8))
1772         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1773                      (const_int 8)))]
1774   ""
1775   "mov{b}\t{%h1, %h0|%h0, %h1}"
1776   [(set_attr "type" "imov")
1777    (set_attr "mode" "QI")])
1778
1779 (define_expand "movdi"
1780   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1781         (match_operand:DI 1 "general_operand" ""))]
1782   ""
1783   "ix86_expand_move (DImode, operands); DONE;")
1784
1785 (define_insn "*pushdi"
1786   [(set (match_operand:DI 0 "push_operand" "=<")
1787         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1788   "!TARGET_64BIT"
1789   "#")
1790
1791 (define_insn "*pushdi2_rex64"
1792   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1793         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1794   "TARGET_64BIT"
1795   "@
1796    push{q}\t%1
1797    #"
1798   [(set_attr "type" "push,multi")
1799    (set_attr "mode" "DI")])
1800
1801 ;; Convert impossible pushes of immediate to existing instructions.
1802 ;; First try to get scratch register and go through it.  In case this
1803 ;; fails, push sign extended lower part first and then overwrite
1804 ;; upper part by 32bit move.
1805 (define_peephole2
1806   [(match_scratch:DI 2 "r")
1807    (set (match_operand:DI 0 "push_operand" "")
1808         (match_operand:DI 1 "immediate_operand" ""))]
1809   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1810    && !x86_64_immediate_operand (operands[1], DImode)"
1811   [(set (match_dup 2) (match_dup 1))
1812    (set (match_dup 0) (match_dup 2))]
1813   "")
1814
1815 ;; We need to define this as both peepholer and splitter for case
1816 ;; peephole2 pass is not run.
1817 ;; "&& 1" is needed to keep it from matching the previous pattern.
1818 (define_peephole2
1819   [(set (match_operand:DI 0 "push_operand" "")
1820         (match_operand:DI 1 "immediate_operand" ""))]
1821   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1822    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1823   [(set (match_dup 0) (match_dup 1))
1824    (set (match_dup 2) (match_dup 3))]
1825   "split_di (operands + 1, 1, operands + 2, operands + 3);
1826    operands[1] = gen_lowpart (DImode, operands[2]);
1827    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1828                                                     GEN_INT (4)));
1829   ")
1830
1831 (define_split
1832   [(set (match_operand:DI 0 "push_operand" "")
1833         (match_operand:DI 1 "immediate_operand" ""))]
1834   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1835    && !symbolic_operand (operands[1], DImode)
1836    && !x86_64_immediate_operand (operands[1], DImode)"
1837   [(set (match_dup 0) (match_dup 1))
1838    (set (match_dup 2) (match_dup 3))]
1839   "split_di (operands + 1, 1, operands + 2, operands + 3);
1840    operands[1] = gen_lowpart (DImode, operands[2]);
1841    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1842                                                     GEN_INT (4)));
1843   ")
1844
1845 (define_insn "*pushdi2_prologue_rex64"
1846   [(set (match_operand:DI 0 "push_operand" "=<")
1847         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1848    (clobber (mem:BLK (scratch)))]
1849   "TARGET_64BIT"
1850   "push{q}\t%1"
1851   [(set_attr "type" "push")
1852    (set_attr "mode" "DI")])
1853
1854 (define_insn "*popdi1_epilogue_rex64"
1855   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1856         (mem:DI (reg:DI SP_REG)))
1857    (set (reg:DI SP_REG)
1858         (plus:DI (reg:DI SP_REG) (const_int 8)))
1859    (clobber (mem:BLK (scratch)))]
1860   "TARGET_64BIT"
1861   "pop{q}\t%0"
1862   [(set_attr "type" "pop")
1863    (set_attr "mode" "DI")])
1864
1865 (define_insn "popdi1"
1866   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1867         (mem:DI (reg:DI SP_REG)))
1868    (set (reg:DI SP_REG)
1869         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1870   "TARGET_64BIT"
1871   "pop{q}\t%0"
1872   [(set_attr "type" "pop")
1873    (set_attr "mode" "DI")])
1874
1875 (define_insn "*movdi_xor_rex64"
1876   [(set (match_operand:DI 0 "register_operand" "=r")
1877         (match_operand:DI 1 "const0_operand" "i"))
1878    (clobber (reg:CC FLAGS_REG))]
1879   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1880    && reload_completed"
1881   "xor{l}\t{%k0, %k0|%k0, %k0}"
1882   [(set_attr "type" "alu1")
1883    (set_attr "mode" "SI")
1884    (set_attr "length_immediate" "0")])
1885
1886 (define_insn "*movdi_or_rex64"
1887   [(set (match_operand:DI 0 "register_operand" "=r")
1888         (match_operand:DI 1 "const_int_operand" "i"))
1889    (clobber (reg:CC FLAGS_REG))]
1890   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1891    && reload_completed
1892    && operands[1] == constm1_rtx"
1893 {
1894   operands[1] = constm1_rtx;
1895   return "or{q}\t{%1, %0|%0, %1}";
1896 }
1897   [(set_attr "type" "alu1")
1898    (set_attr "mode" "DI")
1899    (set_attr "length_immediate" "1")])
1900
1901 (define_insn "*movdi_2"
1902   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*x,!*x")
1903         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*x,*x,m"))]
1904   "!TARGET_64BIT
1905    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1906   "@
1907    #
1908    #
1909    movq\t{%1, %0|%0, %1}
1910    movq\t{%1, %0|%0, %1}
1911    movq\t{%1, %0|%0, %1}
1912    movdqa\t{%1, %0|%0, %1}
1913    movq\t{%1, %0|%0, %1}"
1914   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1915    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1916
1917 (define_split
1918   [(set (match_operand:DI 0 "push_operand" "")
1919         (match_operand:DI 1 "general_operand" ""))]
1920   "!TARGET_64BIT && reload_completed
1921    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1922   [(const_int 0)]
1923   "ix86_split_long_move (operands); DONE;")
1924
1925 ;; %%% This multiword shite has got to go.
1926 (define_split
1927   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1928         (match_operand:DI 1 "general_operand" ""))]
1929   "!TARGET_64BIT && reload_completed
1930    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1931    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1932   [(const_int 0)]
1933   "ix86_split_long_move (operands); DONE;")
1934
1935 (define_insn "*movdi_1_rex64"
1936   [(set (match_operand:DI 0 "nonimmediate_operand"
1937                 "=r,r  ,r,mr,!mr,!*y,!rm,!*y,!*x,!rm,!*x,!*x,!*y")
1938         (match_operand:DI 1 "general_operand"
1939                 "Z ,rem,i,re,n  ,*y ,*y ,rm ,*x ,*x ,rm ,*y ,*x"))]
1940   "TARGET_64BIT
1941    && (TARGET_INTER_UNIT_MOVES || optimize_size)
1942    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1943 {
1944   switch (get_attr_type (insn))
1945     {
1946     case TYPE_SSECVT:
1947       if (which_alternative == 11)
1948         return "movq2dq\t{%1, %0|%0, %1}";
1949       else
1950         return "movdq2q\t{%1, %0|%0, %1}";
1951     case TYPE_SSEMOV:
1952       if (get_attr_mode (insn) == MODE_TI)
1953           return "movdqa\t{%1, %0|%0, %1}";
1954       /* FALLTHRU */
1955     case TYPE_MMXMOV:
1956       /* Moves from and into integer register is done using movd opcode with
1957          REX prefix.  */
1958       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1959           return "movd\t{%1, %0|%0, %1}";
1960       return "movq\t{%1, %0|%0, %1}";
1961     case TYPE_MULTI:
1962       return "#";
1963     case TYPE_LEA:
1964       return "lea{q}\t{%a1, %0|%0, %a1}";
1965     default:
1966       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1967         abort ();
1968       if (get_attr_mode (insn) == MODE_SI)
1969         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1970       else if (which_alternative == 2)
1971         return "movabs{q}\t{%1, %0|%0, %1}";
1972       else
1973         return "mov{q}\t{%1, %0|%0, %1}";
1974     }
1975 }
1976   [(set (attr "type")
1977      (cond [(eq_attr "alternative" "5,6,7")
1978               (const_string "mmxmov")
1979             (eq_attr "alternative" "8,9,10")
1980               (const_string "ssemov")
1981             (eq_attr "alternative" "11,12")
1982               (const_string "ssecvt")
1983             (eq_attr "alternative" "4")
1984               (const_string "multi")
1985             (and (ne (symbol_ref "flag_pic") (const_int 0))
1986                  (match_operand:DI 1 "symbolic_operand" ""))
1987               (const_string "lea")
1988            ]
1989            (const_string "imov")))
1990    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
1991    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
1992    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
1993
1994 (define_insn "*movdi_1_rex64_nointerunit"
1995   [(set (match_operand:DI 0 "nonimmediate_operand"
1996                 "=r,r ,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
1997         (match_operand:DI 1 "general_operand"
1998                 "Z,rem,i,re,n  ,*y ,*y,m  ,*Y ,*Y,m"))]
1999   "TARGET_64BIT
2000    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2001    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2002 {
2003   switch (get_attr_type (insn))
2004     {
2005     case TYPE_SSEMOV:
2006       if (get_attr_mode (insn) == MODE_TI)
2007           return "movdqa\t{%1, %0|%0, %1}";
2008       /* FALLTHRU */
2009     case TYPE_MMXMOV:
2010       return "movq\t{%1, %0|%0, %1}";
2011     case TYPE_MULTI:
2012       return "#";
2013     case TYPE_LEA:
2014       return "lea{q}\t{%a1, %0|%0, %a1}";
2015     default:
2016       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2017         abort ();
2018       if (get_attr_mode (insn) == MODE_SI)
2019         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2020       else if (which_alternative == 2)
2021         return "movabs{q}\t{%1, %0|%0, %1}";
2022       else
2023         return "mov{q}\t{%1, %0|%0, %1}";
2024     }
2025 }
2026   [(set (attr "type")
2027      (cond [(eq_attr "alternative" "5,6,7")
2028               (const_string "mmxmov")
2029             (eq_attr "alternative" "8,9,10")
2030               (const_string "ssemov")
2031             (eq_attr "alternative" "4")
2032               (const_string "multi")
2033             (and (ne (symbol_ref "flag_pic") (const_int 0))
2034                  (match_operand:DI 1 "symbolic_operand" ""))
2035               (const_string "lea")
2036            ]
2037            (const_string "imov")))
2038    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2039    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2040    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2041
2042 ;; Stores and loads of ax to arbitrary constant address.
2043 ;; We fake an second form of instruction to force reload to load address
2044 ;; into register when rax is not available
2045 (define_insn "*movabsdi_1_rex64"
2046   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2047         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2048   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2049   "@
2050    movabs{q}\t{%1, %P0|%P0, %1}
2051    mov{q}\t{%1, %a0|%a0, %1}"
2052   [(set_attr "type" "imov")
2053    (set_attr "modrm" "0,*")
2054    (set_attr "length_address" "8,0")
2055    (set_attr "length_immediate" "0,*")
2056    (set_attr "memory" "store")
2057    (set_attr "mode" "DI")])
2058
2059 (define_insn "*movabsdi_2_rex64"
2060   [(set (match_operand:DI 0 "register_operand" "=a,r")
2061         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2062   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2063   "@
2064    movabs{q}\t{%P1, %0|%0, %P1}
2065    mov{q}\t{%a1, %0|%0, %a1}"
2066   [(set_attr "type" "imov")
2067    (set_attr "modrm" "0,*")
2068    (set_attr "length_address" "8,0")
2069    (set_attr "length_immediate" "0")
2070    (set_attr "memory" "load")
2071    (set_attr "mode" "DI")])
2072
2073 ;; Convert impossible stores of immediate to existing instructions.
2074 ;; First try to get scratch register and go through it.  In case this
2075 ;; fails, move by 32bit parts.
2076 (define_peephole2
2077   [(match_scratch:DI 2 "r")
2078    (set (match_operand:DI 0 "memory_operand" "")
2079         (match_operand:DI 1 "immediate_operand" ""))]
2080   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2081    && !x86_64_immediate_operand (operands[1], DImode)"
2082   [(set (match_dup 2) (match_dup 1))
2083    (set (match_dup 0) (match_dup 2))]
2084   "")
2085
2086 ;; We need to define this as both peepholer and splitter for case
2087 ;; peephole2 pass is not run.
2088 ;; "&& 1" is needed to keep it from matching the previous pattern.
2089 (define_peephole2
2090   [(set (match_operand:DI 0 "memory_operand" "")
2091         (match_operand:DI 1 "immediate_operand" ""))]
2092   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2093    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2094   [(set (match_dup 2) (match_dup 3))
2095    (set (match_dup 4) (match_dup 5))]
2096   "split_di (operands, 2, operands + 2, operands + 4);")
2097
2098 (define_split
2099   [(set (match_operand:DI 0 "memory_operand" "")
2100         (match_operand:DI 1 "immediate_operand" ""))]
2101   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2102    && !symbolic_operand (operands[1], DImode)
2103    && !x86_64_immediate_operand (operands[1], DImode)"
2104   [(set (match_dup 2) (match_dup 3))
2105    (set (match_dup 4) (match_dup 5))]
2106   "split_di (operands, 2, operands + 2, operands + 4);")
2107
2108 (define_insn "*swapdi_rex64"
2109   [(set (match_operand:DI 0 "register_operand" "+r")
2110         (match_operand:DI 1 "register_operand" "+r"))
2111    (set (match_dup 1)
2112         (match_dup 0))]
2113   "TARGET_64BIT"
2114   "xchg{q}\t%1, %0"
2115   [(set_attr "type" "imov")
2116    (set_attr "mode" "DI")
2117    (set_attr "pent_pair" "np")
2118    (set_attr "athlon_decode" "vector")])
2119
2120 (define_expand "movsf"
2121   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2122         (match_operand:SF 1 "general_operand" ""))]
2123   ""
2124   "ix86_expand_move (SFmode, operands); DONE;")
2125
2126 (define_insn "*pushsf"
2127   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2128         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2129   "!TARGET_64BIT"
2130 {
2131   switch (which_alternative)
2132     {
2133     case 1:
2134       return "push{l}\t%1";
2135
2136     default:
2137       /* This insn should be already split before reg-stack.  */
2138       abort ();
2139     }
2140 }
2141   [(set_attr "type" "multi,push,multi")
2142    (set_attr "mode" "SF,SI,SF")])
2143
2144 (define_insn "*pushsf_rex64"
2145   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2146         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2147   "TARGET_64BIT"
2148 {
2149   switch (which_alternative)
2150     {
2151     case 1:
2152       return "push{q}\t%q1";
2153
2154     default:
2155       /* This insn should be already split before reg-stack.  */
2156       abort ();
2157     }
2158 }
2159   [(set_attr "type" "multi,push,multi")
2160    (set_attr "mode" "SF,DI,SF")])
2161
2162 (define_split
2163   [(set (match_operand:SF 0 "push_operand" "")
2164         (match_operand:SF 1 "memory_operand" ""))]
2165   "reload_completed
2166    && GET_CODE (operands[1]) == MEM
2167    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2168    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2169   [(set (match_dup 0)
2170         (match_dup 1))]
2171   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2172
2173
2174 ;; %%% Kill this when call knows how to work this out.
2175 (define_split
2176   [(set (match_operand:SF 0 "push_operand" "")
2177         (match_operand:SF 1 "any_fp_register_operand" ""))]
2178   "!TARGET_64BIT"
2179   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2180    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2181
2182 (define_split
2183   [(set (match_operand:SF 0 "push_operand" "")
2184         (match_operand:SF 1 "any_fp_register_operand" ""))]
2185   "TARGET_64BIT"
2186   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2187    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2188
2189 (define_insn "*movsf_1"
2190   [(set (match_operand:SF 0 "nonimmediate_operand"
2191           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2192         (match_operand:SF 1 "general_operand"
2193           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2194   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2195    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2196    && (reload_in_progress || reload_completed
2197        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2198        || GET_CODE (operands[1]) != CONST_DOUBLE
2199        || memory_operand (operands[0], SFmode))" 
2200 {
2201   switch (which_alternative)
2202     {
2203     case 0:
2204       return output_387_reg_move (insn, operands);
2205
2206     case 1:
2207       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2208         return "fstp%z0\t%y0";
2209       else
2210         return "fst%z0\t%y0";
2211
2212     case 2:
2213       return standard_80387_constant_opcode (operands[1]);
2214
2215     case 3:
2216     case 4:
2217       return "mov{l}\t{%1, %0|%0, %1}";
2218     case 5:
2219       if (get_attr_mode (insn) == MODE_TI)
2220         return "pxor\t%0, %0";
2221       else
2222         return "xorps\t%0, %0";
2223     case 6:
2224       if (get_attr_mode (insn) == MODE_V4SF)
2225         return "movaps\t{%1, %0|%0, %1}";
2226       else
2227         return "movss\t{%1, %0|%0, %1}";
2228     case 7:
2229     case 8:
2230       return "movss\t{%1, %0|%0, %1}";
2231
2232     case 9:
2233     case 10:
2234       return "movd\t{%1, %0|%0, %1}";
2235
2236     case 11:
2237       return "movq\t{%1, %0|%0, %1}";
2238
2239     default:
2240       abort();
2241     }
2242 }
2243   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2244    (set (attr "mode")
2245         (cond [(eq_attr "alternative" "3,4,9,10")
2246                  (const_string "SI")
2247                (eq_attr "alternative" "5")
2248                  (if_then_else
2249                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2250                                  (const_int 0))
2251                              (ne (symbol_ref "TARGET_SSE2")
2252                                  (const_int 0)))
2253                         (eq (symbol_ref "optimize_size")
2254                             (const_int 0)))
2255                    (const_string "TI")
2256                    (const_string "V4SF"))
2257                /* For architectures resolving dependencies on
2258                   whole SSE registers use APS move to break dependency
2259                   chains, otherwise use short move to avoid extra work. 
2260
2261                   Do the same for architectures resolving dependencies on
2262                   the parts.  While in DF mode it is better to always handle
2263                   just register parts, the SF mode is different due to lack
2264                   of instructions to load just part of the register.  It is
2265                   better to maintain the whole registers in single format
2266                   to avoid problems on using packed logical operations.  */
2267                (eq_attr "alternative" "6")
2268                  (if_then_else
2269                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2270                             (const_int 0))
2271                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2272                             (const_int 0)))
2273                    (const_string "V4SF")
2274                    (const_string "SF"))
2275                (eq_attr "alternative" "11")
2276                  (const_string "DI")]
2277                (const_string "SF")))])
2278
2279 (define_insn "*movsf_1_nointerunit"
2280   [(set (match_operand:SF 0 "nonimmediate_operand"
2281           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!m,!*y")
2282         (match_operand:SF 1 "general_operand"
2283           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,m  ,*y,*y"))]
2284   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2285    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2286    && (reload_in_progress || reload_completed
2287        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2288        || GET_CODE (operands[1]) != CONST_DOUBLE
2289        || memory_operand (operands[0], SFmode))" 
2290 {
2291   switch (which_alternative)
2292     {
2293     case 0:
2294       return output_387_reg_move (insn, operands);
2295
2296     case 1:
2297       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2298         return "fstp%z0\t%y0";
2299       else
2300         return "fst%z0\t%y0";
2301
2302     case 2:
2303       return standard_80387_constant_opcode (operands[1]);
2304
2305     case 3:
2306     case 4:
2307       return "mov{l}\t{%1, %0|%0, %1}";
2308     case 5:
2309       if (get_attr_mode (insn) == MODE_TI)
2310         return "pxor\t%0, %0";
2311       else
2312         return "xorps\t%0, %0";
2313     case 6:
2314       if (get_attr_mode (insn) == MODE_V4SF)
2315         return "movaps\t{%1, %0|%0, %1}";
2316       else
2317         return "movss\t{%1, %0|%0, %1}";
2318     case 7:
2319     case 8:
2320       return "movss\t{%1, %0|%0, %1}";
2321
2322     case 9:
2323     case 10:
2324       return "movd\t{%1, %0|%0, %1}";
2325
2326     case 11:
2327       return "movq\t{%1, %0|%0, %1}";
2328
2329     default:
2330       abort();
2331     }
2332 }
2333   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2334    (set (attr "mode")
2335         (cond [(eq_attr "alternative" "3,4,9,10")
2336                  (const_string "SI")
2337                (eq_attr "alternative" "5")
2338                  (if_then_else
2339                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2340                                  (const_int 0))
2341                              (ne (symbol_ref "TARGET_SSE2")
2342                                  (const_int 0)))
2343                         (eq (symbol_ref "optimize_size")
2344                             (const_int 0)))
2345                    (const_string "TI")
2346                    (const_string "V4SF"))
2347                /* For architectures resolving dependencies on
2348                   whole SSE registers use APS move to break dependency
2349                   chains, otherwise use short move to avoid extra work. 
2350
2351                   Do the same for architectures resolving dependencies on
2352                   the parts.  While in DF mode it is better to always handle
2353                   just register parts, the SF mode is different due to lack
2354                   of instructions to load just part of the register.  It is
2355                   better to maintain the whole registers in single format
2356                   to avoid problems on using packed logical operations.  */
2357                (eq_attr "alternative" "6")
2358                  (if_then_else
2359                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2360                             (const_int 0))
2361                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2362                             (const_int 0)))
2363                    (const_string "V4SF")
2364                    (const_string "SF"))
2365                (eq_attr "alternative" "11")
2366                  (const_string "DI")]
2367                (const_string "SF")))])
2368
2369 (define_insn "*swapsf"
2370   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2371         (match_operand:SF 1 "fp_register_operand" "+f"))
2372    (set (match_dup 1)
2373         (match_dup 0))]
2374   "reload_completed || TARGET_80387"
2375 {
2376   if (STACK_TOP_P (operands[0]))
2377     return "fxch\t%1";
2378   else
2379     return "fxch\t%0";
2380 }
2381   [(set_attr "type" "fxch")
2382    (set_attr "mode" "SF")])
2383
2384 (define_expand "movdf"
2385   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2386         (match_operand:DF 1 "general_operand" ""))]
2387   ""
2388   "ix86_expand_move (DFmode, operands); DONE;")
2389
2390 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2391 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2392 ;; On the average, pushdf using integers can be still shorter.  Allow this
2393 ;; pattern for optimize_size too.
2394
2395 (define_insn "*pushdf_nointeger"
2396   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2397         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2398   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2399 {
2400   /* This insn should be already split before reg-stack.  */
2401   abort ();
2402 }
2403   [(set_attr "type" "multi")
2404    (set_attr "mode" "DF,SI,SI,DF")])
2405
2406 (define_insn "*pushdf_integer"
2407   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2408         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2409   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2410 {
2411   /* This insn should be already split before reg-stack.  */
2412   abort ();
2413 }
2414   [(set_attr "type" "multi")
2415    (set_attr "mode" "DF,SI,DF")])
2416
2417 ;; %%% Kill this when call knows how to work this out.
2418 (define_split
2419   [(set (match_operand:DF 0 "push_operand" "")
2420         (match_operand:DF 1 "any_fp_register_operand" ""))]
2421   "!TARGET_64BIT && reload_completed"
2422   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2423    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2424   "")
2425
2426 (define_split
2427   [(set (match_operand:DF 0 "push_operand" "")
2428         (match_operand:DF 1 "any_fp_register_operand" ""))]
2429   "TARGET_64BIT && reload_completed"
2430   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2431    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2432   "")
2433
2434 (define_split
2435   [(set (match_operand:DF 0 "push_operand" "")
2436         (match_operand:DF 1 "general_operand" ""))]
2437   "reload_completed"
2438   [(const_int 0)]
2439   "ix86_split_long_move (operands); DONE;")
2440
2441 ;; Moving is usually shorter when only FP registers are used. This separate
2442 ;; movdf pattern avoids the use of integer registers for FP operations
2443 ;; when optimizing for size.
2444
2445 (define_insn "*movdf_nointeger"
2446   [(set (match_operand:DF 0 "nonimmediate_operand"
2447                                 "=f#x,m  ,f#x,*r  ,o  ,x#f,x#f,x#f  ,m")
2448         (match_operand:DF 1 "general_operand"
2449                                 "fm#x,f#x,G  ,*roF,F*r,C  ,x#f,xHm#f,x#f"))]
2450   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2451    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2452    && (reload_in_progress || reload_completed
2453        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2454        || GET_CODE (operands[1]) != CONST_DOUBLE
2455        || memory_operand (operands[0], DFmode))" 
2456 {
2457   switch (which_alternative)
2458     {
2459     case 0:
2460       return output_387_reg_move (insn, operands);
2461
2462     case 1:
2463       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2464         return "fstp%z0\t%y0";
2465       else
2466         return "fst%z0\t%y0";
2467
2468     case 2:
2469       return standard_80387_constant_opcode (operands[1]);
2470
2471     case 3:
2472     case 4:
2473       return "#";
2474     case 5:
2475       switch (get_attr_mode (insn))
2476         {
2477         case MODE_V4SF:
2478           return "xorps\t%0, %0";
2479         case MODE_V2DF:
2480           return "xorpd\t%0, %0";
2481         case MODE_TI:
2482           return "pxor\t%0, %0";
2483         default:
2484           abort ();
2485         }
2486     case 6:
2487     case 7:
2488     case 8:
2489       switch (get_attr_mode (insn))
2490         {
2491         case MODE_V4SF:
2492           return "movaps\t{%1, %0|%0, %1}";
2493         case MODE_V2DF:
2494           return "movapd\t{%1, %0|%0, %1}";
2495         case MODE_TI:
2496           return "movdqa\t{%1, %0|%0, %1}";
2497         case MODE_DI:
2498           return "movq\t{%1, %0|%0, %1}";
2499         case MODE_DF:
2500           return "movsd\t{%1, %0|%0, %1}";
2501         case MODE_V1DF:
2502           return "movlpd\t{%1, %0|%0, %1}";
2503         default:
2504           abort ();
2505         }
2506
2507     default:
2508       abort();
2509     }
2510 }
2511   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2512    (set (attr "mode")
2513         (cond [(eq_attr "alternative" "3,4")
2514                  (const_string "SI")
2515
2516                /* For SSE1, we have many fewer alternatives.  */
2517                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2518                  (cond [(eq_attr "alternative" "5,6")
2519                           (if_then_else
2520                             (ne (symbol_ref "optimize_size") (const_int 0))
2521                             (const_string "V4SF")
2522                             (const_string "TI"))
2523                        ]
2524                    (const_string "DI"))
2525
2526                /* xorps is one byte shorter.  */
2527                (eq_attr "alternative" "5")
2528                  (cond [(ne (symbol_ref "optimize_size")
2529                             (const_int 0))
2530                           (const_string "V4SF")
2531                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2532                             (const_int 0))
2533                           (const_string "TI")
2534                        ]
2535                        (const_string "V2DF"))
2536
2537                /* For architectures resolving dependencies on
2538                   whole SSE registers use APD move to break dependency
2539                   chains, otherwise use short move to avoid extra work.
2540
2541                   movaps encodes one byte shorter.  */
2542                (eq_attr "alternative" "6")
2543                  (cond
2544                    [(ne (symbol_ref "optimize_size")
2545                         (const_int 0))
2546                       (const_string "V4SF")
2547                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2548                         (const_int 0))
2549                       (const_string "V2DF")
2550                    ]
2551                    (const_string "DF"))
2552                /* For architectures resolving dependencies on register
2553                   parts we may avoid extra work to zero out upper part
2554                   of register.  */
2555                (eq_attr "alternative" "7")
2556                  (if_then_else
2557                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2558                        (const_int 0))
2559                    (const_string "V1DF")
2560                    (const_string "DF"))
2561               ]
2562               (const_string "DF")))])
2563
2564 (define_insn "*movdf_integer"
2565   [(set (match_operand:DF 0 "nonimmediate_operand"
2566                         "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y#rf,Y#rf,Y#rf ,m")
2567         (match_operand:DF 1 "general_operand"
2568                         "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C   ,Y#rf,Ym#rf,Y#rf"))]
2569   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2570    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2571    && (reload_in_progress || reload_completed
2572        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2573        || GET_CODE (operands[1]) != CONST_DOUBLE
2574        || memory_operand (operands[0], DFmode))" 
2575 {
2576   switch (which_alternative)
2577     {
2578     case 0:
2579       return output_387_reg_move (insn, operands);
2580
2581     case 1:
2582       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2583         return "fstp%z0\t%y0";
2584       else
2585         return "fst%z0\t%y0";
2586
2587     case 2:
2588       return standard_80387_constant_opcode (operands[1]);
2589
2590     case 3:
2591     case 4:
2592       return "#";
2593
2594     case 5:
2595       switch (get_attr_mode (insn))
2596         {
2597         case MODE_V4SF:
2598           return "xorps\t%0, %0";
2599         case MODE_V2DF:
2600           return "xorpd\t%0, %0";
2601         case MODE_TI:
2602           return "pxor\t%0, %0";
2603         default:
2604           abort ();
2605         }
2606     case 6:
2607     case 7:
2608     case 8:
2609       switch (get_attr_mode (insn))
2610         {
2611         case MODE_V4SF:
2612           return "movaps\t{%1, %0|%0, %1}";
2613         case MODE_V2DF:
2614           return "movapd\t{%1, %0|%0, %1}";
2615         case MODE_TI:
2616           return "movdqa\t{%1, %0|%0, %1}";
2617         case MODE_DI:
2618           return "movq\t{%1, %0|%0, %1}";
2619         case MODE_DF:
2620           return "movsd\t{%1, %0|%0, %1}";
2621         case MODE_V1DF:
2622           return "movlpd\t{%1, %0|%0, %1}";
2623         default:
2624           abort ();
2625         }
2626
2627     default:
2628       abort();
2629     }
2630 }
2631   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2632    (set (attr "mode")
2633         (cond [(eq_attr "alternative" "3,4")
2634                  (const_string "SI")
2635
2636                /* For SSE1, we have many fewer alternatives.  */
2637                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2638                  (cond [(eq_attr "alternative" "5,6")
2639                           (if_then_else
2640                             (ne (symbol_ref "optimize_size") (const_int 0))
2641                             (const_string "V4SF")
2642                             (const_string "TI"))
2643                        ]
2644                    (const_string "DI"))
2645
2646                /* xorps is one byte shorter.  */
2647                (eq_attr "alternative" "5")
2648                  (cond [(ne (symbol_ref "optimize_size")
2649                             (const_int 0))
2650                           (const_string "V4SF")
2651                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2652                             (const_int 0))
2653                           (const_string "TI")
2654                        ]
2655                        (const_string "V2DF"))
2656
2657                /* For architectures resolving dependencies on
2658                   whole SSE registers use APD move to break dependency
2659                   chains, otherwise use short move to avoid extra work.
2660
2661                   movaps encodes one byte shorter.  */
2662                (eq_attr "alternative" "6")
2663                  (cond
2664                    [(ne (symbol_ref "optimize_size")
2665                         (const_int 0))
2666                       (const_string "V4SF")
2667                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2668                         (const_int 0))
2669                       (const_string "V2DF")
2670                    ]
2671                    (const_string "DF"))
2672                /* For architectures resolving dependencies on register
2673                   parts we may avoid extra work to zero out upper part
2674                   of register.  */
2675                (eq_attr "alternative" "7")
2676                  (if_then_else
2677                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2678                        (const_int 0))
2679                    (const_string "V1DF")
2680                    (const_string "DF"))
2681               ]
2682               (const_string "DF")))])
2683
2684 (define_split
2685   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2686         (match_operand:DF 1 "general_operand" ""))]
2687   "reload_completed
2688    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2689    && ! (ANY_FP_REG_P (operands[0]) || 
2690          (GET_CODE (operands[0]) == SUBREG
2691           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2692    && ! (ANY_FP_REG_P (operands[1]) || 
2693          (GET_CODE (operands[1]) == SUBREG
2694           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2695   [(const_int 0)]
2696   "ix86_split_long_move (operands); DONE;")
2697
2698 (define_insn "*swapdf"
2699   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2700         (match_operand:DF 1 "fp_register_operand" "+f"))
2701    (set (match_dup 1)
2702         (match_dup 0))]
2703   "reload_completed || TARGET_80387"
2704 {
2705   if (STACK_TOP_P (operands[0]))
2706     return "fxch\t%1";
2707   else
2708     return "fxch\t%0";
2709 }
2710   [(set_attr "type" "fxch")
2711    (set_attr "mode" "DF")])
2712
2713 (define_expand "movxf"
2714   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2715         (match_operand:XF 1 "general_operand" ""))]
2716   ""
2717   "ix86_expand_move (XFmode, operands); DONE;")
2718
2719 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2720 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2721 ;; Pushing using integer instructions is longer except for constants
2722 ;; and direct memory references.
2723 ;; (assuming that any given constant is pushed only once, but this ought to be
2724 ;;  handled elsewhere).
2725
2726 (define_insn "*pushxf_nointeger"
2727   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2728         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2729   "optimize_size"
2730 {
2731   /* This insn should be already split before reg-stack.  */
2732   abort ();
2733 }
2734   [(set_attr "type" "multi")
2735    (set_attr "mode" "XF,SI,SI")])
2736
2737 (define_insn "*pushxf_integer"
2738   [(set (match_operand:XF 0 "push_operand" "=<,<")
2739         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2740   "!optimize_size"
2741 {
2742   /* This insn should be already split before reg-stack.  */
2743   abort ();
2744 }
2745   [(set_attr "type" "multi")
2746    (set_attr "mode" "XF,SI")])
2747
2748 (define_split
2749   [(set (match_operand 0 "push_operand" "")
2750         (match_operand 1 "general_operand" ""))]
2751   "reload_completed
2752    && (GET_MODE (operands[0]) == XFmode
2753        || GET_MODE (operands[0]) == DFmode)
2754    && !ANY_FP_REG_P (operands[1])"
2755   [(const_int 0)]
2756   "ix86_split_long_move (operands); DONE;")
2757
2758 (define_split
2759   [(set (match_operand:XF 0 "push_operand" "")
2760         (match_operand:XF 1 "any_fp_register_operand" ""))]
2761   "!TARGET_64BIT"
2762   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2763    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2764   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2765
2766 (define_split
2767   [(set (match_operand:XF 0 "push_operand" "")
2768         (match_operand:XF 1 "any_fp_register_operand" ""))]
2769   "TARGET_64BIT"
2770   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2771    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2772   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2773
2774 ;; Do not use integer registers when optimizing for size
2775 (define_insn "*movxf_nointeger"
2776   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2777         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2778   "optimize_size
2779    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2780    && (reload_in_progress || reload_completed
2781        || GET_CODE (operands[1]) != CONST_DOUBLE
2782        || memory_operand (operands[0], XFmode))" 
2783 {
2784   switch (which_alternative)
2785     {
2786     case 0:
2787       return output_387_reg_move (insn, operands);
2788
2789     case 1:
2790       /* There is no non-popping store to memory for XFmode.  So if
2791          we need one, follow the store with a load.  */
2792       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2793         return "fstp%z0\t%y0\;fld%z0\t%y0";
2794       else
2795         return "fstp%z0\t%y0";
2796
2797     case 2:
2798       return standard_80387_constant_opcode (operands[1]);
2799
2800     case 3: case 4:
2801       return "#";
2802     }
2803   abort();
2804 }
2805   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2806    (set_attr "mode" "XF,XF,XF,SI,SI")])
2807
2808 (define_insn "*movxf_integer"
2809   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2810         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2811   "!optimize_size
2812    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2813    && (reload_in_progress || reload_completed
2814        || GET_CODE (operands[1]) != CONST_DOUBLE
2815        || memory_operand (operands[0], XFmode))" 
2816 {
2817   switch (which_alternative)
2818     {
2819     case 0:
2820       return output_387_reg_move (insn, operands);
2821
2822     case 1:
2823       /* There is no non-popping store to memory for XFmode.  So if
2824          we need one, follow the store with a load.  */
2825       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2826         return "fstp%z0\t%y0\;fld%z0\t%y0";
2827       else
2828         return "fstp%z0\t%y0";
2829
2830     case 2:
2831       return standard_80387_constant_opcode (operands[1]);
2832
2833     case 3: case 4:
2834       return "#";
2835     }
2836   abort();
2837 }
2838   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2839    (set_attr "mode" "XF,XF,XF,SI,SI")])
2840
2841 (define_split
2842   [(set (match_operand 0 "nonimmediate_operand" "")
2843         (match_operand 1 "general_operand" ""))]
2844   "reload_completed
2845    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2846    && GET_MODE (operands[0]) == XFmode
2847    && ! (ANY_FP_REG_P (operands[0]) || 
2848          (GET_CODE (operands[0]) == SUBREG
2849           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2850    && ! (ANY_FP_REG_P (operands[1]) || 
2851          (GET_CODE (operands[1]) == SUBREG
2852           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2853   [(const_int 0)]
2854   "ix86_split_long_move (operands); DONE;")
2855
2856 (define_split
2857   [(set (match_operand 0 "register_operand" "")
2858         (match_operand 1 "memory_operand" ""))]
2859   "reload_completed
2860    && GET_CODE (operands[1]) == MEM
2861    && (GET_MODE (operands[0]) == XFmode
2862        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2863    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2864    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2865   [(set (match_dup 0) (match_dup 1))]
2866 {
2867   rtx c = get_pool_constant (XEXP (operands[1], 0));
2868   rtx r = operands[0];
2869
2870   if (GET_CODE (r) == SUBREG)
2871     r = SUBREG_REG (r);
2872
2873   if (SSE_REG_P (r))
2874     {
2875       if (!standard_sse_constant_p (c))
2876         FAIL;
2877     }
2878   else if (FP_REG_P (r))
2879     {
2880       if (!standard_80387_constant_p (c))
2881         FAIL;
2882     }
2883   else if (MMX_REG_P (r))
2884     FAIL;
2885
2886   operands[1] = c;
2887 })
2888
2889 (define_insn "swapxf"
2890   [(set (match_operand:XF 0 "register_operand" "+f")
2891         (match_operand:XF 1 "register_operand" "+f"))
2892    (set (match_dup 1)
2893         (match_dup 0))]
2894   "TARGET_80387"
2895 {
2896   if (STACK_TOP_P (operands[0]))
2897     return "fxch\t%1";
2898   else
2899     return "fxch\t%0";
2900 }
2901   [(set_attr "type" "fxch")
2902    (set_attr "mode" "XF")])
2903 \f
2904 ;; Zero extension instructions
2905
2906 (define_expand "zero_extendhisi2"
2907   [(set (match_operand:SI 0 "register_operand" "")
2908      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2909   ""
2910 {
2911   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2912     {
2913       operands[1] = force_reg (HImode, operands[1]);
2914       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2915       DONE;
2916     }
2917 })
2918
2919 (define_insn "zero_extendhisi2_and"
2920   [(set (match_operand:SI 0 "register_operand" "=r")
2921      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2922    (clobber (reg:CC FLAGS_REG))]
2923   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2924   "#"
2925   [(set_attr "type" "alu1")
2926    (set_attr "mode" "SI")])
2927
2928 (define_split
2929   [(set (match_operand:SI 0 "register_operand" "")
2930         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2931    (clobber (reg:CC FLAGS_REG))]
2932   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2933   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2934               (clobber (reg:CC FLAGS_REG))])]
2935   "")
2936
2937 (define_insn "*zero_extendhisi2_movzwl"
2938   [(set (match_operand:SI 0 "register_operand" "=r")
2939      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2940   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2941   "movz{wl|x}\t{%1, %0|%0, %1}"
2942   [(set_attr "type" "imovx")
2943    (set_attr "mode" "SI")])
2944
2945 (define_expand "zero_extendqihi2"
2946   [(parallel
2947     [(set (match_operand:HI 0 "register_operand" "")
2948        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2949      (clobber (reg:CC FLAGS_REG))])]
2950   ""
2951   "")
2952
2953 (define_insn "*zero_extendqihi2_and"
2954   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2955      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2956    (clobber (reg:CC FLAGS_REG))]
2957   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2958   "#"
2959   [(set_attr "type" "alu1")
2960    (set_attr "mode" "HI")])
2961
2962 (define_insn "*zero_extendqihi2_movzbw_and"
2963   [(set (match_operand:HI 0 "register_operand" "=r,r")
2964      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2965    (clobber (reg:CC FLAGS_REG))]
2966   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2967   "#"
2968   [(set_attr "type" "imovx,alu1")
2969    (set_attr "mode" "HI")])
2970
2971 (define_insn "*zero_extendqihi2_movzbw"
2972   [(set (match_operand:HI 0 "register_operand" "=r")
2973      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2974   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2975   "movz{bw|x}\t{%1, %0|%0, %1}"
2976   [(set_attr "type" "imovx")
2977    (set_attr "mode" "HI")])
2978
2979 ;; For the movzbw case strip only the clobber
2980 (define_split
2981   [(set (match_operand:HI 0 "register_operand" "")
2982         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2983    (clobber (reg:CC FLAGS_REG))]
2984   "reload_completed 
2985    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2986    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2987   [(set (match_operand:HI 0 "register_operand" "")
2988         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2989
2990 ;; When source and destination does not overlap, clear destination
2991 ;; first and then do the movb
2992 (define_split
2993   [(set (match_operand:HI 0 "register_operand" "")
2994         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2995    (clobber (reg:CC FLAGS_REG))]
2996   "reload_completed
2997    && ANY_QI_REG_P (operands[0])
2998    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2999    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3000   [(set (match_dup 0) (const_int 0))
3001    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3002   "operands[2] = gen_lowpart (QImode, operands[0]);")
3003
3004 ;; Rest is handled by single and.
3005 (define_split
3006   [(set (match_operand:HI 0 "register_operand" "")
3007         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3008    (clobber (reg:CC FLAGS_REG))]
3009   "reload_completed
3010    && true_regnum (operands[0]) == true_regnum (operands[1])"
3011   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3012               (clobber (reg:CC FLAGS_REG))])]
3013   "")
3014
3015 (define_expand "zero_extendqisi2"
3016   [(parallel
3017     [(set (match_operand:SI 0 "register_operand" "")
3018        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3019      (clobber (reg:CC FLAGS_REG))])]
3020   ""
3021   "")
3022
3023 (define_insn "*zero_extendqisi2_and"
3024   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3025      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3026    (clobber (reg:CC FLAGS_REG))]
3027   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3028   "#"
3029   [(set_attr "type" "alu1")
3030    (set_attr "mode" "SI")])
3031
3032 (define_insn "*zero_extendqisi2_movzbw_and"
3033   [(set (match_operand:SI 0 "register_operand" "=r,r")
3034      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3035    (clobber (reg:CC FLAGS_REG))]
3036   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3037   "#"
3038   [(set_attr "type" "imovx,alu1")
3039    (set_attr "mode" "SI")])
3040
3041 (define_insn "*zero_extendqisi2_movzbw"
3042   [(set (match_operand:SI 0 "register_operand" "=r")
3043      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3044   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3045   "movz{bl|x}\t{%1, %0|%0, %1}"
3046   [(set_attr "type" "imovx")
3047    (set_attr "mode" "SI")])
3048
3049 ;; For the movzbl case strip only the clobber
3050 (define_split
3051   [(set (match_operand:SI 0 "register_operand" "")
3052         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3053    (clobber (reg:CC FLAGS_REG))]
3054   "reload_completed 
3055    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3056    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3057   [(set (match_dup 0)
3058         (zero_extend:SI (match_dup 1)))])
3059
3060 ;; When source and destination does not overlap, clear destination
3061 ;; first and then do the movb
3062 (define_split
3063   [(set (match_operand:SI 0 "register_operand" "")
3064         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3065    (clobber (reg:CC FLAGS_REG))]
3066   "reload_completed
3067    && ANY_QI_REG_P (operands[0])
3068    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3069    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3070    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3071   [(set (match_dup 0) (const_int 0))
3072    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3073   "operands[2] = gen_lowpart (QImode, operands[0]);")
3074
3075 ;; Rest is handled by single and.
3076 (define_split
3077   [(set (match_operand:SI 0 "register_operand" "")
3078         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3079    (clobber (reg:CC FLAGS_REG))]
3080   "reload_completed
3081    && true_regnum (operands[0]) == true_regnum (operands[1])"
3082   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3083               (clobber (reg:CC FLAGS_REG))])]
3084   "")
3085
3086 ;; %%% Kill me once multi-word ops are sane.
3087 (define_expand "zero_extendsidi2"
3088   [(set (match_operand:DI 0 "register_operand" "=r")
3089      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3090   ""
3091   "if (!TARGET_64BIT)
3092      {
3093        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3094        DONE;
3095      }
3096   ")
3097
3098 (define_insn "zero_extendsidi2_32"
3099   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3100         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3101    (clobber (reg:CC FLAGS_REG))]
3102   "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3103   "@
3104    #
3105    #
3106    #
3107    movd\t{%1, %0|%0, %1}
3108    movd\t{%1, %0|%0, %1}"
3109   [(set_attr "mode" "SI,SI,SI,DI,TI")
3110    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3111
3112 (define_insn "*zero_extendsidi2_32_1"
3113   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3114         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3115    (clobber (reg:CC FLAGS_REG))]
3116   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3117   "@
3118    #
3119    #
3120    #
3121    movd\t{%1, %0|%0, %1}
3122    movd\t{%1, %0|%0, %1}"
3123   [(set_attr "mode" "SI,SI,SI,DI,TI")
3124    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3125
3126 (define_insn "zero_extendsidi2_rex64"
3127   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3128      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3129   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3130   "@
3131    mov\t{%k1, %k0|%k0, %k1}
3132    #
3133    movd\t{%1, %0|%0, %1}
3134    movd\t{%1, %0|%0, %1}"
3135   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3136    (set_attr "mode" "SI,DI,DI,TI")])
3137
3138 (define_insn "*zero_extendsidi2_rex64_1"
3139   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3140      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3141   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3142   "@
3143    mov\t{%k1, %k0|%k0, %k1}
3144    #
3145    movd\t{%1, %0|%0, %1}
3146    movd\t{%1, %0|%0, %1}"
3147   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3148    (set_attr "mode" "SI,DI,SI,SI")])
3149
3150 (define_split
3151   [(set (match_operand:DI 0 "memory_operand" "")
3152      (zero_extend:DI (match_dup 0)))]
3153   "TARGET_64BIT"
3154   [(set (match_dup 4) (const_int 0))]
3155   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3156
3157 (define_split 
3158   [(set (match_operand:DI 0 "register_operand" "")
3159         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3160    (clobber (reg:CC FLAGS_REG))]
3161   "!TARGET_64BIT && reload_completed
3162    && true_regnum (operands[0]) == true_regnum (operands[1])"
3163   [(set (match_dup 4) (const_int 0))]
3164   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3165
3166 (define_split 
3167   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3168         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3169    (clobber (reg:CC FLAGS_REG))]
3170   "!TARGET_64BIT && reload_completed
3171    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3172   [(set (match_dup 3) (match_dup 1))
3173    (set (match_dup 4) (const_int 0))]
3174   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3175
3176 (define_insn "zero_extendhidi2"
3177   [(set (match_operand:DI 0 "register_operand" "=r,r")
3178      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3179   "TARGET_64BIT"
3180   "@
3181    movz{wl|x}\t{%1, %k0|%k0, %1}
3182    movz{wq|x}\t{%1, %0|%0, %1}"
3183   [(set_attr "type" "imovx")
3184    (set_attr "mode" "SI,DI")])
3185
3186 (define_insn "zero_extendqidi2"
3187   [(set (match_operand:DI 0 "register_operand" "=r,r")
3188      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3189   "TARGET_64BIT"
3190   "@
3191    movz{bl|x}\t{%1, %k0|%k0, %1}
3192    movz{bq|x}\t{%1, %0|%0, %1}"
3193   [(set_attr "type" "imovx")
3194    (set_attr "mode" "SI,DI")])
3195 \f
3196 ;; Sign extension instructions
3197
3198 (define_expand "extendsidi2"
3199   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3200                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3201               (clobber (reg:CC FLAGS_REG))
3202               (clobber (match_scratch:SI 2 ""))])]
3203   ""
3204 {
3205   if (TARGET_64BIT)
3206     {
3207       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3208       DONE;
3209     }
3210 })
3211
3212 (define_insn "*extendsidi2_1"
3213   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3214         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3215    (clobber (reg:CC FLAGS_REG))
3216    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3217   "!TARGET_64BIT"
3218   "#")
3219
3220 (define_insn "extendsidi2_rex64"
3221   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3222         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3223   "TARGET_64BIT"
3224   "@
3225    {cltq|cdqe}
3226    movs{lq|x}\t{%1,%0|%0, %1}"
3227   [(set_attr "type" "imovx")
3228    (set_attr "mode" "DI")
3229    (set_attr "prefix_0f" "0")
3230    (set_attr "modrm" "0,1")])
3231
3232 (define_insn "extendhidi2"
3233   [(set (match_operand:DI 0 "register_operand" "=r")
3234         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3235   "TARGET_64BIT"
3236   "movs{wq|x}\t{%1,%0|%0, %1}"
3237   [(set_attr "type" "imovx")
3238    (set_attr "mode" "DI")])
3239
3240 (define_insn "extendqidi2"
3241   [(set (match_operand:DI 0 "register_operand" "=r")
3242         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3243   "TARGET_64BIT"
3244   "movs{bq|x}\t{%1,%0|%0, %1}"
3245    [(set_attr "type" "imovx")
3246     (set_attr "mode" "DI")])
3247
3248 ;; Extend to memory case when source register does die.
3249 (define_split 
3250   [(set (match_operand:DI 0 "memory_operand" "")
3251         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3252    (clobber (reg:CC FLAGS_REG))
3253    (clobber (match_operand:SI 2 "register_operand" ""))]
3254   "(reload_completed
3255     && dead_or_set_p (insn, operands[1])
3256     && !reg_mentioned_p (operands[1], operands[0]))"
3257   [(set (match_dup 3) (match_dup 1))
3258    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3259               (clobber (reg:CC FLAGS_REG))])
3260    (set (match_dup 4) (match_dup 1))]
3261   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3262
3263 ;; Extend to memory case when source register does not die.
3264 (define_split 
3265   [(set (match_operand:DI 0 "memory_operand" "")
3266         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3267    (clobber (reg:CC FLAGS_REG))
3268    (clobber (match_operand:SI 2 "register_operand" ""))]
3269   "reload_completed"
3270   [(const_int 0)]
3271 {
3272   split_di (&operands[0], 1, &operands[3], &operands[4]);
3273
3274   emit_move_insn (operands[3], operands[1]);
3275
3276   /* Generate a cltd if possible and doing so it profitable.  */
3277   if (true_regnum (operands[1]) == 0
3278       && true_regnum (operands[2]) == 1
3279       && (optimize_size || TARGET_USE_CLTD))
3280     {
3281       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3282     }
3283   else
3284     {
3285       emit_move_insn (operands[2], operands[1]);
3286       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3287     }
3288   emit_move_insn (operands[4], operands[2]);
3289   DONE;
3290 })
3291
3292 ;; Extend to register case.  Optimize case where source and destination
3293 ;; registers match and cases where we can use cltd.
3294 (define_split 
3295   [(set (match_operand:DI 0 "register_operand" "")
3296         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3297    (clobber (reg:CC FLAGS_REG))
3298    (clobber (match_scratch:SI 2 ""))]
3299   "reload_completed"
3300   [(const_int 0)]
3301 {
3302   split_di (&operands[0], 1, &operands[3], &operands[4]);
3303
3304   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3305     emit_move_insn (operands[3], operands[1]);
3306
3307   /* Generate a cltd if possible and doing so it profitable.  */
3308   if (true_regnum (operands[3]) == 0
3309       && (optimize_size || TARGET_USE_CLTD))
3310     {
3311       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3312       DONE;
3313     }
3314
3315   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3316     emit_move_insn (operands[4], operands[1]);
3317
3318   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3319   DONE;
3320 })
3321
3322 (define_insn "extendhisi2"
3323   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3324         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3325   ""
3326 {
3327   switch (get_attr_prefix_0f (insn))
3328     {
3329     case 0:
3330       return "{cwtl|cwde}";
3331     default:
3332       return "movs{wl|x}\t{%1,%0|%0, %1}";
3333     }
3334 }
3335   [(set_attr "type" "imovx")
3336    (set_attr "mode" "SI")
3337    (set (attr "prefix_0f")
3338      ;; movsx is short decodable while cwtl is vector decoded.
3339      (if_then_else (and (eq_attr "cpu" "!k6")
3340                         (eq_attr "alternative" "0"))
3341         (const_string "0")
3342         (const_string "1")))
3343    (set (attr "modrm")
3344      (if_then_else (eq_attr "prefix_0f" "0")
3345         (const_string "0")
3346         (const_string "1")))])
3347
3348 (define_insn "*extendhisi2_zext"
3349   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3350         (zero_extend:DI
3351           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3352   "TARGET_64BIT"
3353 {
3354   switch (get_attr_prefix_0f (insn))
3355     {
3356     case 0:
3357       return "{cwtl|cwde}";
3358     default:
3359       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3360     }
3361 }
3362   [(set_attr "type" "imovx")
3363    (set_attr "mode" "SI")
3364    (set (attr "prefix_0f")
3365      ;; movsx is short decodable while cwtl is vector decoded.
3366      (if_then_else (and (eq_attr "cpu" "!k6")
3367                         (eq_attr "alternative" "0"))
3368         (const_string "0")
3369         (const_string "1")))
3370    (set (attr "modrm")
3371      (if_then_else (eq_attr "prefix_0f" "0")
3372         (const_string "0")
3373         (const_string "1")))])
3374
3375 (define_insn "extendqihi2"
3376   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3377         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3378   ""
3379 {
3380   switch (get_attr_prefix_0f (insn))
3381     {
3382     case 0:
3383       return "{cbtw|cbw}";
3384     default:
3385       return "movs{bw|x}\t{%1,%0|%0, %1}";
3386     }
3387 }
3388   [(set_attr "type" "imovx")
3389    (set_attr "mode" "HI")
3390    (set (attr "prefix_0f")
3391      ;; movsx is short decodable while cwtl is vector decoded.
3392      (if_then_else (and (eq_attr "cpu" "!k6")
3393                         (eq_attr "alternative" "0"))
3394         (const_string "0")
3395         (const_string "1")))
3396    (set (attr "modrm")
3397      (if_then_else (eq_attr "prefix_0f" "0")
3398         (const_string "0")
3399         (const_string "1")))])
3400
3401 (define_insn "extendqisi2"
3402   [(set (match_operand:SI 0 "register_operand" "=r")
3403         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3404   ""
3405   "movs{bl|x}\t{%1,%0|%0, %1}"
3406    [(set_attr "type" "imovx")
3407     (set_attr "mode" "SI")])
3408
3409 (define_insn "*extendqisi2_zext"
3410   [(set (match_operand:DI 0 "register_operand" "=r")
3411         (zero_extend:DI
3412           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3413   "TARGET_64BIT"
3414   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3415    [(set_attr "type" "imovx")
3416     (set_attr "mode" "SI")])
3417 \f
3418 ;; Conversions between float and double.
3419
3420 ;; These are all no-ops in the model used for the 80387.  So just
3421 ;; emit moves.
3422
3423 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3424 (define_insn "*dummy_extendsfdf2"
3425   [(set (match_operand:DF 0 "push_operand" "=<")
3426         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3427   "0"
3428   "#")
3429
3430 (define_split
3431   [(set (match_operand:DF 0 "push_operand" "")
3432         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3433   "!TARGET_64BIT"
3434   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3435    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3436
3437 (define_split
3438   [(set (match_operand:DF 0 "push_operand" "")
3439         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3440   "TARGET_64BIT"
3441   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3442    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3443
3444 (define_insn "*dummy_extendsfxf2"
3445   [(set (match_operand:XF 0 "push_operand" "=<")
3446         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3447   "0"
3448   "#")
3449
3450 (define_split
3451   [(set (match_operand:XF 0 "push_operand" "")
3452         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3453   ""
3454   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3455    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3456   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3457
3458 (define_split
3459   [(set (match_operand:XF 0 "push_operand" "")
3460         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3461   "TARGET_64BIT"
3462   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3463    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3464   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3465
3466 (define_split
3467   [(set (match_operand:XF 0 "push_operand" "")
3468         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3469   ""
3470   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3471    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3472   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3473
3474 (define_split
3475   [(set (match_operand:XF 0 "push_operand" "")
3476         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3477   "TARGET_64BIT"
3478   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3479    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3480   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3481
3482 (define_expand "extendsfdf2"
3483   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3484         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3485   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3486 {
3487   /* ??? Needed for compress_float_constant since all fp constants
3488      are LEGITIMATE_CONSTANT_P.  */
3489   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3490     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3491   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3492     operands[1] = force_reg (SFmode, operands[1]);
3493 })
3494
3495 (define_insn "*extendsfdf2_mixed"
3496   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3497         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3498   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3499    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3500 {
3501   switch (which_alternative)
3502     {
3503     case 0:
3504       return output_387_reg_move (insn, operands);
3505
3506     case 1:
3507       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3508         return "fstp%z0\t%y0";
3509       else
3510         return "fst%z0\t%y0";
3511
3512     case 2:
3513       return "cvtss2sd\t{%1, %0|%0, %1}";
3514
3515     default:
3516       abort ();
3517     }
3518 }
3519   [(set_attr "type" "fmov,fmov,ssecvt")
3520    (set_attr "mode" "SF,XF,DF")])
3521
3522 (define_insn "*extendsfdf2_sse"
3523   [(set (match_operand:DF 0 "register_operand" "=Y")
3524         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3525   "TARGET_SSE2 && TARGET_SSE_MATH
3526    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3527   "cvtss2sd\t{%1, %0|%0, %1}"
3528   [(set_attr "type" "ssecvt")
3529    (set_attr "mode" "DF")])
3530
3531 (define_insn "*extendsfdf2_i387"
3532   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3533         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3534   "TARGET_80387
3535    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3536 {
3537   switch (which_alternative)
3538     {
3539     case 0:
3540       return output_387_reg_move (insn, operands);
3541
3542     case 1:
3543       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3544         return "fstp%z0\t%y0";
3545       else
3546         return "fst%z0\t%y0";
3547
3548     default:
3549       abort ();
3550     }
3551 }
3552   [(set_attr "type" "fmov")
3553    (set_attr "mode" "SF,XF")])
3554
3555 (define_expand "extendsfxf2"
3556   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3557         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3558   "TARGET_80387"
3559 {
3560   /* ??? Needed for compress_float_constant since all fp constants
3561      are LEGITIMATE_CONSTANT_P.  */
3562   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3563     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3564   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3565     operands[1] = force_reg (SFmode, operands[1]);
3566 })
3567
3568 (define_insn "*extendsfxf2_i387"
3569   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3570         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3571   "TARGET_80387
3572    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3573 {
3574   switch (which_alternative)
3575     {
3576     case 0:
3577       return output_387_reg_move (insn, operands);
3578
3579     case 1:
3580       /* There is no non-popping store to memory for XFmode.  So if
3581          we need one, follow the store with a load.  */
3582       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3583         return "fstp%z0\t%y0";
3584       else
3585         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3586
3587     default:
3588       abort ();
3589     }
3590 }
3591   [(set_attr "type" "fmov")
3592    (set_attr "mode" "SF,XF")])
3593
3594 (define_expand "extenddfxf2"
3595   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3596         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3597   "TARGET_80387"
3598 {
3599   /* ??? Needed for compress_float_constant since all fp constants
3600      are LEGITIMATE_CONSTANT_P.  */
3601   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3602     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3603   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3604     operands[1] = force_reg (DFmode, operands[1]);
3605 })
3606
3607 (define_insn "*extenddfxf2_i387"
3608   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3609         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3610   "TARGET_80387
3611    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3612 {
3613   switch (which_alternative)
3614     {
3615     case 0:
3616       return output_387_reg_move (insn, operands);
3617
3618     case 1:
3619       /* There is no non-popping store to memory for XFmode.  So if
3620          we need one, follow the store with a load.  */
3621       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3622         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3623       else
3624         return "fstp%z0\t%y0";
3625
3626     default:
3627       abort ();
3628     }
3629 }
3630   [(set_attr "type" "fmov")
3631    (set_attr "mode" "DF,XF")])
3632
3633 ;; %%% This seems bad bad news.
3634 ;; This cannot output into an f-reg because there is no way to be sure
3635 ;; of truncating in that case.  Otherwise this is just like a simple move
3636 ;; insn.  So we pretend we can output to a reg in order to get better
3637 ;; register preferencing, but we really use a stack slot.
3638
3639 (define_expand "truncdfsf2"
3640   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3641                    (float_truncate:SF
3642                     (match_operand:DF 1 "register_operand" "")))
3643               (clobber (match_dup 2))])]
3644   "TARGET_80387 || TARGET_SSE2"
3645   "
3646    if (!TARGET_80387)
3647      {
3648         emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3649         DONE;
3650      }
3651    else if (flag_unsafe_math_optimizations)
3652      {
3653         rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3654         emit_insn (gen_truncdfsf2_noop (reg, operands[1]));
3655         if (reg != operands[0])
3656           emit_move_insn (operands[0], reg);
3657         DONE;
3658      }
3659    else
3660      operands[2] = assign_386_stack_local (SFmode, 0);
3661 ")
3662
3663 (define_insn "truncdfsf2_noop"
3664   [(set (match_operand:SF 0 "register_operand" "=f")
3665         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3666   "TARGET_80387 && flag_unsafe_math_optimizations"
3667 {
3668   return output_387_reg_move (insn, operands);
3669 }
3670   [(set_attr "type" "fmov")
3671    (set_attr "mode" "SF")])
3672
3673 (define_insn "*truncdfsf2_1"
3674   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3675         (float_truncate:SF
3676          (match_operand:DF 1 "register_operand" "f,f,f,f")))
3677    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3678   "TARGET_80387 && !TARGET_SSE2"
3679 {
3680   switch (which_alternative)
3681     {
3682     case 0:
3683       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3684         return "fstp%z0\t%y0";
3685       else
3686         return "fst%z0\t%y0";
3687     default:
3688       abort ();
3689     }
3690 }
3691   [(set_attr "type" "fmov,multi,multi,multi")
3692    (set_attr "mode" "SF,SF,SF,SF")])
3693
3694 (define_insn "*truncdfsf2_1_sse"
3695   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3696         (float_truncate:SF
3697          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3698    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3699   "TARGET_80387 && TARGET_SSE2"
3700 {
3701   switch (which_alternative)
3702     {
3703     case 0:
3704       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3705         return "fstp%z0\t%y0";
3706       else
3707         return "fst%z0\t%y0";
3708     case 4:
3709       return "#";
3710     default:
3711       abort ();
3712     }
3713 }
3714   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3715    (set_attr "mode" "SF,SF,SF,SF,DF")])
3716
3717 (define_insn "*truncdfsf2_2"
3718   [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3719         (float_truncate:SF
3720          (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3721   "TARGET_80387 && TARGET_SSE2
3722    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3723 {
3724   switch (which_alternative)
3725     {
3726     case 0:
3727     case 1:
3728       return "cvtsd2ss\t{%1, %0|%0, %1}";
3729     case 2:
3730       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3731         return "fstp%z0\t%y0";
3732       else
3733         return "fst%z0\t%y0";
3734     default:
3735       abort ();
3736     }
3737 }
3738   [(set_attr "type" "ssecvt,ssecvt,fmov")
3739    (set_attr "athlon_decode" "vector,double,*")
3740    (set_attr "mode" "SF,SF,SF")])
3741
3742 (define_insn "*truncdfsf2_3"
3743   [(set (match_operand:SF 0 "memory_operand" "=m")
3744         (float_truncate:SF
3745          (match_operand:DF 1 "register_operand" "f")))]
3746   "TARGET_80387"
3747 {
3748   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3749     return "fstp%z0\t%y0";
3750   else
3751     return "fst%z0\t%y0";
3752 }
3753   [(set_attr "type" "fmov")
3754    (set_attr "mode" "SF")])
3755
3756 (define_insn "truncdfsf2_sse_only"
3757   [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3758         (float_truncate:SF
3759          (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3760   "!TARGET_80387 && TARGET_SSE2"
3761   "cvtsd2ss\t{%1, %0|%0, %1}"
3762   [(set_attr "type" "ssecvt")
3763    (set_attr "athlon_decode" "vector,double")
3764    (set_attr "mode" "SF")])
3765
3766 (define_split
3767   [(set (match_operand:SF 0 "memory_operand" "")
3768         (float_truncate:SF
3769          (match_operand:DF 1 "register_operand" "")))
3770    (clobber (match_operand:SF 2 "memory_operand" ""))]
3771   "TARGET_80387"
3772   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3773   "")
3774
3775 (define_split
3776   [(set (match_operand:SF 0 "register_operand" "")
3777         (float_truncate:SF
3778          (match_operand:DF 1 "nonimmediate_operand" "")))
3779    (clobber (match_operand 2 "" ""))]
3780   "TARGET_80387 && reload_completed
3781    && SSE_REG_P (operands[0])
3782    && !STACK_REG_P (operands[1])"
3783   [(const_int 0)]
3784 {
3785   emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3786   DONE;
3787 })
3788
3789 (define_split
3790   [(set (match_operand:SF 0 "register_operand" "")
3791         (float_truncate:SF
3792          (match_operand:DF 1 "fp_register_operand" "")))
3793    (clobber (match_operand:SF 2 "memory_operand" ""))]
3794   "TARGET_80387 && reload_completed"
3795   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3796    (set (match_dup 0) (match_dup 2))]
3797   "")
3798
3799 (define_expand "truncxfsf2"
3800   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3801                    (float_truncate:SF
3802                     (match_operand:XF 1 "register_operand" "")))
3803               (clobber (match_dup 2))])]
3804   "TARGET_80387"
3805   "
3806   if (flag_unsafe_math_optimizations)
3807     {
3808       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3809       emit_insn (gen_truncxfsf2_noop (reg, operands[1]));
3810       if (reg != operands[0])
3811         emit_move_insn (operands[0], reg);
3812       DONE;
3813     }
3814   else
3815     operands[2] = assign_386_stack_local (SFmode, 0);
3816   ")
3817
3818 (define_insn "truncxfsf2_noop"
3819   [(set (match_operand:SF 0 "register_operand" "=f")
3820         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3821   "TARGET_80387 && flag_unsafe_math_optimizations"
3822 {
3823   return output_387_reg_move (insn, operands);
3824 }
3825   [(set_attr "type" "fmov")
3826    (set_attr "mode" "SF")])
3827
3828 (define_insn "*truncxfsf2_1"
3829   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3830         (float_truncate:SF
3831          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3832    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3833   "TARGET_80387"
3834 {
3835   switch (which_alternative)
3836     {
3837     case 0:
3838       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3839         return "fstp%z0\t%y0";
3840       else
3841         return "fst%z0\t%y0";
3842     default:
3843       abort();
3844     }
3845 }
3846   [(set_attr "type" "fmov,multi,multi,multi")
3847    (set_attr "mode" "SF")])
3848
3849 (define_insn "*truncxfsf2_2"
3850   [(set (match_operand:SF 0 "memory_operand" "=m")
3851         (float_truncate:SF
3852          (match_operand:XF 1 "register_operand" "f")))]
3853   "TARGET_80387"
3854 {
3855   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3856     return "fstp%z0\t%y0";
3857   else
3858     return "fst%z0\t%y0";
3859 }
3860   [(set_attr "type" "fmov")
3861    (set_attr "mode" "SF")])
3862
3863 (define_split
3864   [(set (match_operand:SF 0 "memory_operand" "")
3865         (float_truncate:SF
3866          (match_operand:XF 1 "register_operand" "")))
3867    (clobber (match_operand:SF 2 "memory_operand" ""))]
3868   "TARGET_80387"
3869   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3870   "")
3871
3872 (define_split
3873   [(set (match_operand:SF 0 "register_operand" "")
3874         (float_truncate:SF
3875          (match_operand:XF 1 "register_operand" "")))
3876    (clobber (match_operand:SF 2 "memory_operand" ""))]
3877   "TARGET_80387 && reload_completed"
3878   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3879    (set (match_dup 0) (match_dup 2))]
3880   "")
3881
3882 (define_expand "truncxfdf2"
3883   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3884                    (float_truncate:DF
3885                     (match_operand:XF 1 "register_operand" "")))
3886               (clobber (match_dup 2))])]
3887   "TARGET_80387"
3888   "
3889   if (flag_unsafe_math_optimizations)
3890     {
3891       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3892       emit_insn (gen_truncxfdf2_noop (reg, operands[1]));
3893       if (reg != operands[0])
3894         emit_move_insn (operands[0], reg);
3895       DONE;
3896     }
3897   else
3898     operands[2] = assign_386_stack_local (DFmode, 0);
3899   ")
3900
3901 (define_insn "truncxfdf2_noop"
3902   [(set (match_operand:DF 0 "register_operand" "=f")
3903         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3904   "TARGET_80387 && flag_unsafe_math_optimizations"
3905 {
3906   return output_387_reg_move (insn, operands);
3907 }
3908   [(set_attr "type" "fmov")
3909    (set_attr "mode" "DF")])
3910
3911 (define_insn "*truncxfdf2_1"
3912   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3913         (float_truncate:DF
3914          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3915    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3916   "TARGET_80387"
3917 {
3918   switch (which_alternative)
3919     {
3920     case 0:
3921       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3922         return "fstp%z0\t%y0";
3923       else
3924         return "fst%z0\t%y0";
3925     default:
3926       abort();
3927     }
3928   abort ();
3929 }
3930   [(set_attr "type" "fmov,multi,multi,multi")
3931    (set_attr "mode" "DF")])
3932
3933 (define_insn "*truncxfdf2_2"
3934   [(set (match_operand:DF 0 "memory_operand" "=m")
3935         (float_truncate:DF
3936           (match_operand:XF 1 "register_operand" "f")))]
3937   "TARGET_80387"
3938 {
3939   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3940     return "fstp%z0\t%y0";
3941   else
3942     return "fst%z0\t%y0";
3943 }
3944   [(set_attr "type" "fmov")
3945    (set_attr "mode" "DF")])
3946
3947 (define_split
3948   [(set (match_operand:DF 0 "memory_operand" "")
3949         (float_truncate:DF
3950          (match_operand:XF 1 "register_operand" "")))
3951    (clobber (match_operand:DF 2 "memory_operand" ""))]
3952   "TARGET_80387"
3953   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3954   "")
3955
3956 (define_split
3957   [(set (match_operand:DF 0 "register_operand" "")
3958         (float_truncate:DF
3959          (match_operand:XF 1 "register_operand" "")))
3960    (clobber (match_operand:DF 2 "memory_operand" ""))]
3961   "TARGET_80387 && reload_completed"
3962   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3963    (set (match_dup 0) (match_dup 2))]
3964   "")
3965
3966 \f
3967 ;; %%% Break up all these bad boys.
3968
3969 ;; Signed conversion to DImode.
3970
3971 (define_expand "fix_truncxfdi2"
3972   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3973                    (fix:DI (match_operand:XF 1 "register_operand" "")))
3974               (clobber (reg:CC FLAGS_REG))])]
3975   "TARGET_80387"
3976   "")
3977
3978 (define_expand "fix_truncdfdi2"
3979   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3980                    (fix:DI (match_operand:DF 1 "register_operand" "")))
3981               (clobber (reg:CC FLAGS_REG))])]
3982   "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
3983 {
3984   if (TARGET_64BIT && TARGET_SSE2)
3985    {
3986      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
3987      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
3988      if (out != operands[0])
3989         emit_move_insn (operands[0], out);
3990      DONE;
3991    }
3992 })
3993
3994 (define_expand "fix_truncsfdi2"
3995   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3996                    (fix:DI (match_operand:SF 1 "register_operand" "")))
3997               (clobber (reg:CC FLAGS_REG))])] 
3998   "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
3999 {
4000   if (TARGET_SSE && TARGET_64BIT)
4001    {
4002      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4003      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4004      if (out != operands[0])
4005         emit_move_insn (operands[0], out);
4006      DONE;
4007    }
4008 })
4009
4010 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4011 ;; of the machinery.
4012 (define_insn_and_split "*fix_truncdi_1"
4013   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4014         (fix:DI (match_operand 1 "register_operand" "f,f")))
4015    (clobber (reg:CC FLAGS_REG))]
4016   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4017    && !reload_completed && !reload_in_progress
4018    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4019   "#"
4020   "&& 1"
4021   [(const_int 0)]
4022 {
4023   ix86_optimize_mode_switching = 1;
4024   operands[2] = assign_386_stack_local (HImode, 1);
4025   operands[3] = assign_386_stack_local (HImode, 2);
4026   if (memory_operand (operands[0], VOIDmode))
4027     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4028                                        operands[2], operands[3]));
4029   else
4030     {
4031       operands[4] = assign_386_stack_local (DImode, 0);
4032       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4033                                            operands[2], operands[3],
4034                                            operands[4]));
4035     }
4036   DONE;
4037 }
4038   [(set_attr "type" "fistp")
4039    (set_attr "i387_cw" "trunc")
4040    (set_attr "mode" "DI")])
4041
4042 (define_insn "fix_truncdi_nomemory"
4043   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4044         (fix:DI (match_operand 1 "register_operand" "f,f")))
4045    (use (match_operand:HI 2 "memory_operand" "m,m"))
4046    (use (match_operand:HI 3 "memory_operand" "m,m"))
4047    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4048    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4049   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4050    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4051   "#"
4052   [(set_attr "type" "fistp")
4053    (set_attr "i387_cw" "trunc")
4054    (set_attr "mode" "DI")])
4055
4056 (define_insn "fix_truncdi_memory"
4057   [(set (match_operand:DI 0 "memory_operand" "=m")
4058         (fix:DI (match_operand 1 "register_operand" "f")))
4059    (use (match_operand:HI 2 "memory_operand" "m"))
4060    (use (match_operand:HI 3 "memory_operand" "m"))
4061    (clobber (match_scratch:DF 4 "=&1f"))]
4062   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4063    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4064   "* return output_fix_trunc (insn, operands);"
4065   [(set_attr "type" "fistp")
4066    (set_attr "i387_cw" "trunc")
4067    (set_attr "mode" "DI")])
4068
4069 (define_split 
4070   [(set (match_operand:DI 0 "register_operand" "")
4071         (fix:DI (match_operand 1 "register_operand" "")))
4072    (use (match_operand:HI 2 "memory_operand" ""))
4073    (use (match_operand:HI 3 "memory_operand" ""))
4074    (clobber (match_operand:DI 4 "memory_operand" ""))
4075    (clobber (match_scratch 5 ""))]
4076   "reload_completed"
4077   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4078               (use (match_dup 2))
4079               (use (match_dup 3))
4080               (clobber (match_dup 5))])
4081    (set (match_dup 0) (match_dup 4))]
4082   "")
4083
4084 (define_split 
4085   [(set (match_operand:DI 0 "memory_operand" "")
4086         (fix:DI (match_operand 1 "register_operand" "")))
4087    (use (match_operand:HI 2 "memory_operand" ""))
4088    (use (match_operand:HI 3 "memory_operand" ""))
4089    (clobber (match_operand:DI 4 "memory_operand" ""))
4090    (clobber (match_scratch 5 ""))]
4091   "reload_completed"
4092   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4093               (use (match_dup 2))
4094               (use (match_dup 3))
4095               (clobber (match_dup 5))])]
4096   "")
4097
4098 ;; When SSE available, it is always faster to use it!
4099 (define_insn "fix_truncsfdi_sse"
4100   [(set (match_operand:DI 0 "register_operand" "=r,r")
4101         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4102   "TARGET_64BIT && TARGET_SSE"
4103   "cvttss2si{q}\t{%1, %0|%0, %1}"
4104   [(set_attr "type" "sseicvt")
4105    (set_attr "mode" "SF")
4106    (set_attr "athlon_decode" "double,vector")])
4107
4108 ;; Avoid vector decoded form of the instruction.
4109 (define_peephole2
4110   [(match_scratch:SF 2 "x")
4111    (set (match_operand:DI 0 "register_operand" "")
4112         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4113   "TARGET_K8 && !optimize_size"
4114   [(set (match_dup 2) (match_dup 1))
4115    (set (match_dup 0) (fix:DI (match_dup 2)))]
4116   "")
4117
4118 (define_insn "fix_truncdfdi_sse"
4119   [(set (match_operand:DI 0 "register_operand" "=r,r")
4120         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4121   "TARGET_64BIT && TARGET_SSE2"
4122   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4123   [(set_attr "type" "sseicvt,sseicvt")
4124    (set_attr "mode" "DF")
4125    (set_attr "athlon_decode" "double,vector")])
4126
4127 ;; Avoid vector decoded form of the instruction.
4128 (define_peephole2
4129   [(match_scratch:DF 2 "Y")
4130    (set (match_operand:DI 0 "register_operand" "")
4131         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4132   "TARGET_K8 && !optimize_size"
4133   [(set (match_dup 2) (match_dup 1))
4134    (set (match_dup 0) (fix:DI (match_dup 2)))]
4135   "")
4136
4137 ;; Signed conversion to SImode.
4138
4139 (define_expand "fix_truncxfsi2"
4140   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4141                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4142               (clobber (reg:CC FLAGS_REG))])]
4143   "TARGET_80387"
4144   "")
4145
4146 (define_expand "fix_truncdfsi2"
4147   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4148                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4149               (clobber (reg:CC FLAGS_REG))])]
4150   "TARGET_80387 || TARGET_SSE2"
4151 {
4152   if (TARGET_SSE2)
4153    {
4154      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4155      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4156      if (out != operands[0])
4157         emit_move_insn (operands[0], out);
4158      DONE;
4159    }
4160 })
4161
4162 (define_expand "fix_truncsfsi2"
4163   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4164                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4165               (clobber (reg:CC FLAGS_REG))])] 
4166   "TARGET_80387 || TARGET_SSE"
4167 {
4168   if (TARGET_SSE)
4169    {
4170      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4171      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4172      if (out != operands[0])
4173         emit_move_insn (operands[0], out);
4174      DONE;
4175    }
4176 })
4177
4178 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4179 ;; of the machinery.
4180 (define_insn_and_split "*fix_truncsi_1"
4181   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4182         (fix:SI (match_operand 1 "register_operand" "f,f")))
4183    (clobber (reg:CC FLAGS_REG))]
4184   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4185    && !reload_completed && !reload_in_progress
4186    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4187   "#"
4188   "&& 1"
4189   [(const_int 0)]
4190 {
4191   ix86_optimize_mode_switching = 1;
4192   operands[2] = assign_386_stack_local (HImode, 1);
4193   operands[3] = assign_386_stack_local (HImode, 2);
4194   if (memory_operand (operands[0], VOIDmode))
4195     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4196                                        operands[2], operands[3]));
4197   else
4198     {
4199       operands[4] = assign_386_stack_local (SImode, 0);
4200       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4201                                            operands[2], operands[3],
4202                                            operands[4]));
4203     }
4204   DONE;
4205 }
4206   [(set_attr "type" "fistp")
4207    (set_attr "i387_cw" "trunc")
4208    (set_attr "mode" "SI")])
4209
4210 (define_insn "fix_truncsi_nomemory"
4211   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4212         (fix:SI (match_operand 1 "register_operand" "f,f")))
4213    (use (match_operand:HI 2 "memory_operand" "m,m"))
4214    (use (match_operand:HI 3 "memory_operand" "m,m"))
4215    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4216   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4217    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4218   "#"
4219   [(set_attr "type" "fistp")
4220    (set_attr "i387_cw" "trunc")
4221    (set_attr "mode" "SI")])
4222
4223 (define_insn "fix_truncsi_memory"
4224   [(set (match_operand:SI 0 "memory_operand" "=m")
4225         (fix:SI (match_operand 1 "register_operand" "f")))
4226    (use (match_operand:HI 2 "memory_operand" "m"))
4227    (use (match_operand:HI 3 "memory_operand" "m"))]
4228   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4229    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4230   "* return output_fix_trunc (insn, operands);"
4231   [(set_attr "type" "fistp")
4232    (set_attr "i387_cw" "trunc")
4233    (set_attr "mode" "SI")])
4234
4235 ;; When SSE available, it is always faster to use it!
4236 (define_insn "fix_truncsfsi_sse"
4237   [(set (match_operand:SI 0 "register_operand" "=r,r")
4238         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4239   "TARGET_SSE"
4240   "cvttss2si\t{%1, %0|%0, %1}"
4241   [(set_attr "type" "sseicvt")
4242    (set_attr "mode" "DF")
4243    (set_attr "athlon_decode" "double,vector")])
4244
4245 ;; Avoid vector decoded form of the instruction.
4246 (define_peephole2
4247   [(match_scratch:SF 2 "x")
4248    (set (match_operand:SI 0 "register_operand" "")
4249         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4250   "TARGET_K8 && !optimize_size"
4251   [(set (match_dup 2) (match_dup 1))
4252    (set (match_dup 0) (fix:SI (match_dup 2)))]
4253   "")
4254
4255 (define_insn "fix_truncdfsi_sse"
4256   [(set (match_operand:SI 0 "register_operand" "=r,r")
4257         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4258   "TARGET_SSE2"
4259   "cvttsd2si\t{%1, %0|%0, %1}"
4260   [(set_attr "type" "sseicvt")
4261    (set_attr "mode" "DF")
4262    (set_attr "athlon_decode" "double,vector")])
4263
4264 ;; Avoid vector decoded form of the instruction.
4265 (define_peephole2
4266   [(match_scratch:DF 2 "Y")
4267    (set (match_operand:SI 0 "register_operand" "")
4268         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4269   "TARGET_K8 && !optimize_size"
4270   [(set (match_dup 2) (match_dup 1))
4271    (set (match_dup 0) (fix:SI (match_dup 2)))]
4272   "")
4273
4274 (define_split 
4275   [(set (match_operand:SI 0 "register_operand" "")
4276         (fix:SI (match_operand 1 "register_operand" "")))
4277    (use (match_operand:HI 2 "memory_operand" ""))
4278    (use (match_operand:HI 3 "memory_operand" ""))
4279    (clobber (match_operand:SI 4 "memory_operand" ""))]
4280   "reload_completed"
4281   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4282               (use (match_dup 2))
4283               (use (match_dup 3))])
4284    (set (match_dup 0) (match_dup 4))]
4285   "")
4286
4287 (define_split 
4288   [(set (match_operand:SI 0 "memory_operand" "")
4289         (fix:SI (match_operand 1 "register_operand" "")))
4290    (use (match_operand:HI 2 "memory_operand" ""))
4291    (use (match_operand:HI 3 "memory_operand" ""))
4292    (clobber (match_operand:SI 4 "memory_operand" ""))]
4293   "reload_completed"
4294   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4295               (use (match_dup 2))
4296               (use (match_dup 3))])]
4297   "")
4298
4299 ;; Signed conversion to HImode.
4300
4301 (define_expand "fix_truncxfhi2"
4302   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4303                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4304               (clobber (reg:CC FLAGS_REG))])] 
4305   "TARGET_80387"
4306   "")
4307
4308 (define_expand "fix_truncdfhi2"
4309   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4310                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4311               (clobber (reg:CC FLAGS_REG))])]
4312   "TARGET_80387 && !TARGET_SSE2"
4313   "")
4314
4315 (define_expand "fix_truncsfhi2"
4316   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4317                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4318                (clobber (reg:CC FLAGS_REG))])]
4319   "TARGET_80387 && !TARGET_SSE"
4320   "")
4321
4322 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4323 ;; of the machinery.
4324 (define_insn_and_split "*fix_trunchi_1"
4325   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4326         (fix:HI (match_operand 1 "register_operand" "f,f")))
4327    (clobber (reg:CC FLAGS_REG))]
4328   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4329    && !reload_completed && !reload_in_progress
4330    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4331   "#"
4332   "&& 1"
4333   [(const_int 0)]
4334 {
4335   ix86_optimize_mode_switching = 1;
4336   operands[2] = assign_386_stack_local (HImode, 1);
4337   operands[3] = assign_386_stack_local (HImode, 2);
4338   if (memory_operand (operands[0], VOIDmode))
4339     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4340                                        operands[2], operands[3]));
4341   else
4342     {
4343       operands[4] = assign_386_stack_local (HImode, 0);
4344       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4345                                            operands[2], operands[3],
4346                                            operands[4]));
4347     }
4348   DONE;
4349 }
4350   [(set_attr "type" "fistp")
4351    (set_attr "i387_cw" "trunc")
4352    (set_attr "mode" "HI")])
4353
4354 (define_insn "fix_trunchi_nomemory"
4355   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4356         (fix:HI (match_operand 1 "register_operand" "f,f")))
4357    (use (match_operand:HI 2 "memory_operand" "m,m"))
4358    (use (match_operand:HI 3 "memory_operand" "m,m"))
4359    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4360   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4361    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4362   "#"
4363   [(set_attr "type" "fistp")
4364    (set_attr "i387_cw" "trunc")
4365    (set_attr "mode" "HI")])
4366
4367 (define_insn "fix_trunchi_memory"
4368   [(set (match_operand:HI 0 "memory_operand" "=m")
4369         (fix:HI (match_operand 1 "register_operand" "f")))
4370    (use (match_operand:HI 2 "memory_operand" "m"))
4371    (use (match_operand:HI 3 "memory_operand" "m"))]
4372   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4373    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4374   "* return output_fix_trunc (insn, operands);"
4375   [(set_attr "type" "fistp")
4376    (set_attr "i387_cw" "trunc")
4377    (set_attr "mode" "HI")])
4378
4379 (define_split 
4380   [(set (match_operand:HI 0 "memory_operand" "")
4381         (fix:HI (match_operand 1 "register_operand" "")))
4382    (use (match_operand:HI 2 "memory_operand" ""))
4383    (use (match_operand:HI 3 "memory_operand" ""))
4384    (clobber (match_operand:HI 4 "memory_operand" ""))]
4385   "reload_completed"
4386   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4387               (use (match_dup 2))
4388               (use (match_dup 3))])]
4389   "")
4390
4391 (define_split 
4392   [(set (match_operand:HI 0 "register_operand" "")
4393         (fix:HI (match_operand 1 "register_operand" "")))
4394    (use (match_operand:HI 2 "memory_operand" ""))
4395    (use (match_operand:HI 3 "memory_operand" ""))
4396    (clobber (match_operand:HI 4 "memory_operand" ""))]
4397   "reload_completed"
4398   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4399               (use (match_dup 2))
4400               (use (match_dup 3))
4401               (clobber (match_dup 4))])
4402    (set (match_dup 0) (match_dup 4))]
4403   "")
4404
4405 (define_insn "x86_fnstcw_1"
4406   [(set (match_operand:HI 0 "memory_operand" "=m")
4407         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4408   "TARGET_80387"
4409   "fnstcw\t%0"
4410   [(set_attr "length" "2")
4411    (set_attr "mode" "HI")
4412    (set_attr "unit" "i387")])
4413
4414 (define_insn "x86_fldcw_1"
4415   [(set (reg:HI FPSR_REG)
4416         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4417   "TARGET_80387"
4418   "fldcw\t%0"
4419   [(set_attr "length" "2")
4420    (set_attr "mode" "HI")
4421    (set_attr "unit" "i387")
4422    (set_attr "athlon_decode" "vector")])
4423 \f
4424 ;; Conversion between fixed point and floating point.
4425
4426 ;; Even though we only accept memory inputs, the backend _really_
4427 ;; wants to be able to do this between registers.
4428
4429 (define_expand "floathisf2"
4430   [(set (match_operand:SF 0 "register_operand" "")
4431         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4432   "TARGET_80387 || TARGET_SSE_MATH"
4433 {
4434   if (TARGET_SSE_MATH)
4435     {
4436       emit_insn (gen_floatsisf2 (operands[0],
4437                                  convert_to_mode (SImode, operands[1], 0)));
4438       DONE;
4439     }
4440 })
4441
4442 (define_insn "*floathisf2_i387"
4443   [(set (match_operand:SF 0 "register_operand" "=f,f")
4444         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4445   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4446   "@
4447    fild%z1\t%1
4448    #"
4449   [(set_attr "type" "fmov,multi")
4450    (set_attr "mode" "SF")
4451    (set_attr "fp_int_src" "true")])
4452
4453 (define_expand "floatsisf2"
4454   [(set (match_operand:SF 0 "register_operand" "")
4455         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4456   "TARGET_80387 || TARGET_SSE_MATH"
4457   "")
4458
4459 (define_insn "*floatsisf2_mixed"
4460   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4461         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4462   "TARGET_MIX_SSE_I387"
4463   "@
4464    fild%z1\t%1
4465    #
4466    cvtsi2ss\t{%1, %0|%0, %1}
4467    cvtsi2ss\t{%1, %0|%0, %1}"
4468   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4469    (set_attr "mode" "SF")
4470    (set_attr "athlon_decode" "*,*,vector,double")
4471    (set_attr "fp_int_src" "true")])
4472
4473 (define_insn "*floatsisf2_sse"
4474   [(set (match_operand:SF 0 "register_operand" "=x,x")
4475         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4476   "TARGET_SSE_MATH"
4477   "cvtsi2ss\t{%1, %0|%0, %1}"
4478   [(set_attr "type" "sseicvt")
4479    (set_attr "mode" "SF")
4480    (set_attr "athlon_decode" "vector,double")
4481    (set_attr "fp_int_src" "true")])
4482
4483 ; Avoid possible reformatting penalty on the destination by first
4484 ; zeroing it out
4485 (define_split
4486   [(set (match_operand:SF 0 "register_operand" "")
4487         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4488   "reload_completed
4489    && TARGET_SSE_MATH && TARGET_SSE_PARTIAL_REGS
4490    && SSE_REG_P (operands[0])"
4491   [(const_int 0)]
4492 {
4493   rtx dest;
4494   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4495   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4496   emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4497   DONE;
4498 })
4499
4500 (define_insn "*floatsisf2_i387"
4501   [(set (match_operand:SF 0 "register_operand" "=f,f")
4502         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4503   "TARGET_80387"
4504   "@
4505    fild%z1\t%1
4506    #"
4507   [(set_attr "type" "fmov,multi")
4508    (set_attr "mode" "SF")
4509    (set_attr "fp_int_src" "true")])
4510
4511 (define_expand "floatdisf2"
4512   [(set (match_operand:SF 0 "register_operand" "")
4513         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4514   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4515   "")
4516
4517 (define_insn "*floatdisf2_mixed"
4518   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4519         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4520   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4521   "@
4522    fild%z1\t%1
4523    #
4524    cvtsi2ss{q}\t{%1, %0|%0, %1}
4525    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4526   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4527    (set_attr "mode" "SF")
4528    (set_attr "athlon_decode" "*,*,vector,double")
4529    (set_attr "fp_int_src" "true")])
4530
4531 (define_insn "*floatdisf2_sse"
4532   [(set (match_operand:SF 0 "register_operand" "=x,x")
4533         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4534   "TARGET_64BIT && TARGET_SSE_MATH"
4535   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4536   [(set_attr "type" "sseicvt")
4537    (set_attr "mode" "SF")
4538    (set_attr "athlon_decode" "vector,double")
4539    (set_attr "fp_int_src" "true")])
4540
4541 ; Avoid possible reformatting penalty on the destination by first
4542 ; zeroing it out
4543 (define_split
4544   [(set (match_operand:SF 0 "register_operand" "")
4545         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4546   "reload_completed
4547    && TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE_PARTIAL_REGS
4548    && SSE_REG_P (operands[0])"
4549   [(const_int 0)]
4550 {
4551   rtx dest;
4552   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4553   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4554   emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4555   DONE;
4556 })
4557
4558 (define_insn "*floatdisf2_i387"
4559   [(set (match_operand:SF 0 "register_operand" "=f,f")
4560         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4561   "TARGET_80387"
4562   "@
4563    fild%z1\t%1
4564    #"
4565   [(set_attr "type" "fmov,multi")
4566    (set_attr "mode" "SF")
4567    (set_attr "fp_int_src" "true")])
4568
4569 (define_expand "floathidf2"
4570   [(set (match_operand:DF 0 "register_operand" "")
4571         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4572   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4573 {
4574   if (TARGET_SSE2 && TARGET_SSE_MATH)
4575     {
4576       emit_insn (gen_floatsidf2 (operands[0],
4577                                  convert_to_mode (SImode, operands[1], 0)));
4578       DONE;
4579     }
4580 })
4581
4582 (define_insn "*floathidf2_i387"
4583   [(set (match_operand:DF 0 "register_operand" "=f,f")
4584         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4585   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4586   "@
4587    fild%z1\t%1
4588    #"
4589   [(set_attr "type" "fmov,multi")
4590    (set_attr "mode" "DF")
4591    (set_attr "fp_int_src" "true")])
4592
4593 (define_expand "floatsidf2"
4594   [(set (match_operand:DF 0 "register_operand" "")
4595         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4596   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4597   "")
4598
4599 (define_insn "*floatsidf2_mixed"
4600   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4601         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4602   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4603   "@
4604    fild%z1\t%1
4605    #
4606    cvtsi2sd\t{%1, %0|%0, %1}
4607    cvtsi2sd\t{%1, %0|%0, %1}"
4608   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4609    (set_attr "mode" "DF")
4610    (set_attr "athlon_decode" "*,*,double,direct")
4611    (set_attr "fp_int_src" "true")])
4612
4613 (define_insn "*floatsidf2_sse"
4614   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4615         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4616   "TARGET_SSE2 && TARGET_SSE_MATH"
4617   "cvtsi2sd\t{%1, %0|%0, %1}"
4618   [(set_attr "type" "sseicvt")
4619    (set_attr "mode" "DF")
4620    (set_attr "athlon_decode" "double,direct")
4621    (set_attr "fp_int_src" "true")])
4622
4623 (define_insn "*floatsidf2_i387"
4624   [(set (match_operand:DF 0 "register_operand" "=f,f")
4625         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4626   "TARGET_80387"
4627   "@
4628    fild%z1\t%1
4629    #"
4630   [(set_attr "type" "fmov,multi")
4631    (set_attr "mode" "DF")
4632    (set_attr "fp_int_src" "true")])
4633
4634 (define_expand "floatdidf2"
4635   [(set (match_operand:DF 0 "register_operand" "")
4636         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4637   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4638   "")
4639
4640 (define_insn "*floatdidf2_mixed"
4641   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4642         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4643   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4644   "@
4645    fild%z1\t%1
4646    #
4647    cvtsi2sd{q}\t{%1, %0|%0, %1}
4648    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4649   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4650    (set_attr "mode" "DF")
4651    (set_attr "athlon_decode" "*,*,double,direct")
4652    (set_attr "fp_int_src" "true")])
4653
4654 (define_insn "*floatdidf2_sse"
4655   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4656         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4657   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4658   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4659   [(set_attr "type" "sseicvt")
4660    (set_attr "mode" "DF")
4661    (set_attr "athlon_decode" "double,direct")
4662    (set_attr "fp_int_src" "true")])
4663
4664 (define_insn "*floatdidf2_i387"
4665   [(set (match_operand:DF 0 "register_operand" "=f,f")
4666         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4667   "TARGET_80387"
4668   "@
4669    fild%z1\t%1
4670    #"
4671   [(set_attr "type" "fmov,multi")
4672    (set_attr "mode" "DF")
4673    (set_attr "fp_int_src" "true")])
4674
4675 (define_insn "floathixf2"
4676   [(set (match_operand:XF 0 "register_operand" "=f,f")
4677         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4678   "TARGET_80387"
4679   "@
4680    fild%z1\t%1
4681    #"
4682   [(set_attr "type" "fmov,multi")
4683    (set_attr "mode" "XF")
4684    (set_attr "fp_int_src" "true")])
4685
4686 (define_insn "floatsixf2"
4687   [(set (match_operand:XF 0 "register_operand" "=f,f")
4688         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4689   "TARGET_80387"
4690   "@
4691    fild%z1\t%1
4692    #"
4693   [(set_attr "type" "fmov,multi")
4694    (set_attr "mode" "XF")
4695    (set_attr "fp_int_src" "true")])
4696
4697 (define_insn "floatdixf2"
4698   [(set (match_operand:XF 0 "register_operand" "=f,f")
4699         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4700   "TARGET_80387"
4701   "@
4702    fild%z1\t%1
4703    #"
4704   [(set_attr "type" "fmov,multi")
4705    (set_attr "mode" "XF")
4706    (set_attr "fp_int_src" "true")])
4707
4708 ;; %%% Kill these when reload knows how to do it.
4709 (define_split
4710   [(set (match_operand 0 "fp_register_operand" "")
4711         (float (match_operand 1 "register_operand" "")))]
4712   "reload_completed
4713    && TARGET_80387
4714    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4715   [(const_int 0)]
4716 {
4717   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4718   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4719   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4720   ix86_free_from_memory (GET_MODE (operands[1]));
4721   DONE;
4722 })
4723
4724 (define_expand "floatunssisf2"
4725   [(use (match_operand:SF 0 "register_operand" ""))
4726    (use (match_operand:SI 1 "register_operand" ""))]
4727   "!TARGET_64BIT && TARGET_SSE_MATH"
4728   "x86_emit_floatuns (operands); DONE;")
4729
4730 (define_expand "floatunsdisf2"
4731   [(use (match_operand:SF 0 "register_operand" ""))
4732    (use (match_operand:DI 1 "register_operand" ""))]
4733   "TARGET_64BIT && TARGET_SSE_MATH"
4734   "x86_emit_floatuns (operands); DONE;")
4735
4736 (define_expand "floatunsdidf2"
4737   [(use (match_operand:DF 0 "register_operand" ""))
4738    (use (match_operand:DI 1 "register_operand" ""))]
4739   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4740   "x86_emit_floatuns (operands); DONE;")
4741 \f
4742 ;; SSE extract/set expanders
4743
4744 (define_expand "vec_setv2df"
4745   [(match_operand:V2DF 0 "register_operand" "")
4746    (match_operand:DF 1 "register_operand" "")
4747    (match_operand 2 "const_int_operand" "")]
4748   "TARGET_SSE2"
4749 {
4750   switch (INTVAL (operands[2]))
4751     {
4752     case 0:
4753       emit_insn (gen_sse2_movsd (operands[0], operands[0],
4754                                  simplify_gen_subreg (V2DFmode, operands[1],
4755                                                       DFmode, 0)));
4756       break;
4757     case 1:
4758       {
4759         rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4760
4761         emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4762       }
4763       break;
4764     default:
4765       abort ();
4766     }
4767   DONE;
4768 })
4769
4770 (define_expand "vec_extractv2df"
4771   [(match_operand:DF 0 "register_operand" "")
4772    (match_operand:V2DF 1 "register_operand" "")
4773    (match_operand 2 "const_int_operand" "")]
4774   "TARGET_SSE2"
4775 {
4776   switch (INTVAL (operands[2]))
4777     {
4778     case 0:
4779       emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4780       break;
4781     case 1:
4782       {
4783         rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4784
4785         emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4786       }
4787       break;
4788     default:
4789       abort ();
4790     }
4791   DONE;
4792 })
4793
4794 (define_expand "vec_initv2df"
4795   [(match_operand:V2DF 0 "register_operand" "")
4796    (match_operand 1 "" "")]
4797   "TARGET_SSE2"
4798 {
4799   ix86_expand_vector_init (operands[0], operands[1]);
4800   DONE;
4801 })
4802
4803 (define_expand "vec_setv4sf"
4804   [(match_operand:V4SF 0 "register_operand" "")
4805    (match_operand:SF 1 "register_operand" "")
4806    (match_operand 2 "const_int_operand" "")]
4807   "TARGET_SSE"
4808 {
4809   switch (INTVAL (operands[2]))
4810     {
4811     case 0:
4812       emit_insn (gen_sse_movss (operands[0], operands[0],
4813                                 simplify_gen_subreg (V4SFmode, operands[1],
4814                                                      SFmode, 0)));
4815       break;
4816     case 1:
4817       {
4818         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4819         rtx tmp = gen_reg_rtx (V4SFmode);
4820  
4821         emit_move_insn (tmp, operands[0]);
4822         emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4823         emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4824         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4825                                    GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4826       }
4827       break;
4828     case 2:
4829       {
4830         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4831         rtx tmp = gen_reg_rtx (V4SFmode);
4832
4833         emit_move_insn (tmp, operands[0]);
4834         emit_insn (gen_sse_movss (tmp, tmp, op1));
4835         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4836                                    GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4837       }
4838       break;
4839     case 3:
4840       {
4841         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4842         rtx tmp = gen_reg_rtx (V4SFmode);
4843
4844         emit_move_insn (tmp, operands[0]);
4845         emit_insn (gen_sse_movss (tmp, tmp, op1));
4846         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4847                                    GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4848       }
4849       break;
4850     default:
4851       abort ();
4852     }
4853   DONE;
4854 })
4855
4856 (define_expand "vec_extractv4sf"
4857   [(match_operand:SF 0 "register_operand" "")
4858    (match_operand:V4SF 1 "register_operand" "")
4859    (match_operand 2 "const_int_operand" "")]
4860   "TARGET_SSE"
4861 {
4862   switch (INTVAL (operands[2]))
4863     {
4864     case 0:
4865       emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4866       break;
4867     case 1:
4868       {
4869         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4870         rtx tmp = gen_reg_rtx (V4SFmode);
4871  
4872         emit_move_insn (tmp, operands[1]);
4873         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4874                                    const1_rtx));
4875       }
4876       break;
4877     case 2:
4878       {
4879         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4880         rtx tmp = gen_reg_rtx (V4SFmode);
4881  
4882         emit_move_insn (tmp, operands[1]);
4883         emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4884       }
4885       break;
4886     case 3:
4887       {
4888         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4889         rtx tmp = gen_reg_rtx (V4SFmode);
4890  
4891         emit_move_insn (tmp, operands[1]);
4892         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4893                                    GEN_INT (3)));
4894       }
4895       break;
4896     default:
4897       abort ();
4898     }
4899   DONE;
4900 })
4901
4902 (define_expand "vec_initv4sf"
4903   [(match_operand:V4SF 0 "register_operand" "")
4904    (match_operand 1 "" "")]
4905   "TARGET_SSE"
4906 {
4907   ix86_expand_vector_init (operands[0], operands[1]);
4908   DONE;
4909 })
4910 \f
4911 ;; Add instructions
4912
4913 ;; %%% splits for addsidi3
4914 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4915 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4916 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4917
4918 (define_expand "adddi3"
4919   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4920         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4921                  (match_operand:DI 2 "x86_64_general_operand" "")))
4922    (clobber (reg:CC FLAGS_REG))]
4923   ""
4924   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4925
4926 (define_insn "*adddi3_1"
4927   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4928         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4929                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4930    (clobber (reg:CC FLAGS_REG))]
4931   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4932   "#")
4933
4934 (define_split
4935   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4936         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4937                  (match_operand:DI 2 "general_operand" "")))
4938    (clobber (reg:CC FLAGS_REG))]
4939   "!TARGET_64BIT && reload_completed"
4940   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4941                                           UNSPEC_ADD_CARRY))
4942               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4943    (parallel [(set (match_dup 3)
4944                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4945                                      (match_dup 4))
4946                             (match_dup 5)))
4947               (clobber (reg:CC FLAGS_REG))])]
4948   "split_di (operands+0, 1, operands+0, operands+3);
4949    split_di (operands+1, 1, operands+1, operands+4);
4950    split_di (operands+2, 1, operands+2, operands+5);")
4951
4952 (define_insn "adddi3_carry_rex64"
4953   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4954           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4955                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4956                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4957    (clobber (reg:CC FLAGS_REG))]
4958   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4959   "adc{q}\t{%2, %0|%0, %2}"
4960   [(set_attr "type" "alu")
4961    (set_attr "pent_pair" "pu")
4962    (set_attr "mode" "DI")])
4963
4964 (define_insn "*adddi3_cc_rex64"
4965   [(set (reg:CC FLAGS_REG)
4966         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4967                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4968                    UNSPEC_ADD_CARRY))
4969    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4970         (plus:DI (match_dup 1) (match_dup 2)))]
4971   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4972   "add{q}\t{%2, %0|%0, %2}"
4973   [(set_attr "type" "alu")
4974    (set_attr "mode" "DI")])
4975
4976 (define_insn "addqi3_carry"
4977   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4978           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4979                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4980                    (match_operand:QI 2 "general_operand" "qi,qm")))
4981    (clobber (reg:CC FLAGS_REG))]
4982   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4983   "adc{b}\t{%2, %0|%0, %2}"
4984   [(set_attr "type" "alu")
4985    (set_attr "pent_pair" "pu")
4986    (set_attr "mode" "QI")])
4987
4988 (define_insn "addhi3_carry"
4989   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4990           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4991                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4992                    (match_operand:HI 2 "general_operand" "ri,rm")))
4993    (clobber (reg:CC FLAGS_REG))]
4994   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4995   "adc{w}\t{%2, %0|%0, %2}"
4996   [(set_attr "type" "alu")
4997    (set_attr "pent_pair" "pu")
4998    (set_attr "mode" "HI")])
4999
5000 (define_insn "addsi3_carry"
5001   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5002           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5003                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5004                    (match_operand:SI 2 "general_operand" "ri,rm")))
5005    (clobber (reg:CC FLAGS_REG))]
5006   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5007   "adc{l}\t{%2, %0|%0, %2}"
5008   [(set_attr "type" "alu")
5009    (set_attr "pent_pair" "pu")
5010    (set_attr "mode" "SI")])
5011
5012 (define_insn "*addsi3_carry_zext"
5013   [(set (match_operand:DI 0 "register_operand" "=r")
5014           (zero_extend:DI 
5015             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5016                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5017                      (match_operand:SI 2 "general_operand" "rim"))))
5018    (clobber (reg:CC FLAGS_REG))]
5019   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5020   "adc{l}\t{%2, %k0|%k0, %2}"
5021   [(set_attr "type" "alu")
5022    (set_attr "pent_pair" "pu")
5023    (set_attr "mode" "SI")])
5024
5025 (define_insn "*addsi3_cc"
5026   [(set (reg:CC FLAGS_REG)
5027         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5028                     (match_operand:SI 2 "general_operand" "ri,rm")]
5029                    UNSPEC_ADD_CARRY))
5030    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5031         (plus:SI (match_dup 1) (match_dup 2)))]
5032   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5033   "add{l}\t{%2, %0|%0, %2}"
5034   [(set_attr "type" "alu")
5035    (set_attr "mode" "SI")])
5036
5037 (define_insn "addqi3_cc"
5038   [(set (reg:CC FLAGS_REG)
5039         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5040                     (match_operand:QI 2 "general_operand" "qi,qm")]
5041                    UNSPEC_ADD_CARRY))
5042    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5043         (plus:QI (match_dup 1) (match_dup 2)))]
5044   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5045   "add{b}\t{%2, %0|%0, %2}"
5046   [(set_attr "type" "alu")
5047    (set_attr "mode" "QI")])
5048
5049 (define_expand "addsi3"
5050   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5051                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5052                             (match_operand:SI 2 "general_operand" "")))
5053               (clobber (reg:CC FLAGS_REG))])]
5054   ""
5055   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5056
5057 (define_insn "*lea_1"
5058   [(set (match_operand:SI 0 "register_operand" "=r")
5059         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5060   "!TARGET_64BIT"
5061   "lea{l}\t{%a1, %0|%0, %a1}"
5062   [(set_attr "type" "lea")
5063    (set_attr "mode" "SI")])
5064
5065 (define_insn "*lea_1_rex64"
5066   [(set (match_operand:SI 0 "register_operand" "=r")
5067         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5068   "TARGET_64BIT"
5069   "lea{l}\t{%a1, %0|%0, %a1}"
5070   [(set_attr "type" "lea")
5071    (set_attr "mode" "SI")])
5072
5073 (define_insn "*lea_1_zext"
5074   [(set (match_operand:DI 0 "register_operand" "=r")
5075         (zero_extend:DI
5076          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5077   "TARGET_64BIT"
5078   "lea{l}\t{%a1, %k0|%k0, %a1}"
5079   [(set_attr "type" "lea")
5080    (set_attr "mode" "SI")])
5081
5082 (define_insn "*lea_2_rex64"
5083   [(set (match_operand:DI 0 "register_operand" "=r")
5084         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5085   "TARGET_64BIT"
5086   "lea{q}\t{%a1, %0|%0, %a1}"
5087   [(set_attr "type" "lea")
5088    (set_attr "mode" "DI")])
5089
5090 ;; The lea patterns for non-Pmodes needs to be matched by several
5091 ;; insns converted to real lea by splitters.
5092
5093 (define_insn_and_split "*lea_general_1"
5094   [(set (match_operand 0 "register_operand" "=r")
5095         (plus (plus (match_operand 1 "index_register_operand" "l")
5096                     (match_operand 2 "register_operand" "r"))
5097               (match_operand 3 "immediate_operand" "i")))]
5098   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5099     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5100    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5101    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5102    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5103    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5104        || GET_MODE (operands[3]) == VOIDmode)"
5105   "#"
5106   "&& reload_completed"
5107   [(const_int 0)]
5108 {
5109   rtx pat;
5110   operands[0] = gen_lowpart (SImode, operands[0]);
5111   operands[1] = gen_lowpart (Pmode, operands[1]);
5112   operands[2] = gen_lowpart (Pmode, operands[2]);
5113   operands[3] = gen_lowpart (Pmode, operands[3]);
5114   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5115                       operands[3]);
5116   if (Pmode != SImode)
5117     pat = gen_rtx_SUBREG (SImode, pat, 0);
5118   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5119   DONE;
5120 }
5121   [(set_attr "type" "lea")
5122    (set_attr "mode" "SI")])
5123
5124 (define_insn_and_split "*lea_general_1_zext"
5125   [(set (match_operand:DI 0 "register_operand" "=r")
5126         (zero_extend:DI
5127           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5128                             (match_operand:SI 2 "register_operand" "r"))
5129                    (match_operand:SI 3 "immediate_operand" "i"))))]
5130   "TARGET_64BIT"
5131   "#"
5132   "&& reload_completed"
5133   [(set (match_dup 0)
5134         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5135                                                      (match_dup 2))
5136                                             (match_dup 3)) 0)))]
5137 {
5138   operands[1] = gen_lowpart (Pmode, operands[1]);
5139   operands[2] = gen_lowpart (Pmode, operands[2]);
5140   operands[3] = gen_lowpart (Pmode, operands[3]);
5141 }
5142   [(set_attr "type" "lea")
5143    (set_attr "mode" "SI")])
5144
5145 (define_insn_and_split "*lea_general_2"
5146   [(set (match_operand 0 "register_operand" "=r")
5147         (plus (mult (match_operand 1 "index_register_operand" "l")
5148                     (match_operand 2 "const248_operand" "i"))
5149               (match_operand 3 "nonmemory_operand" "ri")))]
5150   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5151     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5152    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5153    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5154    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5155        || GET_MODE (operands[3]) == VOIDmode)"
5156   "#"
5157   "&& reload_completed"
5158   [(const_int 0)]
5159 {
5160   rtx pat;
5161   operands[0] = gen_lowpart (SImode, operands[0]);
5162   operands[1] = gen_lowpart (Pmode, operands[1]);
5163   operands[3] = gen_lowpart (Pmode, operands[3]);
5164   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5165                       operands[3]);
5166   if (Pmode != SImode)
5167     pat = gen_rtx_SUBREG (SImode, pat, 0);
5168   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5169   DONE;
5170 }
5171   [(set_attr "type" "lea")
5172    (set_attr "mode" "SI")])
5173
5174 (define_insn_and_split "*lea_general_2_zext"
5175   [(set (match_operand:DI 0 "register_operand" "=r")
5176         (zero_extend:DI
5177           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5178                             (match_operand:SI 2 "const248_operand" "n"))
5179                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5180   "TARGET_64BIT"
5181   "#"
5182   "&& reload_completed"
5183   [(set (match_dup 0)
5184         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5185                                                      (match_dup 2))
5186                                             (match_dup 3)) 0)))]
5187 {
5188   operands[1] = gen_lowpart (Pmode, operands[1]);
5189   operands[3] = gen_lowpart (Pmode, operands[3]);
5190 }
5191   [(set_attr "type" "lea")
5192    (set_attr "mode" "SI")])
5193
5194 (define_insn_and_split "*lea_general_3"
5195   [(set (match_operand 0 "register_operand" "=r")
5196         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5197                           (match_operand 2 "const248_operand" "i"))
5198                     (match_operand 3 "register_operand" "r"))
5199               (match_operand 4 "immediate_operand" "i")))]
5200   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5201     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5202    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5203    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5204    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5205   "#"
5206   "&& reload_completed"
5207   [(const_int 0)]
5208 {
5209   rtx pat;
5210   operands[0] = gen_lowpart (SImode, operands[0]);
5211   operands[1] = gen_lowpart (Pmode, operands[1]);
5212   operands[3] = gen_lowpart (Pmode, operands[3]);
5213   operands[4] = gen_lowpart (Pmode, operands[4]);
5214   pat = gen_rtx_PLUS (Pmode,
5215                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5216                                                          operands[2]),
5217                                     operands[3]),
5218                       operands[4]);
5219   if (Pmode != SImode)
5220     pat = gen_rtx_SUBREG (SImode, pat, 0);
5221   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5222   DONE;
5223 }
5224   [(set_attr "type" "lea")
5225    (set_attr "mode" "SI")])
5226
5227 (define_insn_and_split "*lea_general_3_zext"
5228   [(set (match_operand:DI 0 "register_operand" "=r")
5229         (zero_extend:DI
5230           (plus:SI (plus:SI (mult:SI
5231                               (match_operand:SI 1 "index_register_operand" "l")
5232                               (match_operand:SI 2 "const248_operand" "n"))
5233                             (match_operand:SI 3 "register_operand" "r"))
5234                    (match_operand:SI 4 "immediate_operand" "i"))))]
5235   "TARGET_64BIT"
5236   "#"
5237   "&& reload_completed"
5238   [(set (match_dup 0)
5239         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5240                                                               (match_dup 2))
5241                                                      (match_dup 3))
5242                                             (match_dup 4)) 0)))]
5243 {
5244   operands[1] = gen_lowpart (Pmode, operands[1]);
5245   operands[3] = gen_lowpart (Pmode, operands[3]);
5246   operands[4] = gen_lowpart (Pmode, operands[4]);
5247 }
5248   [(set_attr "type" "lea")
5249    (set_attr "mode" "SI")])
5250
5251 (define_insn "*adddi_1_rex64"
5252   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5253         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5254                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5255    (clobber (reg:CC FLAGS_REG))]
5256   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5257 {
5258   switch (get_attr_type (insn))
5259     {
5260     case TYPE_LEA:
5261       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5262       return "lea{q}\t{%a2, %0|%0, %a2}";
5263
5264     case TYPE_INCDEC:
5265       if (! rtx_equal_p (operands[0], operands[1]))
5266         abort ();
5267       if (operands[2] == const1_rtx)
5268         return "inc{q}\t%0";
5269       else if (operands[2] == constm1_rtx)
5270         return "dec{q}\t%0";
5271       else
5272         abort ();
5273
5274     default:
5275       if (! rtx_equal_p (operands[0], operands[1]))
5276         abort ();
5277
5278       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5279          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5280       if (GET_CODE (operands[2]) == CONST_INT
5281           /* Avoid overflows.  */
5282           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5283           && (INTVAL (operands[2]) == 128
5284               || (INTVAL (operands[2]) < 0
5285                   && INTVAL (operands[2]) != -128)))
5286         {
5287           operands[2] = GEN_INT (-INTVAL (operands[2]));
5288           return "sub{q}\t{%2, %0|%0, %2}";
5289         }
5290       return "add{q}\t{%2, %0|%0, %2}";
5291     }
5292 }
5293   [(set (attr "type")
5294      (cond [(eq_attr "alternative" "2")
5295               (const_string "lea")
5296             ; Current assemblers are broken and do not allow @GOTOFF in
5297             ; ought but a memory context.
5298             (match_operand:DI 2 "pic_symbolic_operand" "")
5299               (const_string "lea")
5300             (match_operand:DI 2 "incdec_operand" "")
5301               (const_string "incdec")
5302            ]
5303            (const_string "alu")))
5304    (set_attr "mode" "DI")])
5305
5306 ;; Convert lea to the lea pattern to avoid flags dependency.
5307 (define_split
5308   [(set (match_operand:DI 0 "register_operand" "")
5309         (plus:DI (match_operand:DI 1 "register_operand" "")
5310                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5311    (clobber (reg:CC FLAGS_REG))]
5312   "TARGET_64BIT && reload_completed
5313    && true_regnum (operands[0]) != true_regnum (operands[1])"
5314   [(set (match_dup 0)
5315         (plus:DI (match_dup 1)
5316                  (match_dup 2)))]
5317   "")
5318
5319 (define_insn "*adddi_2_rex64"
5320   [(set (reg FLAGS_REG)
5321         (compare
5322           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5323                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5324           (const_int 0)))                       
5325    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5326         (plus:DI (match_dup 1) (match_dup 2)))]
5327   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5328    && ix86_binary_operator_ok (PLUS, DImode, operands)
5329    /* Current assemblers are broken and do not allow @GOTOFF in
5330       ought but a memory context.  */
5331    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5332 {
5333   switch (get_attr_type (insn))
5334     {
5335     case TYPE_INCDEC:
5336       if (! rtx_equal_p (operands[0], operands[1]))
5337         abort ();
5338       if (operands[2] == const1_rtx)
5339         return "inc{q}\t%0";
5340       else if (operands[2] == constm1_rtx)
5341         return "dec{q}\t%0";
5342       else
5343         abort ();
5344
5345     default:
5346       if (! rtx_equal_p (operands[0], operands[1]))
5347         abort ();
5348       /* ???? We ought to handle there the 32bit case too
5349          - do we need new constraint?  */
5350       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5351          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5352       if (GET_CODE (operands[2]) == CONST_INT
5353           /* Avoid overflows.  */
5354           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5355           && (INTVAL (operands[2]) == 128
5356               || (INTVAL (operands[2]) < 0
5357                   && INTVAL (operands[2]) != -128)))
5358         {
5359           operands[2] = GEN_INT (-INTVAL (operands[2]));
5360           return "sub{q}\t{%2, %0|%0, %2}";
5361         }
5362       return "add{q}\t{%2, %0|%0, %2}";
5363     }
5364 }
5365   [(set (attr "type")
5366      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5367         (const_string "incdec")
5368         (const_string "alu")))
5369    (set_attr "mode" "DI")])
5370
5371 (define_insn "*adddi_3_rex64"
5372   [(set (reg FLAGS_REG)
5373         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5374                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5375    (clobber (match_scratch:DI 0 "=r"))]
5376   "TARGET_64BIT
5377    && ix86_match_ccmode (insn, CCZmode)
5378    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5379    /* Current assemblers are broken and do not allow @GOTOFF in
5380       ought but a memory context.  */
5381    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5382 {
5383   switch (get_attr_type (insn))
5384     {
5385     case TYPE_INCDEC:
5386       if (! rtx_equal_p (operands[0], operands[1]))
5387         abort ();
5388       if (operands[2] == const1_rtx)
5389         return "inc{q}\t%0";
5390       else if (operands[2] == constm1_rtx)
5391         return "dec{q}\t%0";
5392       else
5393         abort ();
5394
5395     default:
5396       if (! rtx_equal_p (operands[0], operands[1]))
5397         abort ();
5398       /* ???? We ought to handle there the 32bit case too
5399          - do we need new constraint?  */
5400       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5401          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5402       if (GET_CODE (operands[2]) == CONST_INT
5403           /* Avoid overflows.  */
5404           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5405           && (INTVAL (operands[2]) == 128
5406               || (INTVAL (operands[2]) < 0
5407                   && INTVAL (operands[2]) != -128)))
5408         {
5409           operands[2] = GEN_INT (-INTVAL (operands[2]));
5410           return "sub{q}\t{%2, %0|%0, %2}";
5411         }
5412       return "add{q}\t{%2, %0|%0, %2}";
5413     }
5414 }
5415   [(set (attr "type")
5416      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5417         (const_string "incdec")
5418         (const_string "alu")))
5419    (set_attr "mode" "DI")])
5420
5421 ; For comparisons against 1, -1 and 128, we may generate better code
5422 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5423 ; is matched then.  We can't accept general immediate, because for
5424 ; case of overflows,  the result is messed up.
5425 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5426 ; when negated.
5427 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5428 ; only for comparisons not depending on it.
5429 (define_insn "*adddi_4_rex64"
5430   [(set (reg FLAGS_REG)
5431         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5432                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5433    (clobber (match_scratch:DI 0 "=rm"))]
5434   "TARGET_64BIT
5435    &&  ix86_match_ccmode (insn, CCGCmode)"
5436 {
5437   switch (get_attr_type (insn))
5438     {
5439     case TYPE_INCDEC:
5440       if (operands[2] == constm1_rtx)
5441         return "inc{q}\t%0";
5442       else if (operands[2] == const1_rtx)
5443         return "dec{q}\t%0";
5444       else
5445         abort();
5446
5447     default:
5448       if (! rtx_equal_p (operands[0], operands[1]))
5449         abort ();
5450       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5451          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5452       if ((INTVAL (operands[2]) == -128
5453            || (INTVAL (operands[2]) > 0
5454                && INTVAL (operands[2]) != 128))
5455           /* Avoid overflows.  */
5456           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5457         return "sub{q}\t{%2, %0|%0, %2}";
5458       operands[2] = GEN_INT (-INTVAL (operands[2]));
5459       return "add{q}\t{%2, %0|%0, %2}";
5460     }
5461 }
5462   [(set (attr "type")
5463      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5464         (const_string "incdec")
5465         (const_string "alu")))
5466    (set_attr "mode" "DI")])
5467
5468 (define_insn "*adddi_5_rex64"
5469   [(set (reg FLAGS_REG)
5470         (compare
5471           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5472                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5473           (const_int 0)))                       
5474    (clobber (match_scratch:DI 0 "=r"))]
5475   "TARGET_64BIT
5476    && ix86_match_ccmode (insn, CCGOCmode)
5477    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5478    /* Current assemblers are broken and do not allow @GOTOFF in
5479       ought but a memory context.  */
5480    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5481 {
5482   switch (get_attr_type (insn))
5483     {
5484     case TYPE_INCDEC:
5485       if (! rtx_equal_p (operands[0], operands[1]))
5486         abort ();
5487       if (operands[2] == const1_rtx)
5488         return "inc{q}\t%0";
5489       else if (operands[2] == constm1_rtx)
5490         return "dec{q}\t%0";
5491       else
5492         abort();
5493
5494     default:
5495       if (! rtx_equal_p (operands[0], operands[1]))
5496         abort ();
5497       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5498          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5499       if (GET_CODE (operands[2]) == CONST_INT
5500           /* Avoid overflows.  */
5501           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5502           && (INTVAL (operands[2]) == 128
5503               || (INTVAL (operands[2]) < 0
5504                   && INTVAL (operands[2]) != -128)))
5505         {
5506           operands[2] = GEN_INT (-INTVAL (operands[2]));
5507           return "sub{q}\t{%2, %0|%0, %2}";
5508         }
5509       return "add{q}\t{%2, %0|%0, %2}";
5510     }
5511 }
5512   [(set (attr "type")
5513      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5514         (const_string "incdec")
5515         (const_string "alu")))
5516    (set_attr "mode" "DI")])
5517
5518
5519 (define_insn "*addsi_1"
5520   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5521         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5522                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5523    (clobber (reg:CC FLAGS_REG))]
5524   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5525 {
5526   switch (get_attr_type (insn))
5527     {
5528     case TYPE_LEA:
5529       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5530       return "lea{l}\t{%a2, %0|%0, %a2}";
5531
5532     case TYPE_INCDEC:
5533       if (! rtx_equal_p (operands[0], operands[1]))
5534         abort ();
5535       if (operands[2] == const1_rtx)
5536         return "inc{l}\t%0";
5537       else if (operands[2] == constm1_rtx)
5538         return "dec{l}\t%0";
5539       else
5540         abort();
5541
5542     default:
5543       if (! rtx_equal_p (operands[0], operands[1]))
5544         abort ();
5545
5546       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5547          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5548       if (GET_CODE (operands[2]) == CONST_INT
5549           && (INTVAL (operands[2]) == 128
5550               || (INTVAL (operands[2]) < 0
5551                   && INTVAL (operands[2]) != -128)))
5552         {
5553           operands[2] = GEN_INT (-INTVAL (operands[2]));
5554           return "sub{l}\t{%2, %0|%0, %2}";
5555         }
5556       return "add{l}\t{%2, %0|%0, %2}";
5557     }
5558 }
5559   [(set (attr "type")
5560      (cond [(eq_attr "alternative" "2")
5561               (const_string "lea")
5562             ; Current assemblers are broken and do not allow @GOTOFF in
5563             ; ought but a memory context.
5564             (match_operand:SI 2 "pic_symbolic_operand" "")
5565               (const_string "lea")
5566             (match_operand:SI 2 "incdec_operand" "")
5567               (const_string "incdec")
5568            ]
5569            (const_string "alu")))
5570    (set_attr "mode" "SI")])
5571
5572 ;; Convert lea to the lea pattern to avoid flags dependency.
5573 (define_split
5574   [(set (match_operand 0 "register_operand" "")
5575         (plus (match_operand 1 "register_operand" "")
5576               (match_operand 2 "nonmemory_operand" "")))
5577    (clobber (reg:CC FLAGS_REG))]
5578   "reload_completed
5579    && true_regnum (operands[0]) != true_regnum (operands[1])"
5580   [(const_int 0)]
5581 {
5582   rtx pat;
5583   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5584      may confuse gen_lowpart.  */
5585   if (GET_MODE (operands[0]) != Pmode)
5586     {
5587       operands[1] = gen_lowpart (Pmode, operands[1]);
5588       operands[2] = gen_lowpart (Pmode, operands[2]);
5589     }
5590   operands[0] = gen_lowpart (SImode, operands[0]);
5591   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5592   if (Pmode != SImode)
5593     pat = gen_rtx_SUBREG (SImode, pat, 0);
5594   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5595   DONE;
5596 })
5597
5598 ;; It may seem that nonimmediate operand is proper one for operand 1.
5599 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5600 ;; we take care in ix86_binary_operator_ok to not allow two memory
5601 ;; operands so proper swapping will be done in reload.  This allow
5602 ;; patterns constructed from addsi_1 to match.
5603 (define_insn "addsi_1_zext"
5604   [(set (match_operand:DI 0 "register_operand" "=r,r")
5605         (zero_extend:DI
5606           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5607                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5608    (clobber (reg:CC FLAGS_REG))]
5609   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5610 {
5611   switch (get_attr_type (insn))
5612     {
5613     case TYPE_LEA:
5614       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5615       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5616
5617     case TYPE_INCDEC:
5618       if (operands[2] == const1_rtx)
5619         return "inc{l}\t%k0";
5620       else if (operands[2] == constm1_rtx)
5621         return "dec{l}\t%k0";
5622       else
5623         abort();
5624
5625     default:
5626       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5627          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5628       if (GET_CODE (operands[2]) == CONST_INT
5629           && (INTVAL (operands[2]) == 128
5630               || (INTVAL (operands[2]) < 0
5631                   && INTVAL (operands[2]) != -128)))
5632         {
5633           operands[2] = GEN_INT (-INTVAL (operands[2]));
5634           return "sub{l}\t{%2, %k0|%k0, %2}";
5635         }
5636       return "add{l}\t{%2, %k0|%k0, %2}";
5637     }
5638 }
5639   [(set (attr "type")
5640      (cond [(eq_attr "alternative" "1")
5641               (const_string "lea")
5642             ; Current assemblers are broken and do not allow @GOTOFF in
5643             ; ought but a memory context.
5644             (match_operand:SI 2 "pic_symbolic_operand" "")
5645               (const_string "lea")
5646             (match_operand:SI 2 "incdec_operand" "")
5647               (const_string "incdec")
5648            ]
5649            (const_string "alu")))
5650    (set_attr "mode" "SI")])
5651
5652 ;; Convert lea to the lea pattern to avoid flags dependency.
5653 (define_split
5654   [(set (match_operand:DI 0 "register_operand" "")
5655         (zero_extend:DI
5656           (plus:SI (match_operand:SI 1 "register_operand" "")
5657                    (match_operand:SI 2 "nonmemory_operand" ""))))
5658    (clobber (reg:CC FLAGS_REG))]
5659   "TARGET_64BIT && reload_completed
5660    && true_regnum (operands[0]) != true_regnum (operands[1])"
5661   [(set (match_dup 0)
5662         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5663 {
5664   operands[1] = gen_lowpart (Pmode, operands[1]);
5665   operands[2] = gen_lowpart (Pmode, operands[2]);
5666 })
5667
5668 (define_insn "*addsi_2"
5669   [(set (reg FLAGS_REG)
5670         (compare
5671           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5672                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5673           (const_int 0)))                       
5674    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5675         (plus:SI (match_dup 1) (match_dup 2)))]
5676   "ix86_match_ccmode (insn, CCGOCmode)
5677    && ix86_binary_operator_ok (PLUS, SImode, operands)
5678    /* Current assemblers are broken and do not allow @GOTOFF in
5679       ought but a memory context.  */
5680    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5681 {
5682   switch (get_attr_type (insn))
5683     {
5684     case TYPE_INCDEC:
5685       if (! rtx_equal_p (operands[0], operands[1]))
5686         abort ();
5687       if (operands[2] == const1_rtx)
5688         return "inc{l}\t%0";
5689       else if (operands[2] == constm1_rtx)
5690         return "dec{l}\t%0";
5691       else
5692         abort();
5693
5694     default:
5695       if (! rtx_equal_p (operands[0], operands[1]))
5696         abort ();
5697       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5698          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5699       if (GET_CODE (operands[2]) == CONST_INT
5700           && (INTVAL (operands[2]) == 128
5701               || (INTVAL (operands[2]) < 0
5702                   && INTVAL (operands[2]) != -128)))
5703         {
5704           operands[2] = GEN_INT (-INTVAL (operands[2]));
5705           return "sub{l}\t{%2, %0|%0, %2}";
5706         }
5707       return "add{l}\t{%2, %0|%0, %2}";
5708     }
5709 }
5710   [(set (attr "type")
5711      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5712         (const_string "incdec")
5713         (const_string "alu")))
5714    (set_attr "mode" "SI")])
5715
5716 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5717 (define_insn "*addsi_2_zext"
5718   [(set (reg FLAGS_REG)
5719         (compare
5720           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5721                    (match_operand:SI 2 "general_operand" "rmni"))
5722           (const_int 0)))                       
5723    (set (match_operand:DI 0 "register_operand" "=r")
5724         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5725   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5726    && ix86_binary_operator_ok (PLUS, SImode, operands)
5727    /* Current assemblers are broken and do not allow @GOTOFF in
5728       ought but a memory context.  */
5729    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5730 {
5731   switch (get_attr_type (insn))
5732     {
5733     case TYPE_INCDEC:
5734       if (operands[2] == const1_rtx)
5735         return "inc{l}\t%k0";
5736       else if (operands[2] == constm1_rtx)
5737         return "dec{l}\t%k0";
5738       else
5739         abort();
5740
5741     default:
5742       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5743          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5744       if (GET_CODE (operands[2]) == CONST_INT
5745           && (INTVAL (operands[2]) == 128
5746               || (INTVAL (operands[2]) < 0
5747                   && INTVAL (operands[2]) != -128)))
5748         {
5749           operands[2] = GEN_INT (-INTVAL (operands[2]));
5750           return "sub{l}\t{%2, %k0|%k0, %2}";
5751         }
5752       return "add{l}\t{%2, %k0|%k0, %2}";
5753     }
5754 }
5755   [(set (attr "type")
5756      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5757         (const_string "incdec")
5758         (const_string "alu")))
5759    (set_attr "mode" "SI")])
5760
5761 (define_insn "*addsi_3"
5762   [(set (reg FLAGS_REG)
5763         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5764                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5765    (clobber (match_scratch:SI 0 "=r"))]
5766   "ix86_match_ccmode (insn, CCZmode)
5767    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5768    /* Current assemblers are broken and do not allow @GOTOFF in
5769       ought but a memory context.  */
5770    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5771 {
5772   switch (get_attr_type (insn))
5773     {
5774     case TYPE_INCDEC:
5775       if (! rtx_equal_p (operands[0], operands[1]))
5776         abort ();
5777       if (operands[2] == const1_rtx)
5778         return "inc{l}\t%0";
5779       else if (operands[2] == constm1_rtx)
5780         return "dec{l}\t%0";
5781       else
5782         abort();
5783
5784     default:
5785       if (! rtx_equal_p (operands[0], operands[1]))
5786         abort ();
5787       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5788          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5789       if (GET_CODE (operands[2]) == CONST_INT
5790           && (INTVAL (operands[2]) == 128
5791               || (INTVAL (operands[2]) < 0
5792                   && INTVAL (operands[2]) != -128)))
5793         {
5794           operands[2] = GEN_INT (-INTVAL (operands[2]));
5795           return "sub{l}\t{%2, %0|%0, %2}";
5796         }
5797       return "add{l}\t{%2, %0|%0, %2}";
5798     }
5799 }
5800   [(set (attr "type")
5801      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5802         (const_string "incdec")
5803         (const_string "alu")))
5804    (set_attr "mode" "SI")])
5805
5806 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5807 (define_insn "*addsi_3_zext"
5808   [(set (reg FLAGS_REG)
5809         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5810                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5811    (set (match_operand:DI 0 "register_operand" "=r")
5812         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5813   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5814    && ix86_binary_operator_ok (PLUS, SImode, operands)
5815    /* Current assemblers are broken and do not allow @GOTOFF in
5816       ought but a memory context.  */
5817    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5818 {
5819   switch (get_attr_type (insn))
5820     {
5821     case TYPE_INCDEC:
5822       if (operands[2] == const1_rtx)
5823         return "inc{l}\t%k0";
5824       else if (operands[2] == constm1_rtx)
5825         return "dec{l}\t%k0";
5826       else
5827         abort();
5828
5829     default:
5830       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5831          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5832       if (GET_CODE (operands[2]) == CONST_INT
5833           && (INTVAL (operands[2]) == 128
5834               || (INTVAL (operands[2]) < 0
5835                   && INTVAL (operands[2]) != -128)))
5836         {
5837           operands[2] = GEN_INT (-INTVAL (operands[2]));
5838           return "sub{l}\t{%2, %k0|%k0, %2}";
5839         }
5840       return "add{l}\t{%2, %k0|%k0, %2}";
5841     }
5842 }
5843   [(set (attr "type")
5844      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5845         (const_string "incdec")
5846         (const_string "alu")))
5847    (set_attr "mode" "SI")])
5848
5849 ; For comparisons against 1, -1 and 128, we may generate better code
5850 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5851 ; is matched then.  We can't accept general immediate, because for
5852 ; case of overflows,  the result is messed up.
5853 ; This pattern also don't hold of 0x80000000, since the value overflows
5854 ; when negated.
5855 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5856 ; only for comparisons not depending on it.
5857 (define_insn "*addsi_4"
5858   [(set (reg FLAGS_REG)
5859         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5860                  (match_operand:SI 2 "const_int_operand" "n")))
5861    (clobber (match_scratch:SI 0 "=rm"))]
5862   "ix86_match_ccmode (insn, CCGCmode)
5863    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5864 {
5865   switch (get_attr_type (insn))
5866     {
5867     case TYPE_INCDEC:
5868       if (operands[2] == constm1_rtx)
5869         return "inc{l}\t%0";
5870       else if (operands[2] == const1_rtx)
5871         return "dec{l}\t%0";
5872       else
5873         abort();
5874
5875     default:
5876       if (! rtx_equal_p (operands[0], operands[1]))
5877         abort ();
5878       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5879          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5880       if ((INTVAL (operands[2]) == -128
5881            || (INTVAL (operands[2]) > 0
5882                && INTVAL (operands[2]) != 128)))
5883         return "sub{l}\t{%2, %0|%0, %2}";
5884       operands[2] = GEN_INT (-INTVAL (operands[2]));
5885       return "add{l}\t{%2, %0|%0, %2}";
5886     }
5887 }
5888   [(set (attr "type")
5889      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5890         (const_string "incdec")
5891         (const_string "alu")))
5892    (set_attr "mode" "SI")])
5893
5894 (define_insn "*addsi_5"
5895   [(set (reg FLAGS_REG)
5896         (compare
5897           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5898                    (match_operand:SI 2 "general_operand" "rmni"))
5899           (const_int 0)))                       
5900    (clobber (match_scratch:SI 0 "=r"))]
5901   "ix86_match_ccmode (insn, CCGOCmode)
5902    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5903    /* Current assemblers are broken and do not allow @GOTOFF in
5904       ought but a memory context.  */
5905    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5906 {
5907   switch (get_attr_type (insn))
5908     {
5909     case TYPE_INCDEC:
5910       if (! rtx_equal_p (operands[0], operands[1]))
5911         abort ();
5912       if (operands[2] == const1_rtx)
5913         return "inc{l}\t%0";
5914       else if (operands[2] == constm1_rtx)
5915         return "dec{l}\t%0";
5916       else
5917         abort();
5918
5919     default:
5920       if (! rtx_equal_p (operands[0], operands[1]))
5921         abort ();
5922       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5923          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5924       if (GET_CODE (operands[2]) == CONST_INT
5925           && (INTVAL (operands[2]) == 128
5926               || (INTVAL (operands[2]) < 0
5927                   && INTVAL (operands[2]) != -128)))
5928         {
5929           operands[2] = GEN_INT (-INTVAL (operands[2]));
5930           return "sub{l}\t{%2, %0|%0, %2}";
5931         }
5932       return "add{l}\t{%2, %0|%0, %2}";
5933     }
5934 }
5935   [(set (attr "type")
5936      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5937         (const_string "incdec")
5938         (const_string "alu")))
5939    (set_attr "mode" "SI")])
5940
5941 (define_expand "addhi3"
5942   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5943                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5944                             (match_operand:HI 2 "general_operand" "")))
5945               (clobber (reg:CC FLAGS_REG))])]
5946   "TARGET_HIMODE_MATH"
5947   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5948
5949 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5950 ;; type optimizations enabled by define-splits.  This is not important
5951 ;; for PII, and in fact harmful because of partial register stalls.
5952
5953 (define_insn "*addhi_1_lea"
5954   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5955         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5956                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5957    (clobber (reg:CC FLAGS_REG))]
5958   "!TARGET_PARTIAL_REG_STALL
5959    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5960 {
5961   switch (get_attr_type (insn))
5962     {
5963     case TYPE_LEA:
5964       return "#";
5965     case TYPE_INCDEC:
5966       if (operands[2] == const1_rtx)
5967         return "inc{w}\t%0";
5968       else if (operands[2] == constm1_rtx)
5969         return "dec{w}\t%0";
5970       abort();
5971
5972     default:
5973       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5974          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5975       if (GET_CODE (operands[2]) == CONST_INT
5976           && (INTVAL (operands[2]) == 128
5977               || (INTVAL (operands[2]) < 0
5978                   && INTVAL (operands[2]) != -128)))
5979         {
5980           operands[2] = GEN_INT (-INTVAL (operands[2]));
5981           return "sub{w}\t{%2, %0|%0, %2}";
5982         }
5983       return "add{w}\t{%2, %0|%0, %2}";
5984     }
5985 }
5986   [(set (attr "type")
5987      (if_then_else (eq_attr "alternative" "2")
5988         (const_string "lea")
5989         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5990            (const_string "incdec")
5991            (const_string "alu"))))
5992    (set_attr "mode" "HI,HI,SI")])
5993
5994 (define_insn "*addhi_1"
5995   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5996         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5997                  (match_operand:HI 2 "general_operand" "ri,rm")))
5998    (clobber (reg:CC FLAGS_REG))]
5999   "TARGET_PARTIAL_REG_STALL
6000    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6001 {
6002   switch (get_attr_type (insn))
6003     {
6004     case TYPE_INCDEC:
6005       if (operands[2] == const1_rtx)
6006         return "inc{w}\t%0";
6007       else if (operands[2] == constm1_rtx)
6008         return "dec{w}\t%0";
6009       abort();
6010
6011     default:
6012       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6013          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6014       if (GET_CODE (operands[2]) == CONST_INT
6015           && (INTVAL (operands[2]) == 128
6016               || (INTVAL (operands[2]) < 0
6017                   && INTVAL (operands[2]) != -128)))
6018         {
6019           operands[2] = GEN_INT (-INTVAL (operands[2]));
6020           return "sub{w}\t{%2, %0|%0, %2}";
6021         }
6022       return "add{w}\t{%2, %0|%0, %2}";
6023     }
6024 }
6025   [(set (attr "type")
6026      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6027         (const_string "incdec")
6028         (const_string "alu")))
6029    (set_attr "mode" "HI")])
6030
6031 (define_insn "*addhi_2"
6032   [(set (reg FLAGS_REG)
6033         (compare
6034           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6035                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6036           (const_int 0)))                       
6037    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6038         (plus:HI (match_dup 1) (match_dup 2)))]
6039   "ix86_match_ccmode (insn, CCGOCmode)
6040    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6041 {
6042   switch (get_attr_type (insn))
6043     {
6044     case TYPE_INCDEC:
6045       if (operands[2] == const1_rtx)
6046         return "inc{w}\t%0";
6047       else if (operands[2] == constm1_rtx)
6048         return "dec{w}\t%0";
6049       abort();
6050
6051     default:
6052       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6053          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6054       if (GET_CODE (operands[2]) == CONST_INT
6055           && (INTVAL (operands[2]) == 128
6056               || (INTVAL (operands[2]) < 0
6057                   && INTVAL (operands[2]) != -128)))
6058         {
6059           operands[2] = GEN_INT (-INTVAL (operands[2]));
6060           return "sub{w}\t{%2, %0|%0, %2}";
6061         }
6062       return "add{w}\t{%2, %0|%0, %2}";
6063     }
6064 }
6065   [(set (attr "type")
6066      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6067         (const_string "incdec")
6068         (const_string "alu")))
6069    (set_attr "mode" "HI")])
6070
6071 (define_insn "*addhi_3"
6072   [(set (reg FLAGS_REG)
6073         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6074                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6075    (clobber (match_scratch:HI 0 "=r"))]
6076   "ix86_match_ccmode (insn, CCZmode)
6077    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6078 {
6079   switch (get_attr_type (insn))
6080     {
6081     case TYPE_INCDEC:
6082       if (operands[2] == const1_rtx)
6083         return "inc{w}\t%0";
6084       else if (operands[2] == constm1_rtx)
6085         return "dec{w}\t%0";
6086       abort();
6087
6088     default:
6089       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6090          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6091       if (GET_CODE (operands[2]) == CONST_INT
6092           && (INTVAL (operands[2]) == 128
6093               || (INTVAL (operands[2]) < 0
6094                   && INTVAL (operands[2]) != -128)))
6095         {
6096           operands[2] = GEN_INT (-INTVAL (operands[2]));
6097           return "sub{w}\t{%2, %0|%0, %2}";
6098         }
6099       return "add{w}\t{%2, %0|%0, %2}";
6100     }
6101 }
6102   [(set (attr "type")
6103      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6104         (const_string "incdec")
6105         (const_string "alu")))
6106    (set_attr "mode" "HI")])
6107
6108 ; See comments above addsi_3_imm for details.
6109 (define_insn "*addhi_4"
6110   [(set (reg FLAGS_REG)
6111         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6112                  (match_operand:HI 2 "const_int_operand" "n")))
6113    (clobber (match_scratch:HI 0 "=rm"))]
6114   "ix86_match_ccmode (insn, CCGCmode)
6115    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6116 {
6117   switch (get_attr_type (insn))
6118     {
6119     case TYPE_INCDEC:
6120       if (operands[2] == constm1_rtx)
6121         return "inc{w}\t%0";
6122       else if (operands[2] == const1_rtx)
6123         return "dec{w}\t%0";
6124       else
6125         abort();
6126
6127     default:
6128       if (! rtx_equal_p (operands[0], operands[1]))
6129         abort ();
6130       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6131          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6132       if ((INTVAL (operands[2]) == -128
6133            || (INTVAL (operands[2]) > 0
6134                && INTVAL (operands[2]) != 128)))
6135         return "sub{w}\t{%2, %0|%0, %2}";
6136       operands[2] = GEN_INT (-INTVAL (operands[2]));
6137       return "add{w}\t{%2, %0|%0, %2}";
6138     }
6139 }
6140   [(set (attr "type")
6141      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6142         (const_string "incdec")
6143         (const_string "alu")))
6144    (set_attr "mode" "SI")])
6145
6146
6147 (define_insn "*addhi_5"
6148   [(set (reg FLAGS_REG)
6149         (compare
6150           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6151                    (match_operand:HI 2 "general_operand" "rmni"))
6152           (const_int 0)))                       
6153    (clobber (match_scratch:HI 0 "=r"))]
6154   "ix86_match_ccmode (insn, CCGOCmode)
6155    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6156 {
6157   switch (get_attr_type (insn))
6158     {
6159     case TYPE_INCDEC:
6160       if (operands[2] == const1_rtx)
6161         return "inc{w}\t%0";
6162       else if (operands[2] == constm1_rtx)
6163         return "dec{w}\t%0";
6164       abort();
6165
6166     default:
6167       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6168          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6169       if (GET_CODE (operands[2]) == CONST_INT
6170           && (INTVAL (operands[2]) == 128
6171               || (INTVAL (operands[2]) < 0
6172                   && INTVAL (operands[2]) != -128)))
6173         {
6174           operands[2] = GEN_INT (-INTVAL (operands[2]));
6175           return "sub{w}\t{%2, %0|%0, %2}";
6176         }
6177       return "add{w}\t{%2, %0|%0, %2}";
6178     }
6179 }
6180   [(set (attr "type")
6181      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6182         (const_string "incdec")
6183         (const_string "alu")))
6184    (set_attr "mode" "HI")])
6185
6186 (define_expand "addqi3"
6187   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6188                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6189                             (match_operand:QI 2 "general_operand" "")))
6190               (clobber (reg:CC FLAGS_REG))])]
6191   "TARGET_QIMODE_MATH"
6192   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6193
6194 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6195 (define_insn "*addqi_1_lea"
6196   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6197         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6198                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6199    (clobber (reg:CC FLAGS_REG))]
6200   "!TARGET_PARTIAL_REG_STALL
6201    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6202 {
6203   int widen = (which_alternative == 2);
6204   switch (get_attr_type (insn))
6205     {
6206     case TYPE_LEA:
6207       return "#";
6208     case TYPE_INCDEC:
6209       if (operands[2] == const1_rtx)
6210         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6211       else if (operands[2] == constm1_rtx)
6212         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6213       abort();
6214
6215     default:
6216       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6217          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6218       if (GET_CODE (operands[2]) == CONST_INT
6219           && (INTVAL (operands[2]) == 128
6220               || (INTVAL (operands[2]) < 0
6221                   && INTVAL (operands[2]) != -128)))
6222         {
6223           operands[2] = GEN_INT (-INTVAL (operands[2]));
6224           if (widen)
6225             return "sub{l}\t{%2, %k0|%k0, %2}";
6226           else
6227             return "sub{b}\t{%2, %0|%0, %2}";
6228         }
6229       if (widen)
6230         return "add{l}\t{%k2, %k0|%k0, %k2}";
6231       else
6232         return "add{b}\t{%2, %0|%0, %2}";
6233     }
6234 }
6235   [(set (attr "type")
6236      (if_then_else (eq_attr "alternative" "3")
6237         (const_string "lea")
6238         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6239            (const_string "incdec")
6240            (const_string "alu"))))
6241    (set_attr "mode" "QI,QI,SI,SI")])
6242
6243 (define_insn "*addqi_1"
6244   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6245         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6246                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6247    (clobber (reg:CC FLAGS_REG))]
6248   "TARGET_PARTIAL_REG_STALL
6249    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6250 {
6251   int widen = (which_alternative == 2);
6252   switch (get_attr_type (insn))
6253     {
6254     case TYPE_INCDEC:
6255       if (operands[2] == const1_rtx)
6256         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6257       else if (operands[2] == constm1_rtx)
6258         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6259       abort();
6260
6261     default:
6262       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6263          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6264       if (GET_CODE (operands[2]) == CONST_INT
6265           && (INTVAL (operands[2]) == 128
6266               || (INTVAL (operands[2]) < 0
6267                   && INTVAL (operands[2]) != -128)))
6268         {
6269           operands[2] = GEN_INT (-INTVAL (operands[2]));
6270           if (widen)
6271             return "sub{l}\t{%2, %k0|%k0, %2}";
6272           else
6273             return "sub{b}\t{%2, %0|%0, %2}";
6274         }
6275       if (widen)
6276         return "add{l}\t{%k2, %k0|%k0, %k2}";
6277       else
6278         return "add{b}\t{%2, %0|%0, %2}";
6279     }
6280 }
6281   [(set (attr "type")
6282      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6283         (const_string "incdec")
6284         (const_string "alu")))
6285    (set_attr "mode" "QI,QI,SI")])
6286
6287 (define_insn "*addqi_1_slp"
6288   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6289         (plus:QI (match_dup 0)
6290                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6291    (clobber (reg:CC FLAGS_REG))]
6292   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6293    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6294 {
6295   switch (get_attr_type (insn))
6296     {
6297     case TYPE_INCDEC:
6298       if (operands[1] == const1_rtx)
6299         return "inc{b}\t%0";
6300       else if (operands[1] == constm1_rtx)
6301         return "dec{b}\t%0";
6302       abort();
6303
6304     default:
6305       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6306       if (GET_CODE (operands[1]) == CONST_INT
6307           && INTVAL (operands[1]) < 0)
6308         {
6309           operands[1] = GEN_INT (-INTVAL (operands[1]));
6310           return "sub{b}\t{%1, %0|%0, %1}";
6311         }
6312       return "add{b}\t{%1, %0|%0, %1}";
6313     }
6314 }
6315   [(set (attr "type")
6316      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6317         (const_string "incdec")
6318         (const_string "alu1")))
6319    (set_attr "mode" "QI")])
6320
6321 (define_insn "*addqi_2"
6322   [(set (reg FLAGS_REG)
6323         (compare
6324           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6325                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6326           (const_int 0)))
6327    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6328         (plus:QI (match_dup 1) (match_dup 2)))]
6329   "ix86_match_ccmode (insn, CCGOCmode)
6330    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6331 {
6332   switch (get_attr_type (insn))
6333     {
6334     case TYPE_INCDEC:
6335       if (operands[2] == const1_rtx)
6336         return "inc{b}\t%0";
6337       else if (operands[2] == constm1_rtx
6338                || (GET_CODE (operands[2]) == CONST_INT
6339                    && INTVAL (operands[2]) == 255))
6340         return "dec{b}\t%0";
6341       abort();
6342
6343     default:
6344       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6345       if (GET_CODE (operands[2]) == CONST_INT
6346           && INTVAL (operands[2]) < 0)
6347         {
6348           operands[2] = GEN_INT (-INTVAL (operands[2]));
6349           return "sub{b}\t{%2, %0|%0, %2}";
6350         }
6351       return "add{b}\t{%2, %0|%0, %2}";
6352     }
6353 }
6354   [(set (attr "type")
6355      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6356         (const_string "incdec")
6357         (const_string "alu")))
6358    (set_attr "mode" "QI")])
6359
6360 (define_insn "*addqi_3"
6361   [(set (reg FLAGS_REG)
6362         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6363                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6364    (clobber (match_scratch:QI 0 "=q"))]
6365   "ix86_match_ccmode (insn, CCZmode)
6366    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6367 {
6368   switch (get_attr_type (insn))
6369     {
6370     case TYPE_INCDEC:
6371       if (operands[2] == const1_rtx)
6372         return "inc{b}\t%0";
6373       else if (operands[2] == constm1_rtx
6374                || (GET_CODE (operands[2]) == CONST_INT
6375                    && INTVAL (operands[2]) == 255))
6376         return "dec{b}\t%0";
6377       abort();
6378
6379     default:
6380       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6381       if (GET_CODE (operands[2]) == CONST_INT
6382           && INTVAL (operands[2]) < 0)
6383         {
6384           operands[2] = GEN_INT (-INTVAL (operands[2]));
6385           return "sub{b}\t{%2, %0|%0, %2}";
6386         }
6387       return "add{b}\t{%2, %0|%0, %2}";
6388     }
6389 }
6390   [(set (attr "type")
6391      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6392         (const_string "incdec")
6393         (const_string "alu")))
6394    (set_attr "mode" "QI")])
6395
6396 ; See comments above addsi_3_imm for details.
6397 (define_insn "*addqi_4"
6398   [(set (reg FLAGS_REG)
6399         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6400                  (match_operand:QI 2 "const_int_operand" "n")))
6401    (clobber (match_scratch:QI 0 "=qm"))]
6402   "ix86_match_ccmode (insn, CCGCmode)
6403    && (INTVAL (operands[2]) & 0xff) != 0x80"
6404 {
6405   switch (get_attr_type (insn))
6406     {
6407     case TYPE_INCDEC:
6408       if (operands[2] == constm1_rtx
6409           || (GET_CODE (operands[2]) == CONST_INT
6410               && INTVAL (operands[2]) == 255))
6411         return "inc{b}\t%0";
6412       else if (operands[2] == const1_rtx)
6413         return "dec{b}\t%0";
6414       else
6415         abort();
6416
6417     default:
6418       if (! rtx_equal_p (operands[0], operands[1]))
6419         abort ();
6420       if (INTVAL (operands[2]) < 0)
6421         {
6422           operands[2] = GEN_INT (-INTVAL (operands[2]));
6423           return "add{b}\t{%2, %0|%0, %2}";
6424         }
6425       return "sub{b}\t{%2, %0|%0, %2}";
6426     }
6427 }
6428   [(set (attr "type")
6429      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6430         (const_string "incdec")
6431         (const_string "alu")))
6432    (set_attr "mode" "QI")])
6433
6434
6435 (define_insn "*addqi_5"
6436   [(set (reg FLAGS_REG)
6437         (compare
6438           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6439                    (match_operand:QI 2 "general_operand" "qmni"))
6440           (const_int 0)))
6441    (clobber (match_scratch:QI 0 "=q"))]
6442   "ix86_match_ccmode (insn, CCGOCmode)
6443    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6444 {
6445   switch (get_attr_type (insn))
6446     {
6447     case TYPE_INCDEC:
6448       if (operands[2] == const1_rtx)
6449         return "inc{b}\t%0";
6450       else if (operands[2] == constm1_rtx
6451                || (GET_CODE (operands[2]) == CONST_INT
6452                    && INTVAL (operands[2]) == 255))
6453         return "dec{b}\t%0";
6454       abort();
6455
6456     default:
6457       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6458       if (GET_CODE (operands[2]) == CONST_INT
6459           && INTVAL (operands[2]) < 0)
6460         {
6461           operands[2] = GEN_INT (-INTVAL (operands[2]));
6462           return "sub{b}\t{%2, %0|%0, %2}";
6463         }
6464       return "add{b}\t{%2, %0|%0, %2}";
6465     }
6466 }
6467   [(set (attr "type")
6468      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6469         (const_string "incdec")
6470         (const_string "alu")))
6471    (set_attr "mode" "QI")])
6472
6473
6474 (define_insn "addqi_ext_1"
6475   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6476                          (const_int 8)
6477                          (const_int 8))
6478         (plus:SI
6479           (zero_extract:SI
6480             (match_operand 1 "ext_register_operand" "0")
6481             (const_int 8)
6482             (const_int 8))
6483           (match_operand:QI 2 "general_operand" "Qmn")))
6484    (clobber (reg:CC FLAGS_REG))]
6485   "!TARGET_64BIT"
6486 {
6487   switch (get_attr_type (insn))
6488     {
6489     case TYPE_INCDEC:
6490       if (operands[2] == const1_rtx)
6491         return "inc{b}\t%h0";
6492       else if (operands[2] == constm1_rtx
6493                || (GET_CODE (operands[2]) == CONST_INT
6494                    && INTVAL (operands[2]) == 255))
6495         return "dec{b}\t%h0";
6496       abort();
6497
6498     default:
6499       return "add{b}\t{%2, %h0|%h0, %2}";
6500     }
6501 }
6502   [(set (attr "type")
6503      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6504         (const_string "incdec")
6505         (const_string "alu")))
6506    (set_attr "mode" "QI")])
6507
6508 (define_insn "*addqi_ext_1_rex64"
6509   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6510                          (const_int 8)
6511                          (const_int 8))
6512         (plus:SI
6513           (zero_extract:SI
6514             (match_operand 1 "ext_register_operand" "0")
6515             (const_int 8)
6516             (const_int 8))
6517           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6518    (clobber (reg:CC FLAGS_REG))]
6519   "TARGET_64BIT"
6520 {
6521   switch (get_attr_type (insn))
6522     {
6523     case TYPE_INCDEC:
6524       if (operands[2] == const1_rtx)
6525         return "inc{b}\t%h0";
6526       else if (operands[2] == constm1_rtx
6527                || (GET_CODE (operands[2]) == CONST_INT
6528                    && INTVAL (operands[2]) == 255))
6529         return "dec{b}\t%h0";
6530       abort();
6531
6532     default:
6533       return "add{b}\t{%2, %h0|%h0, %2}";
6534     }
6535 }
6536   [(set (attr "type")
6537      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6538         (const_string "incdec")
6539         (const_string "alu")))
6540    (set_attr "mode" "QI")])
6541
6542 (define_insn "*addqi_ext_2"
6543   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6544                          (const_int 8)
6545                          (const_int 8))
6546         (plus:SI
6547           (zero_extract:SI
6548             (match_operand 1 "ext_register_operand" "%0")
6549             (const_int 8)
6550             (const_int 8))
6551           (zero_extract:SI
6552             (match_operand 2 "ext_register_operand" "Q")
6553             (const_int 8)
6554             (const_int 8))))
6555    (clobber (reg:CC FLAGS_REG))]
6556   ""
6557   "add{b}\t{%h2, %h0|%h0, %h2}"
6558   [(set_attr "type" "alu")
6559    (set_attr "mode" "QI")])
6560
6561 ;; The patterns that match these are at the end of this file.
6562
6563 (define_expand "addxf3"
6564   [(set (match_operand:XF 0 "register_operand" "")
6565         (plus:XF (match_operand:XF 1 "register_operand" "")
6566                  (match_operand:XF 2 "register_operand" "")))]
6567   "TARGET_80387"
6568   "")
6569
6570 (define_expand "adddf3"
6571   [(set (match_operand:DF 0 "register_operand" "")
6572         (plus:DF (match_operand:DF 1 "register_operand" "")
6573                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6574   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6575   "")
6576
6577 (define_expand "addsf3"
6578   [(set (match_operand:SF 0 "register_operand" "")
6579         (plus:SF (match_operand:SF 1 "register_operand" "")
6580                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6581   "TARGET_80387 || TARGET_SSE_MATH"
6582   "")
6583 \f
6584 ;; Subtract instructions
6585
6586 ;; %%% splits for subsidi3
6587
6588 (define_expand "subdi3"
6589   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6590                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6591                              (match_operand:DI 2 "x86_64_general_operand" "")))
6592               (clobber (reg:CC FLAGS_REG))])]
6593   ""
6594   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6595
6596 (define_insn "*subdi3_1"
6597   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6598         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6599                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6600    (clobber (reg:CC FLAGS_REG))]
6601   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6602   "#")
6603
6604 (define_split
6605   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6606         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6607                   (match_operand:DI 2 "general_operand" "")))
6608    (clobber (reg:CC FLAGS_REG))]
6609   "!TARGET_64BIT && reload_completed"
6610   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6611               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6612    (parallel [(set (match_dup 3)
6613                    (minus:SI (match_dup 4)
6614                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6615                                       (match_dup 5))))
6616               (clobber (reg:CC FLAGS_REG))])]
6617   "split_di (operands+0, 1, operands+0, operands+3);
6618    split_di (operands+1, 1, operands+1, operands+4);
6619    split_di (operands+2, 1, operands+2, operands+5);")
6620
6621 (define_insn "subdi3_carry_rex64"
6622   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6623           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6624             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6625                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6626    (clobber (reg:CC FLAGS_REG))]
6627   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6628   "sbb{q}\t{%2, %0|%0, %2}"
6629   [(set_attr "type" "alu")
6630    (set_attr "pent_pair" "pu")
6631    (set_attr "mode" "DI")])
6632
6633 (define_insn "*subdi_1_rex64"
6634   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6635         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6636                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6637    (clobber (reg:CC FLAGS_REG))]
6638   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6639   "sub{q}\t{%2, %0|%0, %2}"
6640   [(set_attr "type" "alu")
6641    (set_attr "mode" "DI")])
6642
6643 (define_insn "*subdi_2_rex64"
6644   [(set (reg FLAGS_REG)
6645         (compare
6646           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6647                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6648           (const_int 0)))
6649    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6650         (minus:DI (match_dup 1) (match_dup 2)))]
6651   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6652    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6653   "sub{q}\t{%2, %0|%0, %2}"
6654   [(set_attr "type" "alu")
6655    (set_attr "mode" "DI")])
6656
6657 (define_insn "*subdi_3_rex63"
6658   [(set (reg FLAGS_REG)
6659         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6660                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6661    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6662         (minus:DI (match_dup 1) (match_dup 2)))]
6663   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6664    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6665   "sub{q}\t{%2, %0|%0, %2}"
6666   [(set_attr "type" "alu")
6667    (set_attr "mode" "DI")])
6668
6669 (define_insn "subqi3_carry"
6670   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6671           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6672             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6673                (match_operand:QI 2 "general_operand" "qi,qm"))))
6674    (clobber (reg:CC FLAGS_REG))]
6675   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6676   "sbb{b}\t{%2, %0|%0, %2}"
6677   [(set_attr "type" "alu")
6678    (set_attr "pent_pair" "pu")
6679    (set_attr "mode" "QI")])
6680
6681 (define_insn "subhi3_carry"
6682   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6683           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6684             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6685                (match_operand:HI 2 "general_operand" "ri,rm"))))
6686    (clobber (reg:CC FLAGS_REG))]
6687   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6688   "sbb{w}\t{%2, %0|%0, %2}"
6689   [(set_attr "type" "alu")
6690    (set_attr "pent_pair" "pu")
6691    (set_attr "mode" "HI")])
6692
6693 (define_insn "subsi3_carry"
6694   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6695           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6696             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6697                (match_operand:SI 2 "general_operand" "ri,rm"))))
6698    (clobber (reg:CC FLAGS_REG))]
6699   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6700   "sbb{l}\t{%2, %0|%0, %2}"
6701   [(set_attr "type" "alu")
6702    (set_attr "pent_pair" "pu")
6703    (set_attr "mode" "SI")])
6704
6705 (define_insn "subsi3_carry_zext"
6706   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6707           (zero_extend:DI
6708             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6709               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6710                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6711    (clobber (reg:CC FLAGS_REG))]
6712   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6713   "sbb{l}\t{%2, %k0|%k0, %2}"
6714   [(set_attr "type" "alu")
6715    (set_attr "pent_pair" "pu")
6716    (set_attr "mode" "SI")])
6717
6718 (define_expand "subsi3"
6719   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6720                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6721                              (match_operand:SI 2 "general_operand" "")))
6722               (clobber (reg:CC FLAGS_REG))])]
6723   ""
6724   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6725
6726 (define_insn "*subsi_1"
6727   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6728         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6729                   (match_operand:SI 2 "general_operand" "ri,rm")))
6730    (clobber (reg:CC FLAGS_REG))]
6731   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6732   "sub{l}\t{%2, %0|%0, %2}"
6733   [(set_attr "type" "alu")
6734    (set_attr "mode" "SI")])
6735
6736 (define_insn "*subsi_1_zext"
6737   [(set (match_operand:DI 0 "register_operand" "=r")
6738         (zero_extend:DI
6739           (minus:SI (match_operand:SI 1 "register_operand" "0")
6740                     (match_operand:SI 2 "general_operand" "rim"))))
6741    (clobber (reg:CC FLAGS_REG))]
6742   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6743   "sub{l}\t{%2, %k0|%k0, %2}"
6744   [(set_attr "type" "alu")
6745    (set_attr "mode" "SI")])
6746
6747 (define_insn "*subsi_2"
6748   [(set (reg FLAGS_REG)
6749         (compare
6750           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6751                     (match_operand:SI 2 "general_operand" "ri,rm"))
6752           (const_int 0)))
6753    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6754         (minus:SI (match_dup 1) (match_dup 2)))]
6755   "ix86_match_ccmode (insn, CCGOCmode)
6756    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6757   "sub{l}\t{%2, %0|%0, %2}"
6758   [(set_attr "type" "alu")
6759    (set_attr "mode" "SI")])
6760
6761 (define_insn "*subsi_2_zext"
6762   [(set (reg FLAGS_REG)
6763         (compare
6764           (minus:SI (match_operand:SI 1 "register_operand" "0")
6765                     (match_operand:SI 2 "general_operand" "rim"))
6766           (const_int 0)))
6767    (set (match_operand:DI 0 "register_operand" "=r")
6768         (zero_extend:DI
6769           (minus:SI (match_dup 1)
6770                     (match_dup 2))))]
6771   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6772    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6773   "sub{l}\t{%2, %k0|%k0, %2}"
6774   [(set_attr "type" "alu")
6775    (set_attr "mode" "SI")])
6776
6777 (define_insn "*subsi_3"
6778   [(set (reg FLAGS_REG)
6779         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6780                  (match_operand:SI 2 "general_operand" "ri,rm")))
6781    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6782         (minus:SI (match_dup 1) (match_dup 2)))]
6783   "ix86_match_ccmode (insn, CCmode)
6784    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6785   "sub{l}\t{%2, %0|%0, %2}"
6786   [(set_attr "type" "alu")
6787    (set_attr "mode" "SI")])
6788
6789 (define_insn "*subsi_3_zext"
6790   [(set (reg FLAGS_REG)
6791         (compare (match_operand:SI 1 "register_operand" "0")
6792                  (match_operand:SI 2 "general_operand" "rim")))
6793    (set (match_operand:DI 0 "register_operand" "=r")
6794         (zero_extend:DI
6795           (minus:SI (match_dup 1)
6796                     (match_dup 2))))]
6797   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6798    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6799   "sub{q}\t{%2, %0|%0, %2}"
6800   [(set_attr "type" "alu")
6801    (set_attr "mode" "DI")])
6802
6803 (define_expand "subhi3"
6804   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6805                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6806                              (match_operand:HI 2 "general_operand" "")))
6807               (clobber (reg:CC FLAGS_REG))])]
6808   "TARGET_HIMODE_MATH"
6809   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6810
6811 (define_insn "*subhi_1"
6812   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6813         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6814                   (match_operand:HI 2 "general_operand" "ri,rm")))
6815    (clobber (reg:CC FLAGS_REG))]
6816   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6817   "sub{w}\t{%2, %0|%0, %2}"
6818   [(set_attr "type" "alu")
6819    (set_attr "mode" "HI")])
6820
6821 (define_insn "*subhi_2"
6822   [(set (reg FLAGS_REG)
6823         (compare
6824           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6825                     (match_operand:HI 2 "general_operand" "ri,rm"))
6826           (const_int 0)))
6827    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6828         (minus:HI (match_dup 1) (match_dup 2)))]
6829   "ix86_match_ccmode (insn, CCGOCmode)
6830    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6831   "sub{w}\t{%2, %0|%0, %2}"
6832   [(set_attr "type" "alu")
6833    (set_attr "mode" "HI")])
6834
6835 (define_insn "*subhi_3"
6836   [(set (reg FLAGS_REG)
6837         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6838                  (match_operand:HI 2 "general_operand" "ri,rm")))
6839    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6840         (minus:HI (match_dup 1) (match_dup 2)))]
6841   "ix86_match_ccmode (insn, CCmode)
6842    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6843   "sub{w}\t{%2, %0|%0, %2}"
6844   [(set_attr "type" "alu")
6845    (set_attr "mode" "HI")])
6846
6847 (define_expand "subqi3"
6848   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6849                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6850                              (match_operand:QI 2 "general_operand" "")))
6851               (clobber (reg:CC FLAGS_REG))])]
6852   "TARGET_QIMODE_MATH"
6853   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6854
6855 (define_insn "*subqi_1"
6856   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6857         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6858                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6859    (clobber (reg:CC FLAGS_REG))]
6860   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6861   "sub{b}\t{%2, %0|%0, %2}"
6862   [(set_attr "type" "alu")
6863    (set_attr "mode" "QI")])
6864
6865 (define_insn "*subqi_1_slp"
6866   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6867         (minus:QI (match_dup 0)
6868                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6869    (clobber (reg:CC FLAGS_REG))]
6870   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6871    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6872   "sub{b}\t{%1, %0|%0, %1}"
6873   [(set_attr "type" "alu1")
6874    (set_attr "mode" "QI")])
6875
6876 (define_insn "*subqi_2"
6877   [(set (reg FLAGS_REG)
6878         (compare
6879           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6880                     (match_operand:QI 2 "general_operand" "qi,qm"))
6881           (const_int 0)))
6882    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6883         (minus:HI (match_dup 1) (match_dup 2)))]
6884   "ix86_match_ccmode (insn, CCGOCmode)
6885    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6886   "sub{b}\t{%2, %0|%0, %2}"
6887   [(set_attr "type" "alu")
6888    (set_attr "mode" "QI")])
6889
6890 (define_insn "*subqi_3"
6891   [(set (reg FLAGS_REG)
6892         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6893                  (match_operand:QI 2 "general_operand" "qi,qm")))
6894    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6895         (minus:HI (match_dup 1) (match_dup 2)))]
6896   "ix86_match_ccmode (insn, CCmode)
6897    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6898   "sub{b}\t{%2, %0|%0, %2}"
6899   [(set_attr "type" "alu")
6900    (set_attr "mode" "QI")])
6901
6902 ;; The patterns that match these are at the end of this file.
6903
6904 (define_expand "subxf3"
6905   [(set (match_operand:XF 0 "register_operand" "")
6906         (minus:XF (match_operand:XF 1 "register_operand" "")
6907                   (match_operand:XF 2 "register_operand" "")))]
6908   "TARGET_80387"
6909   "")
6910
6911 (define_expand "subdf3"
6912   [(set (match_operand:DF 0 "register_operand" "")
6913         (minus:DF (match_operand:DF 1 "register_operand" "")
6914                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6915   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6916   "")
6917
6918 (define_expand "subsf3"
6919   [(set (match_operand:SF 0 "register_operand" "")
6920         (minus:SF (match_operand:SF 1 "register_operand" "")
6921                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6922   "TARGET_80387 || TARGET_SSE_MATH"
6923   "")
6924 \f
6925 ;; Multiply instructions
6926
6927 (define_expand "muldi3"
6928   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6929                    (mult:DI (match_operand:DI 1 "register_operand" "")
6930                             (match_operand:DI 2 "x86_64_general_operand" "")))
6931               (clobber (reg:CC FLAGS_REG))])]
6932   "TARGET_64BIT"
6933   "")
6934
6935 (define_insn "*muldi3_1_rex64"
6936   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6937         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6938                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6939    (clobber (reg:CC FLAGS_REG))]
6940   "TARGET_64BIT
6941    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6942   "@
6943    imul{q}\t{%2, %1, %0|%0, %1, %2}
6944    imul{q}\t{%2, %1, %0|%0, %1, %2}
6945    imul{q}\t{%2, %0|%0, %2}"
6946   [(set_attr "type" "imul")
6947    (set_attr "prefix_0f" "0,0,1")
6948    (set (attr "athlon_decode")
6949         (cond [(eq_attr "cpu" "athlon")
6950                   (const_string "vector")
6951                (eq_attr "alternative" "1")
6952                   (const_string "vector")
6953                (and (eq_attr "alternative" "2")
6954                     (match_operand 1 "memory_operand" ""))
6955                   (const_string "vector")]
6956               (const_string "direct")))
6957    (set_attr "mode" "DI")])
6958
6959 (define_expand "mulsi3"
6960   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6961                    (mult:SI (match_operand:SI 1 "register_operand" "")
6962                             (match_operand:SI 2 "general_operand" "")))
6963               (clobber (reg:CC FLAGS_REG))])]
6964   ""
6965   "")
6966
6967 (define_insn "*mulsi3_1"
6968   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6969         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6970                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6971    (clobber (reg:CC FLAGS_REG))]
6972   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6973   "@
6974    imul{l}\t{%2, %1, %0|%0, %1, %2}
6975    imul{l}\t{%2, %1, %0|%0, %1, %2}
6976    imul{l}\t{%2, %0|%0, %2}"
6977   [(set_attr "type" "imul")
6978    (set_attr "prefix_0f" "0,0,1")
6979    (set (attr "athlon_decode")
6980         (cond [(eq_attr "cpu" "athlon")
6981                   (const_string "vector")
6982                (eq_attr "alternative" "1")
6983                   (const_string "vector")
6984                (and (eq_attr "alternative" "2")
6985                     (match_operand 1 "memory_operand" ""))
6986                   (const_string "vector")]
6987               (const_string "direct")))
6988    (set_attr "mode" "SI")])
6989
6990 (define_insn "*mulsi3_1_zext"
6991   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6992         (zero_extend:DI
6993           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6994                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6995    (clobber (reg:CC FLAGS_REG))]
6996   "TARGET_64BIT
6997    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6998   "@
6999    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7000    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7001    imul{l}\t{%2, %k0|%k0, %2}"
7002   [(set_attr "type" "imul")
7003    (set_attr "prefix_0f" "0,0,1")
7004    (set (attr "athlon_decode")
7005         (cond [(eq_attr "cpu" "athlon")
7006                   (const_string "vector")
7007                (eq_attr "alternative" "1")
7008                   (const_string "vector")
7009                (and (eq_attr "alternative" "2")
7010                     (match_operand 1 "memory_operand" ""))
7011                   (const_string "vector")]
7012               (const_string "direct")))
7013    (set_attr "mode" "SI")])
7014
7015 (define_expand "mulhi3"
7016   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7017                    (mult:HI (match_operand:HI 1 "register_operand" "")
7018                             (match_operand:HI 2 "general_operand" "")))
7019               (clobber (reg:CC FLAGS_REG))])]
7020   "TARGET_HIMODE_MATH"
7021   "")
7022
7023 (define_insn "*mulhi3_1"
7024   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7025         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7026                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7027    (clobber (reg:CC FLAGS_REG))]
7028   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7029   "@
7030    imul{w}\t{%2, %1, %0|%0, %1, %2}
7031    imul{w}\t{%2, %1, %0|%0, %1, %2}
7032    imul{w}\t{%2, %0|%0, %2}"
7033   [(set_attr "type" "imul")
7034    (set_attr "prefix_0f" "0,0,1")
7035    (set (attr "athlon_decode")
7036         (cond [(eq_attr "cpu" "athlon")
7037                   (const_string "vector")
7038                (eq_attr "alternative" "1,2")
7039                   (const_string "vector")]
7040               (const_string "direct")))
7041    (set_attr "mode" "HI")])
7042
7043 (define_expand "mulqi3"
7044   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7045                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7046                             (match_operand:QI 2 "register_operand" "")))
7047               (clobber (reg:CC FLAGS_REG))])]
7048   "TARGET_QIMODE_MATH"
7049   "")
7050
7051 (define_insn "*mulqi3_1"
7052   [(set (match_operand:QI 0 "register_operand" "=a")
7053         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7054                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7055    (clobber (reg:CC FLAGS_REG))]
7056   "TARGET_QIMODE_MATH
7057    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7058   "mul{b}\t%2"
7059   [(set_attr "type" "imul")
7060    (set_attr "length_immediate" "0")
7061    (set (attr "athlon_decode")
7062      (if_then_else (eq_attr "cpu" "athlon")
7063         (const_string "vector")
7064         (const_string "direct")))
7065    (set_attr "mode" "QI")])
7066
7067 (define_expand "umulqihi3"
7068   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7069                    (mult:HI (zero_extend:HI
7070                               (match_operand:QI 1 "nonimmediate_operand" ""))
7071                             (zero_extend:HI
7072                               (match_operand:QI 2 "register_operand" ""))))
7073               (clobber (reg:CC FLAGS_REG))])]
7074   "TARGET_QIMODE_MATH"
7075   "")
7076
7077 (define_insn "*umulqihi3_1"
7078   [(set (match_operand:HI 0 "register_operand" "=a")
7079         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7080                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7081    (clobber (reg:CC FLAGS_REG))]
7082   "TARGET_QIMODE_MATH
7083    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7084   "mul{b}\t%2"
7085   [(set_attr "type" "imul")
7086    (set_attr "length_immediate" "0")
7087    (set (attr "athlon_decode")
7088      (if_then_else (eq_attr "cpu" "athlon")
7089         (const_string "vector")
7090         (const_string "direct")))
7091    (set_attr "mode" "QI")])
7092
7093 (define_expand "mulqihi3"
7094   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7095                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7096                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7097               (clobber (reg:CC FLAGS_REG))])]
7098   "TARGET_QIMODE_MATH"
7099   "")
7100
7101 (define_insn "*mulqihi3_insn"
7102   [(set (match_operand:HI 0 "register_operand" "=a")
7103         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7104                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7105    (clobber (reg:CC FLAGS_REG))]
7106   "TARGET_QIMODE_MATH
7107    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7108   "imul{b}\t%2"
7109   [(set_attr "type" "imul")
7110    (set_attr "length_immediate" "0")
7111    (set (attr "athlon_decode")
7112      (if_then_else (eq_attr "cpu" "athlon")
7113         (const_string "vector")
7114         (const_string "direct")))
7115    (set_attr "mode" "QI")])
7116
7117 (define_expand "umulditi3"
7118   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7119                    (mult:TI (zero_extend:TI
7120                               (match_operand:DI 1 "nonimmediate_operand" ""))
7121                             (zero_extend:TI
7122                               (match_operand:DI 2 "register_operand" ""))))
7123               (clobber (reg:CC FLAGS_REG))])]
7124   "TARGET_64BIT"
7125   "")
7126
7127 (define_insn "*umulditi3_insn"
7128   [(set (match_operand:TI 0 "register_operand" "=A")
7129         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7130                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7131    (clobber (reg:CC FLAGS_REG))]
7132   "TARGET_64BIT
7133    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7134   "mul{q}\t%2"
7135   [(set_attr "type" "imul")
7136    (set_attr "length_immediate" "0")
7137    (set (attr "athlon_decode")
7138      (if_then_else (eq_attr "cpu" "athlon")
7139         (const_string "vector")
7140         (const_string "double")))
7141    (set_attr "mode" "DI")])
7142
7143 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7144 (define_expand "umulsidi3"
7145   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7146                    (mult:DI (zero_extend:DI
7147                               (match_operand:SI 1 "nonimmediate_operand" ""))
7148                             (zero_extend:DI
7149                               (match_operand:SI 2 "register_operand" ""))))
7150               (clobber (reg:CC FLAGS_REG))])]
7151   "!TARGET_64BIT"
7152   "")
7153
7154 (define_insn "*umulsidi3_insn"
7155   [(set (match_operand:DI 0 "register_operand" "=A")
7156         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7157                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7158    (clobber (reg:CC FLAGS_REG))]
7159   "!TARGET_64BIT
7160    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7161   "mul{l}\t%2"
7162   [(set_attr "type" "imul")
7163    (set_attr "length_immediate" "0")
7164    (set (attr "athlon_decode")
7165      (if_then_else (eq_attr "cpu" "athlon")
7166         (const_string "vector")
7167         (const_string "double")))
7168    (set_attr "mode" "SI")])
7169
7170 (define_expand "mulditi3"
7171   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7172                    (mult:TI (sign_extend:TI
7173                               (match_operand:DI 1 "nonimmediate_operand" ""))
7174                             (sign_extend:TI
7175                               (match_operand:DI 2 "register_operand" ""))))
7176               (clobber (reg:CC FLAGS_REG))])]
7177   "TARGET_64BIT"
7178   "")
7179
7180 (define_insn "*mulditi3_insn"
7181   [(set (match_operand:TI 0 "register_operand" "=A")
7182         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7183                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7184    (clobber (reg:CC FLAGS_REG))]
7185   "TARGET_64BIT
7186    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7187   "imul{q}\t%2"
7188   [(set_attr "type" "imul")
7189    (set_attr "length_immediate" "0")
7190    (set (attr "athlon_decode")
7191      (if_then_else (eq_attr "cpu" "athlon")
7192         (const_string "vector")
7193         (const_string "double")))
7194    (set_attr "mode" "DI")])
7195
7196 (define_expand "mulsidi3"
7197   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7198                    (mult:DI (sign_extend:DI
7199                               (match_operand:SI 1 "nonimmediate_operand" ""))
7200                             (sign_extend:DI
7201                               (match_operand:SI 2 "register_operand" ""))))
7202               (clobber (reg:CC FLAGS_REG))])]
7203   "!TARGET_64BIT"
7204   "")
7205
7206 (define_insn "*mulsidi3_insn"
7207   [(set (match_operand:DI 0 "register_operand" "=A")
7208         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7209                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7210    (clobber (reg:CC FLAGS_REG))]
7211   "!TARGET_64BIT
7212    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7213   "imul{l}\t%2"
7214   [(set_attr "type" "imul")
7215    (set_attr "length_immediate" "0")
7216    (set (attr "athlon_decode")
7217      (if_then_else (eq_attr "cpu" "athlon")
7218         (const_string "vector")
7219         (const_string "double")))
7220    (set_attr "mode" "SI")])
7221
7222 (define_expand "umuldi3_highpart"
7223   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7224                    (truncate:DI
7225                      (lshiftrt:TI
7226                        (mult:TI (zero_extend:TI
7227                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7228                                 (zero_extend:TI
7229                                   (match_operand:DI 2 "register_operand" "")))
7230                        (const_int 64))))
7231               (clobber (match_scratch:DI 3 ""))
7232               (clobber (reg:CC FLAGS_REG))])]
7233   "TARGET_64BIT"
7234   "")
7235
7236 (define_insn "*umuldi3_highpart_rex64"
7237   [(set (match_operand:DI 0 "register_operand" "=d")
7238         (truncate:DI
7239           (lshiftrt:TI
7240             (mult:TI (zero_extend:TI
7241                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7242                      (zero_extend:TI
7243                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7244             (const_int 64))))
7245    (clobber (match_scratch:DI 3 "=1"))
7246    (clobber (reg:CC FLAGS_REG))]
7247   "TARGET_64BIT
7248    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7249   "mul{q}\t%2"
7250   [(set_attr "type" "imul")
7251    (set_attr "length_immediate" "0")
7252    (set (attr "athlon_decode")
7253      (if_then_else (eq_attr "cpu" "athlon")
7254         (const_string "vector")
7255         (const_string "double")))
7256    (set_attr "mode" "DI")])
7257
7258 (define_expand "umulsi3_highpart"
7259   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7260                    (truncate:SI
7261                      (lshiftrt:DI
7262                        (mult:DI (zero_extend:DI
7263                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7264                                 (zero_extend:DI
7265                                   (match_operand:SI 2 "register_operand" "")))
7266                        (const_int 32))))
7267               (clobber (match_scratch:SI 3 ""))
7268               (clobber (reg:CC FLAGS_REG))])]
7269   ""
7270   "")
7271
7272 (define_insn "*umulsi3_highpart_insn"
7273   [(set (match_operand:SI 0 "register_operand" "=d")
7274         (truncate:SI
7275           (lshiftrt:DI
7276             (mult:DI (zero_extend:DI
7277                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7278                      (zero_extend:DI
7279                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7280             (const_int 32))))
7281    (clobber (match_scratch:SI 3 "=1"))
7282    (clobber (reg:CC FLAGS_REG))]
7283   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7284   "mul{l}\t%2"
7285   [(set_attr "type" "imul")
7286    (set_attr "length_immediate" "0")
7287    (set (attr "athlon_decode")
7288      (if_then_else (eq_attr "cpu" "athlon")
7289         (const_string "vector")
7290         (const_string "double")))
7291    (set_attr "mode" "SI")])
7292
7293 (define_insn "*umulsi3_highpart_zext"
7294   [(set (match_operand:DI 0 "register_operand" "=d")
7295         (zero_extend:DI (truncate:SI
7296           (lshiftrt:DI
7297             (mult:DI (zero_extend:DI
7298                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7299                      (zero_extend:DI
7300                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7301             (const_int 32)))))
7302    (clobber (match_scratch:SI 3 "=1"))
7303    (clobber (reg:CC FLAGS_REG))]
7304   "TARGET_64BIT
7305    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7306   "mul{l}\t%2"
7307   [(set_attr "type" "imul")
7308    (set_attr "length_immediate" "0")
7309    (set (attr "athlon_decode")
7310      (if_then_else (eq_attr "cpu" "athlon")
7311         (const_string "vector")
7312         (const_string "double")))
7313    (set_attr "mode" "SI")])
7314
7315 (define_expand "smuldi3_highpart"
7316   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7317                    (truncate:DI
7318                      (lshiftrt:TI
7319                        (mult:TI (sign_extend:TI
7320                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7321                                 (sign_extend:TI
7322                                   (match_operand:DI 2 "register_operand" "")))
7323                        (const_int 64))))
7324               (clobber (match_scratch:DI 3 ""))
7325               (clobber (reg:CC FLAGS_REG))])]
7326   "TARGET_64BIT"
7327   "")
7328
7329 (define_insn "*smuldi3_highpart_rex64"
7330   [(set (match_operand:DI 0 "register_operand" "=d")
7331         (truncate:DI
7332           (lshiftrt:TI
7333             (mult:TI (sign_extend:TI
7334                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7335                      (sign_extend:TI
7336                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7337             (const_int 64))))
7338    (clobber (match_scratch:DI 3 "=1"))
7339    (clobber (reg:CC FLAGS_REG))]
7340   "TARGET_64BIT
7341    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7342   "imul{q}\t%2"
7343   [(set_attr "type" "imul")
7344    (set (attr "athlon_decode")
7345      (if_then_else (eq_attr "cpu" "athlon")
7346         (const_string "vector")
7347         (const_string "double")))
7348    (set_attr "mode" "DI")])
7349
7350 (define_expand "smulsi3_highpart"
7351   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7352                    (truncate:SI
7353                      (lshiftrt:DI
7354                        (mult:DI (sign_extend:DI
7355                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7356                                 (sign_extend:DI
7357                                   (match_operand:SI 2 "register_operand" "")))
7358                        (const_int 32))))
7359               (clobber (match_scratch:SI 3 ""))
7360               (clobber (reg:CC FLAGS_REG))])]
7361   ""
7362   "")
7363
7364 (define_insn "*smulsi3_highpart_insn"
7365   [(set (match_operand:SI 0 "register_operand" "=d")
7366         (truncate:SI
7367           (lshiftrt:DI
7368             (mult:DI (sign_extend:DI
7369                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7370                      (sign_extend:DI
7371                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7372             (const_int 32))))
7373    (clobber (match_scratch:SI 3 "=1"))
7374    (clobber (reg:CC FLAGS_REG))]
7375   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7376   "imul{l}\t%2"
7377   [(set_attr "type" "imul")
7378    (set (attr "athlon_decode")
7379      (if_then_else (eq_attr "cpu" "athlon")
7380         (const_string "vector")
7381         (const_string "double")))
7382    (set_attr "mode" "SI")])
7383
7384 (define_insn "*smulsi3_highpart_zext"
7385   [(set (match_operand:DI 0 "register_operand" "=d")
7386         (zero_extend:DI (truncate:SI
7387           (lshiftrt:DI
7388             (mult:DI (sign_extend:DI
7389                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7390                      (sign_extend:DI
7391                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7392             (const_int 32)))))
7393    (clobber (match_scratch:SI 3 "=1"))
7394    (clobber (reg:CC FLAGS_REG))]
7395   "TARGET_64BIT
7396    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7397   "imul{l}\t%2"
7398   [(set_attr "type" "imul")
7399    (set (attr "athlon_decode")
7400      (if_then_else (eq_attr "cpu" "athlon")
7401         (const_string "vector")
7402         (const_string "double")))
7403    (set_attr "mode" "SI")])
7404
7405 ;; The patterns that match these are at the end of this file.
7406
7407 (define_expand "mulxf3"
7408   [(set (match_operand:XF 0 "register_operand" "")
7409         (mult:XF (match_operand:XF 1 "register_operand" "")
7410                  (match_operand:XF 2 "register_operand" "")))]
7411   "TARGET_80387"
7412   "")
7413
7414 (define_expand "muldf3"
7415   [(set (match_operand:DF 0 "register_operand" "")
7416         (mult:DF (match_operand:DF 1 "register_operand" "")
7417                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7418   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7419   "")
7420
7421 (define_expand "mulsf3"
7422   [(set (match_operand:SF 0 "register_operand" "")
7423         (mult:SF (match_operand:SF 1 "register_operand" "")
7424                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7425   "TARGET_80387 || TARGET_SSE_MATH"
7426   "")
7427 \f
7428 ;; Divide instructions
7429
7430 (define_insn "divqi3"
7431   [(set (match_operand:QI 0 "register_operand" "=a")
7432         (div:QI (match_operand:HI 1 "register_operand" "0")
7433                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7434    (clobber (reg:CC FLAGS_REG))]
7435   "TARGET_QIMODE_MATH"
7436   "idiv{b}\t%2"
7437   [(set_attr "type" "idiv")
7438    (set_attr "mode" "QI")])
7439
7440 (define_insn "udivqi3"
7441   [(set (match_operand:QI 0 "register_operand" "=a")
7442         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7443                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7444    (clobber (reg:CC FLAGS_REG))]
7445   "TARGET_QIMODE_MATH"
7446   "div{b}\t%2"
7447   [(set_attr "type" "idiv")
7448    (set_attr "mode" "QI")])
7449
7450 ;; The patterns that match these are at the end of this file.
7451
7452 (define_expand "divxf3"
7453   [(set (match_operand:XF 0 "register_operand" "")
7454         (div:XF (match_operand:XF 1 "register_operand" "")
7455                 (match_operand:XF 2 "register_operand" "")))]
7456   "TARGET_80387"
7457   "")
7458
7459 (define_expand "divdf3"
7460   [(set (match_operand:DF 0 "register_operand" "")
7461         (div:DF (match_operand:DF 1 "register_operand" "")
7462                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7463    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7464    "")
7465  
7466 (define_expand "divsf3"
7467   [(set (match_operand:SF 0 "register_operand" "")
7468         (div:SF (match_operand:SF 1 "register_operand" "")
7469                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7470   "TARGET_80387 || TARGET_SSE_MATH"
7471   "")
7472 \f
7473 ;; Remainder instructions.
7474
7475 (define_expand "divmoddi4"
7476   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7477                    (div:DI (match_operand:DI 1 "register_operand" "")
7478                            (match_operand:DI 2 "nonimmediate_operand" "")))
7479               (set (match_operand:DI 3 "register_operand" "")
7480                    (mod:DI (match_dup 1) (match_dup 2)))
7481               (clobber (reg:CC FLAGS_REG))])]
7482   "TARGET_64BIT"
7483   "")
7484
7485 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7486 ;; Penalize eax case slightly because it results in worse scheduling
7487 ;; of code.
7488 (define_insn "*divmoddi4_nocltd_rex64"
7489   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7490         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7491                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7492    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7493         (mod:DI (match_dup 2) (match_dup 3)))
7494    (clobber (reg:CC FLAGS_REG))]
7495   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7496   "#"
7497   [(set_attr "type" "multi")])
7498
7499 (define_insn "*divmoddi4_cltd_rex64"
7500   [(set (match_operand:DI 0 "register_operand" "=a")
7501         (div:DI (match_operand:DI 2 "register_operand" "a")
7502                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7503    (set (match_operand:DI 1 "register_operand" "=&d")
7504         (mod:DI (match_dup 2) (match_dup 3)))
7505    (clobber (reg:CC FLAGS_REG))]
7506   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7507   "#"
7508   [(set_attr "type" "multi")])
7509
7510 (define_insn "*divmoddi_noext_rex64"
7511   [(set (match_operand:DI 0 "register_operand" "=a")
7512         (div:DI (match_operand:DI 1 "register_operand" "0")
7513                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7514    (set (match_operand:DI 3 "register_operand" "=d")
7515         (mod:DI (match_dup 1) (match_dup 2)))
7516    (use (match_operand:DI 4 "register_operand" "3"))
7517    (clobber (reg:CC FLAGS_REG))]
7518   "TARGET_64BIT"
7519   "idiv{q}\t%2"
7520   [(set_attr "type" "idiv")
7521    (set_attr "mode" "DI")])
7522
7523 (define_split
7524   [(set (match_operand:DI 0 "register_operand" "")
7525         (div:DI (match_operand:DI 1 "register_operand" "")
7526                 (match_operand:DI 2 "nonimmediate_operand" "")))
7527    (set (match_operand:DI 3 "register_operand" "")
7528         (mod:DI (match_dup 1) (match_dup 2)))
7529    (clobber (reg:CC FLAGS_REG))]
7530   "TARGET_64BIT && reload_completed"
7531   [(parallel [(set (match_dup 3)
7532                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7533               (clobber (reg:CC FLAGS_REG))])
7534    (parallel [(set (match_dup 0)
7535                    (div:DI (reg:DI 0) (match_dup 2)))
7536               (set (match_dup 3)
7537                    (mod:DI (reg:DI 0) (match_dup 2)))
7538               (use (match_dup 3))
7539               (clobber (reg:CC FLAGS_REG))])]
7540 {
7541   /* Avoid use of cltd in favor of a mov+shift.  */
7542   if (!TARGET_USE_CLTD && !optimize_size)
7543     {
7544       if (true_regnum (operands[1]))
7545         emit_move_insn (operands[0], operands[1]);
7546       else
7547         emit_move_insn (operands[3], operands[1]);
7548       operands[4] = operands[3];
7549     }
7550   else
7551     {
7552       if (true_regnum (operands[1]))
7553         abort();
7554       operands[4] = operands[1];
7555     }
7556 })
7557
7558
7559 (define_expand "divmodsi4"
7560   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7561                    (div:SI (match_operand:SI 1 "register_operand" "")
7562                            (match_operand:SI 2 "nonimmediate_operand" "")))
7563               (set (match_operand:SI 3 "register_operand" "")
7564                    (mod:SI (match_dup 1) (match_dup 2)))
7565               (clobber (reg:CC FLAGS_REG))])]
7566   ""
7567   "")
7568
7569 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7570 ;; Penalize eax case slightly because it results in worse scheduling
7571 ;; of code.
7572 (define_insn "*divmodsi4_nocltd"
7573   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7574         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7575                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7576    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7577         (mod:SI (match_dup 2) (match_dup 3)))
7578    (clobber (reg:CC FLAGS_REG))]
7579   "!optimize_size && !TARGET_USE_CLTD"
7580   "#"
7581   [(set_attr "type" "multi")])
7582
7583 (define_insn "*divmodsi4_cltd"
7584   [(set (match_operand:SI 0 "register_operand" "=a")
7585         (div:SI (match_operand:SI 2 "register_operand" "a")
7586                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7587    (set (match_operand:SI 1 "register_operand" "=&d")
7588         (mod:SI (match_dup 2) (match_dup 3)))
7589    (clobber (reg:CC FLAGS_REG))]
7590   "optimize_size || TARGET_USE_CLTD"
7591   "#"
7592   [(set_attr "type" "multi")])
7593
7594 (define_insn "*divmodsi_noext"
7595   [(set (match_operand:SI 0 "register_operand" "=a")
7596         (div:SI (match_operand:SI 1 "register_operand" "0")
7597                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7598    (set (match_operand:SI 3 "register_operand" "=d")
7599         (mod:SI (match_dup 1) (match_dup 2)))
7600    (use (match_operand:SI 4 "register_operand" "3"))
7601    (clobber (reg:CC FLAGS_REG))]
7602   ""
7603   "idiv{l}\t%2"
7604   [(set_attr "type" "idiv")
7605    (set_attr "mode" "SI")])
7606
7607 (define_split
7608   [(set (match_operand:SI 0 "register_operand" "")
7609         (div:SI (match_operand:SI 1 "register_operand" "")
7610                 (match_operand:SI 2 "nonimmediate_operand" "")))
7611    (set (match_operand:SI 3 "register_operand" "")
7612         (mod:SI (match_dup 1) (match_dup 2)))
7613    (clobber (reg:CC FLAGS_REG))]
7614   "reload_completed"
7615   [(parallel [(set (match_dup 3)
7616                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7617               (clobber (reg:CC FLAGS_REG))])
7618    (parallel [(set (match_dup 0)
7619                    (div:SI (reg:SI 0) (match_dup 2)))
7620               (set (match_dup 3)
7621                    (mod:SI (reg:SI 0) (match_dup 2)))
7622               (use (match_dup 3))
7623               (clobber (reg:CC FLAGS_REG))])]
7624 {
7625   /* Avoid use of cltd in favor of a mov+shift.  */
7626   if (!TARGET_USE_CLTD && !optimize_size)
7627     {
7628       if (true_regnum (operands[1]))
7629         emit_move_insn (operands[0], operands[1]);
7630       else
7631         emit_move_insn (operands[3], operands[1]);
7632       operands[4] = operands[3];
7633     }
7634   else
7635     {
7636       if (true_regnum (operands[1]))
7637         abort();
7638       operands[4] = operands[1];
7639     }
7640 })
7641 ;; %%% Split me.
7642 (define_insn "divmodhi4"
7643   [(set (match_operand:HI 0 "register_operand" "=a")
7644         (div:HI (match_operand:HI 1 "register_operand" "0")
7645                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7646    (set (match_operand:HI 3 "register_operand" "=&d")
7647         (mod:HI (match_dup 1) (match_dup 2)))
7648    (clobber (reg:CC FLAGS_REG))]
7649   "TARGET_HIMODE_MATH"
7650   "cwtd\;idiv{w}\t%2"
7651   [(set_attr "type" "multi")
7652    (set_attr "length_immediate" "0")
7653    (set_attr "mode" "SI")])
7654
7655 (define_insn "udivmoddi4"
7656   [(set (match_operand:DI 0 "register_operand" "=a")
7657         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7658                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7659    (set (match_operand:DI 3 "register_operand" "=&d")
7660         (umod:DI (match_dup 1) (match_dup 2)))
7661    (clobber (reg:CC FLAGS_REG))]
7662   "TARGET_64BIT"
7663   "xor{q}\t%3, %3\;div{q}\t%2"
7664   [(set_attr "type" "multi")
7665    (set_attr "length_immediate" "0")
7666    (set_attr "mode" "DI")])
7667
7668 (define_insn "*udivmoddi4_noext"
7669   [(set (match_operand:DI 0 "register_operand" "=a")
7670         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7671                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7672    (set (match_operand:DI 3 "register_operand" "=d")
7673         (umod:DI (match_dup 1) (match_dup 2)))
7674    (use (match_dup 3))
7675    (clobber (reg:CC FLAGS_REG))]
7676   "TARGET_64BIT"
7677   "div{q}\t%2"
7678   [(set_attr "type" "idiv")
7679    (set_attr "mode" "DI")])
7680
7681 (define_split
7682   [(set (match_operand:DI 0 "register_operand" "")
7683         (udiv:DI (match_operand:DI 1 "register_operand" "")
7684                  (match_operand:DI 2 "nonimmediate_operand" "")))
7685    (set (match_operand:DI 3 "register_operand" "")
7686         (umod:DI (match_dup 1) (match_dup 2)))
7687    (clobber (reg:CC FLAGS_REG))]
7688   "TARGET_64BIT && reload_completed"
7689   [(set (match_dup 3) (const_int 0))
7690    (parallel [(set (match_dup 0)
7691                    (udiv:DI (match_dup 1) (match_dup 2)))
7692               (set (match_dup 3)
7693                    (umod:DI (match_dup 1) (match_dup 2)))
7694               (use (match_dup 3))
7695               (clobber (reg:CC FLAGS_REG))])]
7696   "")
7697
7698 (define_insn "udivmodsi4"
7699   [(set (match_operand:SI 0 "register_operand" "=a")
7700         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7701                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7702    (set (match_operand:SI 3 "register_operand" "=&d")
7703         (umod:SI (match_dup 1) (match_dup 2)))
7704    (clobber (reg:CC FLAGS_REG))]
7705   ""
7706   "xor{l}\t%3, %3\;div{l}\t%2"
7707   [(set_attr "type" "multi")
7708    (set_attr "length_immediate" "0")
7709    (set_attr "mode" "SI")])
7710
7711 (define_insn "*udivmodsi4_noext"
7712   [(set (match_operand:SI 0 "register_operand" "=a")
7713         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7714                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7715    (set (match_operand:SI 3 "register_operand" "=d")
7716         (umod:SI (match_dup 1) (match_dup 2)))
7717    (use (match_dup 3))
7718    (clobber (reg:CC FLAGS_REG))]
7719   ""
7720   "div{l}\t%2"
7721   [(set_attr "type" "idiv")
7722    (set_attr "mode" "SI")])
7723
7724 (define_split
7725   [(set (match_operand:SI 0 "register_operand" "")
7726         (udiv:SI (match_operand:SI 1 "register_operand" "")
7727                  (match_operand:SI 2 "nonimmediate_operand" "")))
7728    (set (match_operand:SI 3 "register_operand" "")
7729         (umod:SI (match_dup 1) (match_dup 2)))
7730    (clobber (reg:CC FLAGS_REG))]
7731   "reload_completed"
7732   [(set (match_dup 3) (const_int 0))
7733    (parallel [(set (match_dup 0)
7734                    (udiv:SI (match_dup 1) (match_dup 2)))
7735               (set (match_dup 3)
7736                    (umod:SI (match_dup 1) (match_dup 2)))
7737               (use (match_dup 3))
7738               (clobber (reg:CC FLAGS_REG))])]
7739   "")
7740
7741 (define_expand "udivmodhi4"
7742   [(set (match_dup 4) (const_int 0))
7743    (parallel [(set (match_operand:HI 0 "register_operand" "")
7744                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7745                             (match_operand:HI 2 "nonimmediate_operand" "")))
7746               (set (match_operand:HI 3 "register_operand" "")
7747                    (umod:HI (match_dup 1) (match_dup 2)))
7748               (use (match_dup 4))
7749               (clobber (reg:CC FLAGS_REG))])]
7750   "TARGET_HIMODE_MATH"
7751   "operands[4] = gen_reg_rtx (HImode);")
7752
7753 (define_insn "*udivmodhi_noext"
7754   [(set (match_operand:HI 0 "register_operand" "=a")
7755         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7756                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7757    (set (match_operand:HI 3 "register_operand" "=d")
7758         (umod:HI (match_dup 1) (match_dup 2)))
7759    (use (match_operand:HI 4 "register_operand" "3"))
7760    (clobber (reg:CC FLAGS_REG))]
7761   ""
7762   "div{w}\t%2"
7763   [(set_attr "type" "idiv")
7764    (set_attr "mode" "HI")])
7765
7766 ;; We cannot use div/idiv for double division, because it causes
7767 ;; "division by zero" on the overflow and that's not what we expect
7768 ;; from truncate.  Because true (non truncating) double division is
7769 ;; never generated, we can't create this insn anyway.
7770 ;
7771 ;(define_insn ""
7772 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7773 ;       (truncate:SI
7774 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7775 ;                  (zero_extend:DI
7776 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7777 ;   (set (match_operand:SI 3 "register_operand" "=d")
7778 ;       (truncate:SI
7779 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7780 ;   (clobber (reg:CC FLAGS_REG))]
7781 ;  ""
7782 ;  "div{l}\t{%2, %0|%0, %2}"
7783 ;  [(set_attr "type" "idiv")])
7784 \f
7785 ;;- Logical AND instructions
7786
7787 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7788 ;; Note that this excludes ah.
7789
7790 (define_insn "*testdi_1_rex64"
7791   [(set (reg FLAGS_REG)
7792         (compare
7793           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7794                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7795           (const_int 0)))]
7796   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7797    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7798   "@
7799    test{l}\t{%k1, %k0|%k0, %k1}
7800    test{l}\t{%k1, %k0|%k0, %k1}
7801    test{q}\t{%1, %0|%0, %1}
7802    test{q}\t{%1, %0|%0, %1}
7803    test{q}\t{%1, %0|%0, %1}"
7804   [(set_attr "type" "test")
7805    (set_attr "modrm" "0,1,0,1,1")
7806    (set_attr "mode" "SI,SI,DI,DI,DI")
7807    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7808
7809 (define_insn "testsi_1"
7810   [(set (reg FLAGS_REG)
7811         (compare
7812           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7813                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7814           (const_int 0)))]
7815   "ix86_match_ccmode (insn, CCNOmode)
7816    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7817   "test{l}\t{%1, %0|%0, %1}"
7818   [(set_attr "type" "test")
7819    (set_attr "modrm" "0,1,1")
7820    (set_attr "mode" "SI")
7821    (set_attr "pent_pair" "uv,np,uv")])
7822
7823 (define_expand "testsi_ccno_1"
7824   [(set (reg:CCNO FLAGS_REG)
7825         (compare:CCNO
7826           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7827                   (match_operand:SI 1 "nonmemory_operand" ""))
7828           (const_int 0)))]
7829   ""
7830   "")
7831
7832 (define_insn "*testhi_1"
7833   [(set (reg FLAGS_REG)
7834         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7835                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7836                  (const_int 0)))]
7837   "ix86_match_ccmode (insn, CCNOmode)
7838    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7839   "test{w}\t{%1, %0|%0, %1}"
7840   [(set_attr "type" "test")
7841    (set_attr "modrm" "0,1,1")
7842    (set_attr "mode" "HI")
7843    (set_attr "pent_pair" "uv,np,uv")])
7844
7845 (define_expand "testqi_ccz_1"
7846   [(set (reg:CCZ FLAGS_REG)
7847         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7848                              (match_operand:QI 1 "nonmemory_operand" ""))
7849                  (const_int 0)))]
7850   ""
7851   "")
7852
7853 (define_insn "*testqi_1_maybe_si"
7854   [(set (reg FLAGS_REG)
7855         (compare
7856           (and:QI
7857             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7858             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7859           (const_int 0)))]
7860    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7861     && ix86_match_ccmode (insn,
7862                          GET_CODE (operands[1]) == CONST_INT
7863                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7864 {
7865   if (which_alternative == 3)
7866     {
7867       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7868         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7869       return "test{l}\t{%1, %k0|%k0, %1}";
7870     }
7871   return "test{b}\t{%1, %0|%0, %1}";
7872 }
7873   [(set_attr "type" "test")
7874    (set_attr "modrm" "0,1,1,1")
7875    (set_attr "mode" "QI,QI,QI,SI")
7876    (set_attr "pent_pair" "uv,np,uv,np")])
7877
7878 (define_insn "*testqi_1"
7879   [(set (reg FLAGS_REG)
7880         (compare
7881           (and:QI
7882             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7883             (match_operand:QI 1 "general_operand" "n,n,qn"))
7884           (const_int 0)))]
7885   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7886    && ix86_match_ccmode (insn, CCNOmode)"
7887   "test{b}\t{%1, %0|%0, %1}"
7888   [(set_attr "type" "test")
7889    (set_attr "modrm" "0,1,1")
7890    (set_attr "mode" "QI")
7891    (set_attr "pent_pair" "uv,np,uv")])
7892
7893 (define_expand "testqi_ext_ccno_0"
7894   [(set (reg:CCNO FLAGS_REG)
7895         (compare:CCNO
7896           (and:SI
7897             (zero_extract:SI
7898               (match_operand 0 "ext_register_operand" "")
7899               (const_int 8)
7900               (const_int 8))
7901             (match_operand 1 "const_int_operand" ""))
7902           (const_int 0)))]
7903   ""
7904   "")
7905
7906 (define_insn "*testqi_ext_0"
7907   [(set (reg FLAGS_REG)
7908         (compare
7909           (and:SI
7910             (zero_extract:SI
7911               (match_operand 0 "ext_register_operand" "Q")
7912               (const_int 8)
7913               (const_int 8))
7914             (match_operand 1 "const_int_operand" "n"))
7915           (const_int 0)))]
7916   "ix86_match_ccmode (insn, CCNOmode)"
7917   "test{b}\t{%1, %h0|%h0, %1}"
7918   [(set_attr "type" "test")
7919    (set_attr "mode" "QI")
7920    (set_attr "length_immediate" "1")
7921    (set_attr "pent_pair" "np")])
7922
7923 (define_insn "*testqi_ext_1"
7924   [(set (reg FLAGS_REG)
7925         (compare
7926           (and:SI
7927             (zero_extract:SI
7928               (match_operand 0 "ext_register_operand" "Q")
7929               (const_int 8)
7930               (const_int 8))
7931             (zero_extend:SI
7932               (match_operand:QI 1 "general_operand" "Qm")))
7933           (const_int 0)))]
7934   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7935    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7936   "test{b}\t{%1, %h0|%h0, %1}"
7937   [(set_attr "type" "test")
7938    (set_attr "mode" "QI")])
7939
7940 (define_insn "*testqi_ext_1_rex64"
7941   [(set (reg FLAGS_REG)
7942         (compare
7943           (and:SI
7944             (zero_extract:SI
7945               (match_operand 0 "ext_register_operand" "Q")
7946               (const_int 8)
7947               (const_int 8))
7948             (zero_extend:SI
7949               (match_operand:QI 1 "register_operand" "Q")))
7950           (const_int 0)))]
7951   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7952   "test{b}\t{%1, %h0|%h0, %1}"
7953   [(set_attr "type" "test")
7954    (set_attr "mode" "QI")])
7955
7956 (define_insn "*testqi_ext_2"
7957   [(set (reg FLAGS_REG)
7958         (compare
7959           (and:SI
7960             (zero_extract:SI
7961               (match_operand 0 "ext_register_operand" "Q")
7962               (const_int 8)
7963               (const_int 8))
7964             (zero_extract:SI
7965               (match_operand 1 "ext_register_operand" "Q")
7966               (const_int 8)
7967               (const_int 8)))
7968           (const_int 0)))]
7969   "ix86_match_ccmode (insn, CCNOmode)"
7970   "test{b}\t{%h1, %h0|%h0, %h1}"
7971   [(set_attr "type" "test")
7972    (set_attr "mode" "QI")])
7973
7974 ;; Combine likes to form bit extractions for some tests.  Humor it.
7975 (define_insn "*testqi_ext_3"
7976   [(set (reg FLAGS_REG)
7977         (compare (zero_extract:SI
7978                    (match_operand 0 "nonimmediate_operand" "rm")
7979                    (match_operand:SI 1 "const_int_operand" "")
7980                    (match_operand:SI 2 "const_int_operand" ""))
7981                  (const_int 0)))]
7982   "ix86_match_ccmode (insn, CCNOmode)
7983    && (GET_MODE (operands[0]) == SImode
7984        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7985        || GET_MODE (operands[0]) == HImode
7986        || GET_MODE (operands[0]) == QImode)"
7987   "#")
7988
7989 (define_insn "*testqi_ext_3_rex64"
7990   [(set (reg FLAGS_REG)
7991         (compare (zero_extract:DI
7992                    (match_operand 0 "nonimmediate_operand" "rm")
7993                    (match_operand:DI 1 "const_int_operand" "")
7994                    (match_operand:DI 2 "const_int_operand" ""))
7995                  (const_int 0)))]
7996   "TARGET_64BIT
7997    && ix86_match_ccmode (insn, CCNOmode)
7998    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7999    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8000    /* Ensure that resulting mask is zero or sign extended operand.  */
8001    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8002        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8003            && INTVAL (operands[1]) > 32))
8004    && (GET_MODE (operands[0]) == SImode
8005        || GET_MODE (operands[0]) == DImode
8006        || GET_MODE (operands[0]) == HImode
8007        || GET_MODE (operands[0]) == QImode)"
8008   "#")
8009
8010 (define_split
8011   [(set (match_operand 0 "flags_reg_operand" "")
8012         (match_operator 1 "compare_operator"
8013           [(zero_extract
8014              (match_operand 2 "nonimmediate_operand" "")
8015              (match_operand 3 "const_int_operand" "")
8016              (match_operand 4 "const_int_operand" ""))
8017            (const_int 0)]))]
8018   "ix86_match_ccmode (insn, CCNOmode)"
8019   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8020 {
8021   rtx val = operands[2];
8022   HOST_WIDE_INT len = INTVAL (operands[3]);
8023   HOST_WIDE_INT pos = INTVAL (operands[4]);
8024   HOST_WIDE_INT mask;
8025   enum machine_mode mode, submode;
8026
8027   mode = GET_MODE (val);
8028   if (GET_CODE (val) == MEM)
8029     {
8030       /* ??? Combine likes to put non-volatile mem extractions in QImode
8031          no matter the size of the test.  So find a mode that works.  */
8032       if (! MEM_VOLATILE_P (val))
8033         {
8034           mode = smallest_mode_for_size (pos + len, MODE_INT);
8035           val = adjust_address (val, mode, 0);
8036         }
8037     }
8038   else if (GET_CODE (val) == SUBREG
8039            && (submode = GET_MODE (SUBREG_REG (val)),
8040                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8041            && pos + len <= GET_MODE_BITSIZE (submode))
8042     {
8043       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8044       mode = submode;
8045       val = SUBREG_REG (val);
8046     }
8047   else if (mode == HImode && pos + len <= 8)
8048     {
8049       /* Small HImode tests can be converted to QImode.  */
8050       mode = QImode;
8051       val = gen_lowpart (QImode, val);
8052     }
8053
8054   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8055   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8056
8057   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8058 })
8059
8060 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8061 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8062 ;; this is relatively important trick.
8063 ;; Do the conversion only post-reload to avoid limiting of the register class
8064 ;; to QI regs.
8065 (define_split
8066   [(set (match_operand 0 "flags_reg_operand" "")
8067         (match_operator 1 "compare_operator"
8068           [(and (match_operand 2 "register_operand" "")
8069                 (match_operand 3 "const_int_operand" ""))
8070            (const_int 0)]))]
8071    "reload_completed
8072     && QI_REG_P (operands[2])
8073     && GET_MODE (operands[2]) != QImode
8074     && ((ix86_match_ccmode (insn, CCZmode)
8075          && !(INTVAL (operands[3]) & ~(255 << 8)))
8076         || (ix86_match_ccmode (insn, CCNOmode)
8077             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8078   [(set (match_dup 0)
8079         (match_op_dup 1
8080           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8081                    (match_dup 3))
8082            (const_int 0)]))]
8083   "operands[2] = gen_lowpart (SImode, operands[2]);
8084    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8085
8086 (define_split
8087   [(set (match_operand 0 "flags_reg_operand" "")
8088         (match_operator 1 "compare_operator"
8089           [(and (match_operand 2 "nonimmediate_operand" "")
8090                 (match_operand 3 "const_int_operand" ""))
8091            (const_int 0)]))]
8092    "reload_completed
8093     && GET_MODE (operands[2]) != QImode
8094     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8095     && ((ix86_match_ccmode (insn, CCZmode)
8096          && !(INTVAL (operands[3]) & ~255))
8097         || (ix86_match_ccmode (insn, CCNOmode)
8098             && !(INTVAL (operands[3]) & ~127)))"
8099   [(set (match_dup 0)
8100         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8101                          (const_int 0)]))]
8102   "operands[2] = gen_lowpart (QImode, operands[2]);
8103    operands[3] = gen_lowpart (QImode, operands[3]);")
8104
8105
8106 ;; %%% This used to optimize known byte-wide and operations to memory,
8107 ;; and sometimes to QImode registers.  If this is considered useful,
8108 ;; it should be done with splitters.
8109
8110 (define_expand "anddi3"
8111   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8112         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8113                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8114    (clobber (reg:CC FLAGS_REG))]
8115   "TARGET_64BIT"
8116   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8117
8118 (define_insn "*anddi_1_rex64"
8119   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8120         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8121                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8122    (clobber (reg:CC FLAGS_REG))]
8123   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8124 {
8125   switch (get_attr_type (insn))
8126     {
8127     case TYPE_IMOVX:
8128       {
8129         enum machine_mode mode;
8130
8131         if (GET_CODE (operands[2]) != CONST_INT)
8132           abort ();
8133         if (INTVAL (operands[2]) == 0xff)
8134           mode = QImode;
8135         else if (INTVAL (operands[2]) == 0xffff)
8136           mode = HImode;
8137         else
8138           abort ();
8139         
8140         operands[1] = gen_lowpart (mode, operands[1]);
8141         if (mode == QImode)
8142           return "movz{bq|x}\t{%1,%0|%0, %1}";
8143         else
8144           return "movz{wq|x}\t{%1,%0|%0, %1}";
8145       }
8146
8147     default:
8148       if (! rtx_equal_p (operands[0], operands[1]))
8149         abort ();
8150       if (get_attr_mode (insn) == MODE_SI)
8151         return "and{l}\t{%k2, %k0|%k0, %k2}";
8152       else
8153         return "and{q}\t{%2, %0|%0, %2}";
8154     }
8155 }
8156   [(set_attr "type" "alu,alu,alu,imovx")
8157    (set_attr "length_immediate" "*,*,*,0")
8158    (set_attr "mode" "SI,DI,DI,DI")])
8159
8160 (define_insn "*anddi_2"
8161   [(set (reg FLAGS_REG)
8162         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8163                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8164                  (const_int 0)))
8165    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8166         (and:DI (match_dup 1) (match_dup 2)))]
8167   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8168    && ix86_binary_operator_ok (AND, DImode, operands)"
8169   "@
8170    and{l}\t{%k2, %k0|%k0, %k2}
8171    and{q}\t{%2, %0|%0, %2}
8172    and{q}\t{%2, %0|%0, %2}"
8173   [(set_attr "type" "alu")
8174    (set_attr "mode" "SI,DI,DI")])
8175
8176 (define_expand "andsi3"
8177   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8178         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8179                 (match_operand:SI 2 "general_operand" "")))
8180    (clobber (reg:CC FLAGS_REG))]
8181   ""
8182   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8183
8184 (define_insn "*andsi_1"
8185   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8186         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8187                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8188    (clobber (reg:CC FLAGS_REG))]
8189   "ix86_binary_operator_ok (AND, SImode, operands)"
8190 {
8191   switch (get_attr_type (insn))
8192     {
8193     case TYPE_IMOVX:
8194       {
8195         enum machine_mode mode;
8196
8197         if (GET_CODE (operands[2]) != CONST_INT)
8198           abort ();
8199         if (INTVAL (operands[2]) == 0xff)
8200           mode = QImode;
8201         else if (INTVAL (operands[2]) == 0xffff)
8202           mode = HImode;
8203         else
8204           abort ();
8205         
8206         operands[1] = gen_lowpart (mode, operands[1]);
8207         if (mode == QImode)
8208           return "movz{bl|x}\t{%1,%0|%0, %1}";
8209         else
8210           return "movz{wl|x}\t{%1,%0|%0, %1}";
8211       }
8212
8213     default:
8214       if (! rtx_equal_p (operands[0], operands[1]))
8215         abort ();
8216       return "and{l}\t{%2, %0|%0, %2}";
8217     }
8218 }
8219   [(set_attr "type" "alu,alu,imovx")
8220    (set_attr "length_immediate" "*,*,0")
8221    (set_attr "mode" "SI")])
8222
8223 (define_split
8224   [(set (match_operand 0 "register_operand" "")
8225         (and (match_dup 0)
8226              (const_int -65536)))
8227    (clobber (reg:CC FLAGS_REG))]
8228   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8229   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8230   "operands[1] = gen_lowpart (HImode, operands[0]);")
8231
8232 (define_split
8233   [(set (match_operand 0 "ext_register_operand" "")
8234         (and (match_dup 0)
8235              (const_int -256)))
8236    (clobber (reg:CC FLAGS_REG))]
8237   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8238   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8239   "operands[1] = gen_lowpart (QImode, operands[0]);")
8240
8241 (define_split
8242   [(set (match_operand 0 "ext_register_operand" "")
8243         (and (match_dup 0)
8244              (const_int -65281)))
8245    (clobber (reg:CC FLAGS_REG))]
8246   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8247   [(parallel [(set (zero_extract:SI (match_dup 0)
8248                                     (const_int 8)
8249                                     (const_int 8))
8250                    (xor:SI 
8251                      (zero_extract:SI (match_dup 0)
8252                                       (const_int 8)
8253                                       (const_int 8))
8254                      (zero_extract:SI (match_dup 0)
8255                                       (const_int 8)
8256                                       (const_int 8))))
8257               (clobber (reg:CC FLAGS_REG))])]
8258   "operands[0] = gen_lowpart (SImode, operands[0]);")
8259
8260 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8261 (define_insn "*andsi_1_zext"
8262   [(set (match_operand:DI 0 "register_operand" "=r")
8263         (zero_extend:DI
8264           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8265                   (match_operand:SI 2 "general_operand" "rim"))))
8266    (clobber (reg:CC FLAGS_REG))]
8267   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8268   "and{l}\t{%2, %k0|%k0, %2}"
8269   [(set_attr "type" "alu")
8270    (set_attr "mode" "SI")])
8271
8272 (define_insn "*andsi_2"
8273   [(set (reg FLAGS_REG)
8274         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8275                          (match_operand:SI 2 "general_operand" "rim,ri"))
8276                  (const_int 0)))
8277    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8278         (and:SI (match_dup 1) (match_dup 2)))]
8279   "ix86_match_ccmode (insn, CCNOmode)
8280    && ix86_binary_operator_ok (AND, SImode, operands)"
8281   "and{l}\t{%2, %0|%0, %2}"
8282   [(set_attr "type" "alu")
8283    (set_attr "mode" "SI")])
8284
8285 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8286 (define_insn "*andsi_2_zext"
8287   [(set (reg FLAGS_REG)
8288         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8289                          (match_operand:SI 2 "general_operand" "rim"))
8290                  (const_int 0)))
8291    (set (match_operand:DI 0 "register_operand" "=r")
8292         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8293   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8294    && ix86_binary_operator_ok (AND, SImode, operands)"
8295   "and{l}\t{%2, %k0|%k0, %2}"
8296   [(set_attr "type" "alu")
8297    (set_attr "mode" "SI")])
8298
8299 (define_expand "andhi3"
8300   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8301         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8302                 (match_operand:HI 2 "general_operand" "")))
8303    (clobber (reg:CC FLAGS_REG))]
8304   "TARGET_HIMODE_MATH"
8305   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8306
8307 (define_insn "*andhi_1"
8308   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8309         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8310                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8311    (clobber (reg:CC FLAGS_REG))]
8312   "ix86_binary_operator_ok (AND, HImode, operands)"
8313 {
8314   switch (get_attr_type (insn))
8315     {
8316     case TYPE_IMOVX:
8317       if (GET_CODE (operands[2]) != CONST_INT)
8318         abort ();
8319       if (INTVAL (operands[2]) == 0xff)
8320         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8321       abort ();
8322
8323     default:
8324       if (! rtx_equal_p (operands[0], operands[1]))
8325         abort ();
8326
8327       return "and{w}\t{%2, %0|%0, %2}";
8328     }
8329 }
8330   [(set_attr "type" "alu,alu,imovx")
8331    (set_attr "length_immediate" "*,*,0")
8332    (set_attr "mode" "HI,HI,SI")])
8333
8334 (define_insn "*andhi_2"
8335   [(set (reg FLAGS_REG)
8336         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8337                          (match_operand:HI 2 "general_operand" "rim,ri"))
8338                  (const_int 0)))
8339    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8340         (and:HI (match_dup 1) (match_dup 2)))]
8341   "ix86_match_ccmode (insn, CCNOmode)
8342    && ix86_binary_operator_ok (AND, HImode, operands)"
8343   "and{w}\t{%2, %0|%0, %2}"
8344   [(set_attr "type" "alu")
8345    (set_attr "mode" "HI")])
8346
8347 (define_expand "andqi3"
8348   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8349         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8350                 (match_operand:QI 2 "general_operand" "")))
8351    (clobber (reg:CC FLAGS_REG))]
8352   "TARGET_QIMODE_MATH"
8353   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8354
8355 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8356 (define_insn "*andqi_1"
8357   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8358         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8359                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8360    (clobber (reg:CC FLAGS_REG))]
8361   "ix86_binary_operator_ok (AND, QImode, operands)"
8362   "@
8363    and{b}\t{%2, %0|%0, %2}
8364    and{b}\t{%2, %0|%0, %2}
8365    and{l}\t{%k2, %k0|%k0, %k2}"
8366   [(set_attr "type" "alu")
8367    (set_attr "mode" "QI,QI,SI")])
8368
8369 (define_insn "*andqi_1_slp"
8370   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8371         (and:QI (match_dup 0)
8372                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8373    (clobber (reg:CC FLAGS_REG))]
8374   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8375    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8376   "and{b}\t{%1, %0|%0, %1}"
8377   [(set_attr "type" "alu1")
8378    (set_attr "mode" "QI")])
8379
8380 (define_insn "*andqi_2_maybe_si"
8381   [(set (reg FLAGS_REG)
8382         (compare (and:QI
8383                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8384                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8385                  (const_int 0)))
8386    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8387         (and:QI (match_dup 1) (match_dup 2)))]
8388   "ix86_binary_operator_ok (AND, QImode, operands)
8389    && ix86_match_ccmode (insn,
8390                          GET_CODE (operands[2]) == CONST_INT
8391                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8392 {
8393   if (which_alternative == 2)
8394     {
8395       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8396         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8397       return "and{l}\t{%2, %k0|%k0, %2}";
8398     }
8399   return "and{b}\t{%2, %0|%0, %2}";
8400 }
8401   [(set_attr "type" "alu")
8402    (set_attr "mode" "QI,QI,SI")])
8403
8404 (define_insn "*andqi_2"
8405   [(set (reg FLAGS_REG)
8406         (compare (and:QI
8407                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8408                    (match_operand:QI 2 "general_operand" "qim,qi"))
8409                  (const_int 0)))
8410    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8411         (and:QI (match_dup 1) (match_dup 2)))]
8412   "ix86_match_ccmode (insn, CCNOmode)
8413    && ix86_binary_operator_ok (AND, QImode, operands)"
8414   "and{b}\t{%2, %0|%0, %2}"
8415   [(set_attr "type" "alu")
8416    (set_attr "mode" "QI")])
8417
8418 (define_insn "*andqi_2_slp"
8419   [(set (reg FLAGS_REG)
8420         (compare (and:QI
8421                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8422                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8423                  (const_int 0)))
8424    (set (strict_low_part (match_dup 0))
8425         (and:QI (match_dup 0) (match_dup 1)))]
8426   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8427    && ix86_match_ccmode (insn, CCNOmode)
8428    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8429   "and{b}\t{%1, %0|%0, %1}"
8430   [(set_attr "type" "alu1")
8431    (set_attr "mode" "QI")])
8432
8433 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8434 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8435 ;; for a QImode operand, which of course failed.
8436
8437 (define_insn "andqi_ext_0"
8438   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8439                          (const_int 8)
8440                          (const_int 8))
8441         (and:SI 
8442           (zero_extract:SI
8443             (match_operand 1 "ext_register_operand" "0")
8444             (const_int 8)
8445             (const_int 8))
8446           (match_operand 2 "const_int_operand" "n")))
8447    (clobber (reg:CC FLAGS_REG))]
8448   ""
8449   "and{b}\t{%2, %h0|%h0, %2}"
8450   [(set_attr "type" "alu")
8451    (set_attr "length_immediate" "1")
8452    (set_attr "mode" "QI")])
8453
8454 ;; Generated by peephole translating test to and.  This shows up
8455 ;; often in fp comparisons.
8456
8457 (define_insn "*andqi_ext_0_cc"
8458   [(set (reg FLAGS_REG)
8459         (compare
8460           (and:SI
8461             (zero_extract:SI
8462               (match_operand 1 "ext_register_operand" "0")
8463               (const_int 8)
8464               (const_int 8))
8465             (match_operand 2 "const_int_operand" "n"))
8466           (const_int 0)))
8467    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8468                          (const_int 8)
8469                          (const_int 8))
8470         (and:SI 
8471           (zero_extract:SI
8472             (match_dup 1)
8473             (const_int 8)
8474             (const_int 8))
8475           (match_dup 2)))]
8476   "ix86_match_ccmode (insn, CCNOmode)"
8477   "and{b}\t{%2, %h0|%h0, %2}"
8478   [(set_attr "type" "alu")
8479    (set_attr "length_immediate" "1")
8480    (set_attr "mode" "QI")])
8481
8482 (define_insn "*andqi_ext_1"
8483   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8484                          (const_int 8)
8485                          (const_int 8))
8486         (and:SI 
8487           (zero_extract:SI
8488             (match_operand 1 "ext_register_operand" "0")
8489             (const_int 8)
8490             (const_int 8))
8491           (zero_extend:SI
8492             (match_operand:QI 2 "general_operand" "Qm"))))
8493    (clobber (reg:CC FLAGS_REG))]
8494   "!TARGET_64BIT"
8495   "and{b}\t{%2, %h0|%h0, %2}"
8496   [(set_attr "type" "alu")
8497    (set_attr "length_immediate" "0")
8498    (set_attr "mode" "QI")])
8499
8500 (define_insn "*andqi_ext_1_rex64"
8501   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8502                          (const_int 8)
8503                          (const_int 8))
8504         (and:SI 
8505           (zero_extract:SI
8506             (match_operand 1 "ext_register_operand" "0")
8507             (const_int 8)
8508             (const_int 8))
8509           (zero_extend:SI
8510             (match_operand 2 "ext_register_operand" "Q"))))
8511    (clobber (reg:CC FLAGS_REG))]
8512   "TARGET_64BIT"
8513   "and{b}\t{%2, %h0|%h0, %2}"
8514   [(set_attr "type" "alu")
8515    (set_attr "length_immediate" "0")
8516    (set_attr "mode" "QI")])
8517
8518 (define_insn "*andqi_ext_2"
8519   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8520                          (const_int 8)
8521                          (const_int 8))
8522         (and:SI
8523           (zero_extract:SI
8524             (match_operand 1 "ext_register_operand" "%0")
8525             (const_int 8)
8526             (const_int 8))
8527           (zero_extract:SI
8528             (match_operand 2 "ext_register_operand" "Q")
8529             (const_int 8)
8530             (const_int 8))))
8531    (clobber (reg:CC FLAGS_REG))]
8532   ""
8533   "and{b}\t{%h2, %h0|%h0, %h2}"
8534   [(set_attr "type" "alu")
8535    (set_attr "length_immediate" "0")
8536    (set_attr "mode" "QI")])
8537
8538 ;; Convert wide AND instructions with immediate operand to shorter QImode
8539 ;; equivalents when possible.
8540 ;; Don't do the splitting with memory operands, since it introduces risk
8541 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8542 ;; for size, but that can (should?) be handled by generic code instead.
8543 (define_split
8544   [(set (match_operand 0 "register_operand" "")
8545         (and (match_operand 1 "register_operand" "")
8546              (match_operand 2 "const_int_operand" "")))
8547    (clobber (reg:CC FLAGS_REG))]
8548    "reload_completed
8549     && QI_REG_P (operands[0])
8550     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8551     && !(~INTVAL (operands[2]) & ~(255 << 8))
8552     && GET_MODE (operands[0]) != QImode"
8553   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8554                    (and:SI (zero_extract:SI (match_dup 1)
8555                                             (const_int 8) (const_int 8))
8556                            (match_dup 2)))
8557               (clobber (reg:CC FLAGS_REG))])]
8558   "operands[0] = gen_lowpart (SImode, operands[0]);
8559    operands[1] = gen_lowpart (SImode, operands[1]);
8560    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8561
8562 ;; Since AND can be encoded with sign extended immediate, this is only
8563 ;; profitable when 7th bit is not set.
8564 (define_split
8565   [(set (match_operand 0 "register_operand" "")
8566         (and (match_operand 1 "general_operand" "")
8567              (match_operand 2 "const_int_operand" "")))
8568    (clobber (reg:CC FLAGS_REG))]
8569    "reload_completed
8570     && ANY_QI_REG_P (operands[0])
8571     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8572     && !(~INTVAL (operands[2]) & ~255)
8573     && !(INTVAL (operands[2]) & 128)
8574     && GET_MODE (operands[0]) != QImode"
8575   [(parallel [(set (strict_low_part (match_dup 0))
8576                    (and:QI (match_dup 1)
8577                            (match_dup 2)))
8578               (clobber (reg:CC FLAGS_REG))])]
8579   "operands[0] = gen_lowpart (QImode, operands[0]);
8580    operands[1] = gen_lowpart (QImode, operands[1]);
8581    operands[2] = gen_lowpart (QImode, operands[2]);")
8582 \f
8583 ;; Logical inclusive OR instructions
8584
8585 ;; %%% This used to optimize known byte-wide and operations to memory.
8586 ;; If this is considered useful, it should be done with splitters.
8587
8588 (define_expand "iordi3"
8589   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8590         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8591                 (match_operand:DI 2 "x86_64_general_operand" "")))
8592    (clobber (reg:CC FLAGS_REG))]
8593   "TARGET_64BIT"
8594   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8595
8596 (define_insn "*iordi_1_rex64"
8597   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8598         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8599                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8600    (clobber (reg:CC FLAGS_REG))]
8601   "TARGET_64BIT
8602    && ix86_binary_operator_ok (IOR, DImode, operands)"
8603   "or{q}\t{%2, %0|%0, %2}"
8604   [(set_attr "type" "alu")
8605    (set_attr "mode" "DI")])
8606
8607 (define_insn "*iordi_2_rex64"
8608   [(set (reg FLAGS_REG)
8609         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8610                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8611                  (const_int 0)))
8612    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8613         (ior:DI (match_dup 1) (match_dup 2)))]
8614   "TARGET_64BIT
8615    && ix86_match_ccmode (insn, CCNOmode)
8616    && ix86_binary_operator_ok (IOR, DImode, operands)"
8617   "or{q}\t{%2, %0|%0, %2}"
8618   [(set_attr "type" "alu")
8619    (set_attr "mode" "DI")])
8620
8621 (define_insn "*iordi_3_rex64"
8622   [(set (reg FLAGS_REG)
8623         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8624                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8625                  (const_int 0)))
8626    (clobber (match_scratch:DI 0 "=r"))]
8627   "TARGET_64BIT
8628    && ix86_match_ccmode (insn, CCNOmode)
8629    && ix86_binary_operator_ok (IOR, DImode, operands)"
8630   "or{q}\t{%2, %0|%0, %2}"
8631   [(set_attr "type" "alu")
8632    (set_attr "mode" "DI")])
8633
8634
8635 (define_expand "iorsi3"
8636   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8637         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8638                 (match_operand:SI 2 "general_operand" "")))
8639    (clobber (reg:CC FLAGS_REG))]
8640   ""
8641   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8642
8643 (define_insn "*iorsi_1"
8644   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8645         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8646                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8647    (clobber (reg:CC FLAGS_REG))]
8648   "ix86_binary_operator_ok (IOR, SImode, operands)"
8649   "or{l}\t{%2, %0|%0, %2}"
8650   [(set_attr "type" "alu")
8651    (set_attr "mode" "SI")])
8652
8653 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8654 (define_insn "*iorsi_1_zext"
8655   [(set (match_operand:DI 0 "register_operand" "=rm")
8656         (zero_extend:DI
8657           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8658                   (match_operand:SI 2 "general_operand" "rim"))))
8659    (clobber (reg:CC FLAGS_REG))]
8660   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8661   "or{l}\t{%2, %k0|%k0, %2}"
8662   [(set_attr "type" "alu")
8663    (set_attr "mode" "SI")])
8664
8665 (define_insn "*iorsi_1_zext_imm"
8666   [(set (match_operand:DI 0 "register_operand" "=rm")
8667         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8668                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8669    (clobber (reg:CC FLAGS_REG))]
8670   "TARGET_64BIT"
8671   "or{l}\t{%2, %k0|%k0, %2}"
8672   [(set_attr "type" "alu")
8673    (set_attr "mode" "SI")])
8674
8675 (define_insn "*iorsi_2"
8676   [(set (reg FLAGS_REG)
8677         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8678                          (match_operand:SI 2 "general_operand" "rim,ri"))
8679                  (const_int 0)))
8680    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8681         (ior:SI (match_dup 1) (match_dup 2)))]
8682   "ix86_match_ccmode (insn, CCNOmode)
8683    && ix86_binary_operator_ok (IOR, SImode, operands)"
8684   "or{l}\t{%2, %0|%0, %2}"
8685   [(set_attr "type" "alu")
8686    (set_attr "mode" "SI")])
8687
8688 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8689 ;; ??? Special case for immediate operand is missing - it is tricky.
8690 (define_insn "*iorsi_2_zext"
8691   [(set (reg FLAGS_REG)
8692         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8693                          (match_operand:SI 2 "general_operand" "rim"))
8694                  (const_int 0)))
8695    (set (match_operand:DI 0 "register_operand" "=r")
8696         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8697   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8698    && ix86_binary_operator_ok (IOR, SImode, operands)"
8699   "or{l}\t{%2, %k0|%k0, %2}"
8700   [(set_attr "type" "alu")
8701    (set_attr "mode" "SI")])
8702
8703 (define_insn "*iorsi_2_zext_imm"
8704   [(set (reg FLAGS_REG)
8705         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8706                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8707                  (const_int 0)))
8708    (set (match_operand:DI 0 "register_operand" "=r")
8709         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8710   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8711    && ix86_binary_operator_ok (IOR, SImode, operands)"
8712   "or{l}\t{%2, %k0|%k0, %2}"
8713   [(set_attr "type" "alu")
8714    (set_attr "mode" "SI")])
8715
8716 (define_insn "*iorsi_3"
8717   [(set (reg FLAGS_REG)
8718         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8719                          (match_operand:SI 2 "general_operand" "rim"))
8720                  (const_int 0)))
8721    (clobber (match_scratch:SI 0 "=r"))]
8722   "ix86_match_ccmode (insn, CCNOmode)
8723    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8724   "or{l}\t{%2, %0|%0, %2}"
8725   [(set_attr "type" "alu")
8726    (set_attr "mode" "SI")])
8727
8728 (define_expand "iorhi3"
8729   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8730         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8731                 (match_operand:HI 2 "general_operand" "")))
8732    (clobber (reg:CC FLAGS_REG))]
8733   "TARGET_HIMODE_MATH"
8734   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8735
8736 (define_insn "*iorhi_1"
8737   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8738         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8739                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8740    (clobber (reg:CC FLAGS_REG))]
8741   "ix86_binary_operator_ok (IOR, HImode, operands)"
8742   "or{w}\t{%2, %0|%0, %2}"
8743   [(set_attr "type" "alu")
8744    (set_attr "mode" "HI")])
8745
8746 (define_insn "*iorhi_2"
8747   [(set (reg FLAGS_REG)
8748         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8749                          (match_operand:HI 2 "general_operand" "rim,ri"))
8750                  (const_int 0)))
8751    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8752         (ior:HI (match_dup 1) (match_dup 2)))]
8753   "ix86_match_ccmode (insn, CCNOmode)
8754    && ix86_binary_operator_ok (IOR, HImode, operands)"
8755   "or{w}\t{%2, %0|%0, %2}"
8756   [(set_attr "type" "alu")
8757    (set_attr "mode" "HI")])
8758
8759 (define_insn "*iorhi_3"
8760   [(set (reg FLAGS_REG)
8761         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8762                          (match_operand:HI 2 "general_operand" "rim"))
8763                  (const_int 0)))
8764    (clobber (match_scratch:HI 0 "=r"))]
8765   "ix86_match_ccmode (insn, CCNOmode)
8766    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8767   "or{w}\t{%2, %0|%0, %2}"
8768   [(set_attr "type" "alu")
8769    (set_attr "mode" "HI")])
8770
8771 (define_expand "iorqi3"
8772   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8773         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8774                 (match_operand:QI 2 "general_operand" "")))
8775    (clobber (reg:CC FLAGS_REG))]
8776   "TARGET_QIMODE_MATH"
8777   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8778
8779 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8780 (define_insn "*iorqi_1"
8781   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8782         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8783                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8784    (clobber (reg:CC FLAGS_REG))]
8785   "ix86_binary_operator_ok (IOR, QImode, operands)"
8786   "@
8787    or{b}\t{%2, %0|%0, %2}
8788    or{b}\t{%2, %0|%0, %2}
8789    or{l}\t{%k2, %k0|%k0, %k2}"
8790   [(set_attr "type" "alu")
8791    (set_attr "mode" "QI,QI,SI")])
8792
8793 (define_insn "*iorqi_1_slp"
8794   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8795         (ior:QI (match_dup 0)
8796                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8797    (clobber (reg:CC FLAGS_REG))]
8798   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8799    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8800   "or{b}\t{%1, %0|%0, %1}"
8801   [(set_attr "type" "alu1")
8802    (set_attr "mode" "QI")])
8803
8804 (define_insn "*iorqi_2"
8805   [(set (reg FLAGS_REG)
8806         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8807                          (match_operand:QI 2 "general_operand" "qim,qi"))
8808                  (const_int 0)))
8809    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8810         (ior:QI (match_dup 1) (match_dup 2)))]
8811   "ix86_match_ccmode (insn, CCNOmode)
8812    && ix86_binary_operator_ok (IOR, QImode, operands)"
8813   "or{b}\t{%2, %0|%0, %2}"
8814   [(set_attr "type" "alu")
8815    (set_attr "mode" "QI")])
8816
8817 (define_insn "*iorqi_2_slp"
8818   [(set (reg FLAGS_REG)
8819         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8820                          (match_operand:QI 1 "general_operand" "qim,qi"))
8821                  (const_int 0)))
8822    (set (strict_low_part (match_dup 0))
8823         (ior:QI (match_dup 0) (match_dup 1)))]
8824   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8825    && ix86_match_ccmode (insn, CCNOmode)
8826    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8827   "or{b}\t{%1, %0|%0, %1}"
8828   [(set_attr "type" "alu1")
8829    (set_attr "mode" "QI")])
8830
8831 (define_insn "*iorqi_3"
8832   [(set (reg FLAGS_REG)
8833         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8834                          (match_operand:QI 2 "general_operand" "qim"))
8835                  (const_int 0)))
8836    (clobber (match_scratch:QI 0 "=q"))]
8837   "ix86_match_ccmode (insn, CCNOmode)
8838    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8839   "or{b}\t{%2, %0|%0, %2}"
8840   [(set_attr "type" "alu")
8841    (set_attr "mode" "QI")])
8842
8843 (define_insn "iorqi_ext_0"
8844   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8845                          (const_int 8)
8846                          (const_int 8))
8847         (ior:SI 
8848           (zero_extract:SI
8849             (match_operand 1 "ext_register_operand" "0")
8850             (const_int 8)
8851             (const_int 8))
8852           (match_operand 2 "const_int_operand" "n")))
8853    (clobber (reg:CC FLAGS_REG))]
8854   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8855   "or{b}\t{%2, %h0|%h0, %2}"
8856   [(set_attr "type" "alu")
8857    (set_attr "length_immediate" "1")
8858    (set_attr "mode" "QI")])
8859
8860 (define_insn "*iorqi_ext_1"
8861   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8862                          (const_int 8)
8863                          (const_int 8))
8864         (ior:SI 
8865           (zero_extract:SI
8866             (match_operand 1 "ext_register_operand" "0")
8867             (const_int 8)
8868             (const_int 8))
8869           (zero_extend:SI
8870             (match_operand:QI 2 "general_operand" "Qm"))))
8871    (clobber (reg:CC FLAGS_REG))]
8872   "!TARGET_64BIT
8873    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8874   "or{b}\t{%2, %h0|%h0, %2}"
8875   [(set_attr "type" "alu")
8876    (set_attr "length_immediate" "0")
8877    (set_attr "mode" "QI")])
8878
8879 (define_insn "*iorqi_ext_1_rex64"
8880   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8881                          (const_int 8)
8882                          (const_int 8))
8883         (ior:SI 
8884           (zero_extract:SI
8885             (match_operand 1 "ext_register_operand" "0")
8886             (const_int 8)
8887             (const_int 8))
8888           (zero_extend:SI
8889             (match_operand 2 "ext_register_operand" "Q"))))
8890    (clobber (reg:CC FLAGS_REG))]
8891   "TARGET_64BIT
8892    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8893   "or{b}\t{%2, %h0|%h0, %2}"
8894   [(set_attr "type" "alu")
8895    (set_attr "length_immediate" "0")
8896    (set_attr "mode" "QI")])
8897
8898 (define_insn "*iorqi_ext_2"
8899   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8900                          (const_int 8)
8901                          (const_int 8))
8902         (ior:SI 
8903           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8904                            (const_int 8)
8905                            (const_int 8))
8906           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8907                            (const_int 8)
8908                            (const_int 8))))
8909    (clobber (reg:CC FLAGS_REG))]
8910   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8911   "ior{b}\t{%h2, %h0|%h0, %h2}"
8912   [(set_attr "type" "alu")
8913    (set_attr "length_immediate" "0")
8914    (set_attr "mode" "QI")])
8915
8916 (define_split
8917   [(set (match_operand 0 "register_operand" "")
8918         (ior (match_operand 1 "register_operand" "")
8919              (match_operand 2 "const_int_operand" "")))
8920    (clobber (reg:CC FLAGS_REG))]
8921    "reload_completed
8922     && QI_REG_P (operands[0])
8923     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8924     && !(INTVAL (operands[2]) & ~(255 << 8))
8925     && GET_MODE (operands[0]) != QImode"
8926   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8927                    (ior:SI (zero_extract:SI (match_dup 1)
8928                                             (const_int 8) (const_int 8))
8929                            (match_dup 2)))
8930               (clobber (reg:CC FLAGS_REG))])]
8931   "operands[0] = gen_lowpart (SImode, operands[0]);
8932    operands[1] = gen_lowpart (SImode, operands[1]);
8933    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8934
8935 ;; Since OR can be encoded with sign extended immediate, this is only
8936 ;; profitable when 7th bit is set.
8937 (define_split
8938   [(set (match_operand 0 "register_operand" "")
8939         (ior (match_operand 1 "general_operand" "")
8940              (match_operand 2 "const_int_operand" "")))
8941    (clobber (reg:CC FLAGS_REG))]
8942    "reload_completed
8943     && ANY_QI_REG_P (operands[0])
8944     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8945     && !(INTVAL (operands[2]) & ~255)
8946     && (INTVAL (operands[2]) & 128)
8947     && GET_MODE (operands[0]) != QImode"
8948   [(parallel [(set (strict_low_part (match_dup 0))
8949                    (ior:QI (match_dup 1)
8950                            (match_dup 2)))
8951               (clobber (reg:CC FLAGS_REG))])]
8952   "operands[0] = gen_lowpart (QImode, operands[0]);
8953    operands[1] = gen_lowpart (QImode, operands[1]);
8954    operands[2] = gen_lowpart (QImode, operands[2]);")
8955 \f
8956 ;; Logical XOR instructions
8957
8958 ;; %%% This used to optimize known byte-wide and operations to memory.
8959 ;; If this is considered useful, it should be done with splitters.
8960
8961 (define_expand "xordi3"
8962   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8963         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8964                 (match_operand:DI 2 "x86_64_general_operand" "")))
8965    (clobber (reg:CC FLAGS_REG))]
8966   "TARGET_64BIT"
8967   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8968
8969 (define_insn "*xordi_1_rex64"
8970   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8971         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8972                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8973    (clobber (reg:CC FLAGS_REG))]
8974   "TARGET_64BIT
8975    && ix86_binary_operator_ok (XOR, DImode, operands)"
8976   "@
8977    xor{q}\t{%2, %0|%0, %2}
8978    xor{q}\t{%2, %0|%0, %2}"
8979   [(set_attr "type" "alu")
8980    (set_attr "mode" "DI,DI")])
8981
8982 (define_insn "*xordi_2_rex64"
8983   [(set (reg FLAGS_REG)
8984         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8985                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8986                  (const_int 0)))
8987    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8988         (xor:DI (match_dup 1) (match_dup 2)))]
8989   "TARGET_64BIT
8990    && ix86_match_ccmode (insn, CCNOmode)
8991    && ix86_binary_operator_ok (XOR, DImode, operands)"
8992   "@
8993    xor{q}\t{%2, %0|%0, %2}
8994    xor{q}\t{%2, %0|%0, %2}"
8995   [(set_attr "type" "alu")
8996    (set_attr "mode" "DI,DI")])
8997
8998 (define_insn "*xordi_3_rex64"
8999   [(set (reg FLAGS_REG)
9000         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9001                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9002                  (const_int 0)))
9003    (clobber (match_scratch:DI 0 "=r"))]
9004   "TARGET_64BIT
9005    && ix86_match_ccmode (insn, CCNOmode)
9006    && ix86_binary_operator_ok (XOR, DImode, operands)"
9007   "xor{q}\t{%2, %0|%0, %2}"
9008   [(set_attr "type" "alu")
9009    (set_attr "mode" "DI")])
9010
9011 (define_expand "xorsi3"
9012   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9013         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9014                 (match_operand:SI 2 "general_operand" "")))
9015    (clobber (reg:CC FLAGS_REG))]
9016   ""
9017   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9018
9019 (define_insn "*xorsi_1"
9020   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9021         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9022                 (match_operand:SI 2 "general_operand" "ri,rm")))
9023    (clobber (reg:CC FLAGS_REG))]
9024   "ix86_binary_operator_ok (XOR, SImode, operands)"
9025   "xor{l}\t{%2, %0|%0, %2}"
9026   [(set_attr "type" "alu")
9027    (set_attr "mode" "SI")])
9028
9029 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9030 ;; Add speccase for immediates
9031 (define_insn "*xorsi_1_zext"
9032   [(set (match_operand:DI 0 "register_operand" "=r")
9033         (zero_extend:DI
9034           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9035                   (match_operand:SI 2 "general_operand" "rim"))))
9036    (clobber (reg:CC FLAGS_REG))]
9037   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9038   "xor{l}\t{%2, %k0|%k0, %2}"
9039   [(set_attr "type" "alu")
9040    (set_attr "mode" "SI")])
9041
9042 (define_insn "*xorsi_1_zext_imm"
9043   [(set (match_operand:DI 0 "register_operand" "=r")
9044         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9045                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9046    (clobber (reg:CC FLAGS_REG))]
9047   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9048   "xor{l}\t{%2, %k0|%k0, %2}"
9049   [(set_attr "type" "alu")
9050    (set_attr "mode" "SI")])
9051
9052 (define_insn "*xorsi_2"
9053   [(set (reg FLAGS_REG)
9054         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9055                          (match_operand:SI 2 "general_operand" "rim,ri"))
9056                  (const_int 0)))
9057    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9058         (xor:SI (match_dup 1) (match_dup 2)))]
9059   "ix86_match_ccmode (insn, CCNOmode)
9060    && ix86_binary_operator_ok (XOR, SImode, operands)"
9061   "xor{l}\t{%2, %0|%0, %2}"
9062   [(set_attr "type" "alu")
9063    (set_attr "mode" "SI")])
9064
9065 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9066 ;; ??? Special case for immediate operand is missing - it is tricky.
9067 (define_insn "*xorsi_2_zext"
9068   [(set (reg FLAGS_REG)
9069         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9070                          (match_operand:SI 2 "general_operand" "rim"))
9071                  (const_int 0)))
9072    (set (match_operand:DI 0 "register_operand" "=r")
9073         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9074   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9075    && ix86_binary_operator_ok (XOR, SImode, operands)"
9076   "xor{l}\t{%2, %k0|%k0, %2}"
9077   [(set_attr "type" "alu")
9078    (set_attr "mode" "SI")])
9079
9080 (define_insn "*xorsi_2_zext_imm"
9081   [(set (reg FLAGS_REG)
9082         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9083                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9084                  (const_int 0)))
9085    (set (match_operand:DI 0 "register_operand" "=r")
9086         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9087   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9088    && ix86_binary_operator_ok (XOR, SImode, operands)"
9089   "xor{l}\t{%2, %k0|%k0, %2}"
9090   [(set_attr "type" "alu")
9091    (set_attr "mode" "SI")])
9092
9093 (define_insn "*xorsi_3"
9094   [(set (reg FLAGS_REG)
9095         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9096                          (match_operand:SI 2 "general_operand" "rim"))
9097                  (const_int 0)))
9098    (clobber (match_scratch:SI 0 "=r"))]
9099   "ix86_match_ccmode (insn, CCNOmode)
9100    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9101   "xor{l}\t{%2, %0|%0, %2}"
9102   [(set_attr "type" "alu")
9103    (set_attr "mode" "SI")])
9104
9105 (define_expand "xorhi3"
9106   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9107         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9108                 (match_operand:HI 2 "general_operand" "")))
9109    (clobber (reg:CC FLAGS_REG))]
9110   "TARGET_HIMODE_MATH"
9111   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9112
9113 (define_insn "*xorhi_1"
9114   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9115         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9116                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9117    (clobber (reg:CC FLAGS_REG))]
9118   "ix86_binary_operator_ok (XOR, HImode, operands)"
9119   "xor{w}\t{%2, %0|%0, %2}"
9120   [(set_attr "type" "alu")
9121    (set_attr "mode" "HI")])
9122
9123 (define_insn "*xorhi_2"
9124   [(set (reg FLAGS_REG)
9125         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9126                          (match_operand:HI 2 "general_operand" "rim,ri"))
9127                  (const_int 0)))
9128    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9129         (xor:HI (match_dup 1) (match_dup 2)))]
9130   "ix86_match_ccmode (insn, CCNOmode)
9131    && ix86_binary_operator_ok (XOR, HImode, operands)"
9132   "xor{w}\t{%2, %0|%0, %2}"
9133   [(set_attr "type" "alu")
9134    (set_attr "mode" "HI")])
9135
9136 (define_insn "*xorhi_3"
9137   [(set (reg FLAGS_REG)
9138         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9139                          (match_operand:HI 2 "general_operand" "rim"))
9140                  (const_int 0)))
9141    (clobber (match_scratch:HI 0 "=r"))]
9142   "ix86_match_ccmode (insn, CCNOmode)
9143    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9144   "xor{w}\t{%2, %0|%0, %2}"
9145   [(set_attr "type" "alu")
9146    (set_attr "mode" "HI")])
9147
9148 (define_expand "xorqi3"
9149   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9150         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9151                 (match_operand:QI 2 "general_operand" "")))
9152    (clobber (reg:CC FLAGS_REG))]
9153   "TARGET_QIMODE_MATH"
9154   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9155
9156 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9157 (define_insn "*xorqi_1"
9158   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9159         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9160                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9161    (clobber (reg:CC FLAGS_REG))]
9162   "ix86_binary_operator_ok (XOR, QImode, operands)"
9163   "@
9164    xor{b}\t{%2, %0|%0, %2}
9165    xor{b}\t{%2, %0|%0, %2}
9166    xor{l}\t{%k2, %k0|%k0, %k2}"
9167   [(set_attr "type" "alu")
9168    (set_attr "mode" "QI,QI,SI")])
9169
9170 (define_insn "*xorqi_1_slp"
9171   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9172         (xor:QI (match_dup 0)
9173                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9174    (clobber (reg:CC FLAGS_REG))]
9175   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9176    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9177   "xor{b}\t{%1, %0|%0, %1}"
9178   [(set_attr "type" "alu1")
9179    (set_attr "mode" "QI")])
9180
9181 (define_insn "xorqi_ext_0"
9182   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9183                          (const_int 8)
9184                          (const_int 8))
9185         (xor:SI 
9186           (zero_extract:SI
9187             (match_operand 1 "ext_register_operand" "0")
9188             (const_int 8)
9189             (const_int 8))
9190           (match_operand 2 "const_int_operand" "n")))
9191    (clobber (reg:CC FLAGS_REG))]
9192   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9193   "xor{b}\t{%2, %h0|%h0, %2}"
9194   [(set_attr "type" "alu")
9195    (set_attr "length_immediate" "1")
9196    (set_attr "mode" "QI")])
9197
9198 (define_insn "*xorqi_ext_1"
9199   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9200                          (const_int 8)
9201                          (const_int 8))
9202         (xor:SI 
9203           (zero_extract:SI
9204             (match_operand 1 "ext_register_operand" "0")
9205             (const_int 8)
9206             (const_int 8))
9207           (zero_extend:SI
9208             (match_operand:QI 2 "general_operand" "Qm"))))
9209    (clobber (reg:CC FLAGS_REG))]
9210   "!TARGET_64BIT
9211    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9212   "xor{b}\t{%2, %h0|%h0, %2}"
9213   [(set_attr "type" "alu")
9214    (set_attr "length_immediate" "0")
9215    (set_attr "mode" "QI")])
9216
9217 (define_insn "*xorqi_ext_1_rex64"
9218   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9219                          (const_int 8)
9220                          (const_int 8))
9221         (xor:SI 
9222           (zero_extract:SI
9223             (match_operand 1 "ext_register_operand" "0")
9224             (const_int 8)
9225             (const_int 8))
9226           (zero_extend:SI
9227             (match_operand 2 "ext_register_operand" "Q"))))
9228    (clobber (reg:CC FLAGS_REG))]
9229   "TARGET_64BIT
9230    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9231   "xor{b}\t{%2, %h0|%h0, %2}"
9232   [(set_attr "type" "alu")
9233    (set_attr "length_immediate" "0")
9234    (set_attr "mode" "QI")])
9235
9236 (define_insn "*xorqi_ext_2"
9237   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9238                          (const_int 8)
9239                          (const_int 8))
9240         (xor:SI 
9241           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9242                            (const_int 8)
9243                            (const_int 8))
9244           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9245                            (const_int 8)
9246                            (const_int 8))))
9247    (clobber (reg:CC FLAGS_REG))]
9248   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9249   "xor{b}\t{%h2, %h0|%h0, %h2}"
9250   [(set_attr "type" "alu")
9251    (set_attr "length_immediate" "0")
9252    (set_attr "mode" "QI")])
9253
9254 (define_insn "*xorqi_cc_1"
9255   [(set (reg FLAGS_REG)
9256         (compare
9257           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9258                   (match_operand:QI 2 "general_operand" "qim,qi"))
9259           (const_int 0)))
9260    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9261         (xor:QI (match_dup 1) (match_dup 2)))]
9262   "ix86_match_ccmode (insn, CCNOmode)
9263    && ix86_binary_operator_ok (XOR, QImode, operands)"
9264   "xor{b}\t{%2, %0|%0, %2}"
9265   [(set_attr "type" "alu")
9266    (set_attr "mode" "QI")])
9267
9268 (define_insn "*xorqi_2_slp"
9269   [(set (reg FLAGS_REG)
9270         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9271                          (match_operand:QI 1 "general_operand" "qim,qi"))
9272                  (const_int 0)))
9273    (set (strict_low_part (match_dup 0))
9274         (xor:QI (match_dup 0) (match_dup 1)))]
9275   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9276    && ix86_match_ccmode (insn, CCNOmode)
9277    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9278   "xor{b}\t{%1, %0|%0, %1}"
9279   [(set_attr "type" "alu1")
9280    (set_attr "mode" "QI")])
9281
9282 (define_insn "*xorqi_cc_2"
9283   [(set (reg FLAGS_REG)
9284         (compare
9285           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9286                   (match_operand:QI 2 "general_operand" "qim"))
9287           (const_int 0)))
9288    (clobber (match_scratch:QI 0 "=q"))]
9289   "ix86_match_ccmode (insn, CCNOmode)
9290    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9291   "xor{b}\t{%2, %0|%0, %2}"
9292   [(set_attr "type" "alu")
9293    (set_attr "mode" "QI")])
9294
9295 (define_insn "*xorqi_cc_ext_1"
9296   [(set (reg FLAGS_REG)
9297         (compare
9298           (xor:SI
9299             (zero_extract:SI
9300               (match_operand 1 "ext_register_operand" "0")
9301               (const_int 8)
9302               (const_int 8))
9303             (match_operand:QI 2 "general_operand" "qmn"))
9304           (const_int 0)))
9305    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9306                          (const_int 8)
9307                          (const_int 8))
9308         (xor:SI 
9309           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9310           (match_dup 2)))]
9311   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9312   "xor{b}\t{%2, %h0|%h0, %2}"
9313   [(set_attr "type" "alu")
9314    (set_attr "mode" "QI")])
9315
9316 (define_insn "*xorqi_cc_ext_1_rex64"
9317   [(set (reg FLAGS_REG)
9318         (compare
9319           (xor:SI
9320             (zero_extract:SI
9321               (match_operand 1 "ext_register_operand" "0")
9322               (const_int 8)
9323               (const_int 8))
9324             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9325           (const_int 0)))
9326    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9327                          (const_int 8)
9328                          (const_int 8))
9329         (xor:SI 
9330           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9331           (match_dup 2)))]
9332   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9333   "xor{b}\t{%2, %h0|%h0, %2}"
9334   [(set_attr "type" "alu")
9335    (set_attr "mode" "QI")])
9336
9337 (define_expand "xorqi_cc_ext_1"
9338   [(parallel [
9339      (set (reg:CCNO FLAGS_REG)
9340           (compare:CCNO
9341             (xor:SI
9342               (zero_extract:SI
9343                 (match_operand 1 "ext_register_operand" "")
9344                 (const_int 8)
9345                 (const_int 8))
9346               (match_operand:QI 2 "general_operand" ""))
9347             (const_int 0)))
9348      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9349                            (const_int 8)
9350                            (const_int 8))
9351           (xor:SI 
9352             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9353             (match_dup 2)))])]
9354   ""
9355   "")
9356
9357 (define_split
9358   [(set (match_operand 0 "register_operand" "")
9359         (xor (match_operand 1 "register_operand" "")
9360              (match_operand 2 "const_int_operand" "")))
9361    (clobber (reg:CC FLAGS_REG))]
9362    "reload_completed
9363     && QI_REG_P (operands[0])
9364     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9365     && !(INTVAL (operands[2]) & ~(255 << 8))
9366     && GET_MODE (operands[0]) != QImode"
9367   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9368                    (xor:SI (zero_extract:SI (match_dup 1)
9369                                             (const_int 8) (const_int 8))
9370                            (match_dup 2)))
9371               (clobber (reg:CC FLAGS_REG))])]
9372   "operands[0] = gen_lowpart (SImode, operands[0]);
9373    operands[1] = gen_lowpart (SImode, operands[1]);
9374    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9375
9376 ;; Since XOR can be encoded with sign extended immediate, this is only
9377 ;; profitable when 7th bit is set.
9378 (define_split
9379   [(set (match_operand 0 "register_operand" "")
9380         (xor (match_operand 1 "general_operand" "")
9381              (match_operand 2 "const_int_operand" "")))
9382    (clobber (reg:CC FLAGS_REG))]
9383    "reload_completed
9384     && ANY_QI_REG_P (operands[0])
9385     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9386     && !(INTVAL (operands[2]) & ~255)
9387     && (INTVAL (operands[2]) & 128)
9388     && GET_MODE (operands[0]) != QImode"
9389   [(parallel [(set (strict_low_part (match_dup 0))
9390                    (xor:QI (match_dup 1)
9391                            (match_dup 2)))
9392               (clobber (reg:CC FLAGS_REG))])]
9393   "operands[0] = gen_lowpart (QImode, operands[0]);
9394    operands[1] = gen_lowpart (QImode, operands[1]);
9395    operands[2] = gen_lowpart (QImode, operands[2]);")
9396 \f
9397 ;; Negation instructions
9398
9399 (define_expand "negdi2"
9400   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9401                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9402               (clobber (reg:CC FLAGS_REG))])]
9403   ""
9404   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9405
9406 (define_insn "*negdi2_1"
9407   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9408         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9409    (clobber (reg:CC FLAGS_REG))]
9410   "!TARGET_64BIT
9411    && ix86_unary_operator_ok (NEG, DImode, operands)"
9412   "#")
9413
9414 (define_split
9415   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9416         (neg:DI (match_operand:DI 1 "general_operand" "")))
9417    (clobber (reg:CC FLAGS_REG))]
9418   "!TARGET_64BIT && reload_completed"
9419   [(parallel
9420     [(set (reg:CCZ FLAGS_REG)
9421           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9422      (set (match_dup 0) (neg:SI (match_dup 2)))])
9423    (parallel
9424     [(set (match_dup 1)
9425           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9426                             (match_dup 3))
9427                    (const_int 0)))
9428      (clobber (reg:CC FLAGS_REG))])
9429    (parallel
9430     [(set (match_dup 1)
9431           (neg:SI (match_dup 1)))
9432      (clobber (reg:CC FLAGS_REG))])]
9433   "split_di (operands+1, 1, operands+2, operands+3);
9434    split_di (operands+0, 1, operands+0, operands+1);")
9435
9436 (define_insn "*negdi2_1_rex64"
9437   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9438         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9439    (clobber (reg:CC FLAGS_REG))]
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 ;; The problem with neg is that it does not perform (compare x 0),
9446 ;; it really performs (compare 0 x), which leaves us with the zero
9447 ;; flag being the only useful item.
9448
9449 (define_insn "*negdi2_cmpz_rex64"
9450   [(set (reg:CCZ FLAGS_REG)
9451         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9452                      (const_int 0)))
9453    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9454         (neg:DI (match_dup 1)))]
9455   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9456   "neg{q}\t%0"
9457   [(set_attr "type" "negnot")
9458    (set_attr "mode" "DI")])
9459
9460
9461 (define_expand "negsi2"
9462   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9463                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9464               (clobber (reg:CC FLAGS_REG))])]
9465   ""
9466   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9467
9468 (define_insn "*negsi2_1"
9469   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9470         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9471    (clobber (reg:CC FLAGS_REG))]
9472   "ix86_unary_operator_ok (NEG, SImode, operands)"
9473   "neg{l}\t%0"
9474   [(set_attr "type" "negnot")
9475    (set_attr "mode" "SI")])
9476
9477 ;; Combine is quite creative about this pattern.
9478 (define_insn "*negsi2_1_zext"
9479   [(set (match_operand:DI 0 "register_operand" "=r")
9480         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9481                                         (const_int 32)))
9482                      (const_int 32)))
9483    (clobber (reg:CC FLAGS_REG))]
9484   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9485   "neg{l}\t%k0"
9486   [(set_attr "type" "negnot")
9487    (set_attr "mode" "SI")])
9488
9489 ;; The problem with neg is that it does not perform (compare x 0),
9490 ;; it really performs (compare 0 x), which leaves us with the zero
9491 ;; flag being the only useful item.
9492
9493 (define_insn "*negsi2_cmpz"
9494   [(set (reg:CCZ FLAGS_REG)
9495         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9496                      (const_int 0)))
9497    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9498         (neg:SI (match_dup 1)))]
9499   "ix86_unary_operator_ok (NEG, SImode, operands)"
9500   "neg{l}\t%0"
9501   [(set_attr "type" "negnot")
9502    (set_attr "mode" "SI")])
9503
9504 (define_insn "*negsi2_cmpz_zext"
9505   [(set (reg:CCZ FLAGS_REG)
9506         (compare:CCZ (lshiftrt:DI
9507                        (neg:DI (ashift:DI
9508                                  (match_operand:DI 1 "register_operand" "0")
9509                                  (const_int 32)))
9510                        (const_int 32))
9511                      (const_int 0)))
9512    (set (match_operand:DI 0 "register_operand" "=r")
9513         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9514                                         (const_int 32)))
9515                      (const_int 32)))]
9516   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9517   "neg{l}\t%k0"
9518   [(set_attr "type" "negnot")
9519    (set_attr "mode" "SI")])
9520
9521 (define_expand "neghi2"
9522   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9523                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9524               (clobber (reg:CC FLAGS_REG))])]
9525   "TARGET_HIMODE_MATH"
9526   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9527
9528 (define_insn "*neghi2_1"
9529   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9530         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9531    (clobber (reg:CC FLAGS_REG))]
9532   "ix86_unary_operator_ok (NEG, HImode, operands)"
9533   "neg{w}\t%0"
9534   [(set_attr "type" "negnot")
9535    (set_attr "mode" "HI")])
9536
9537 (define_insn "*neghi2_cmpz"
9538   [(set (reg:CCZ FLAGS_REG)
9539         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9540                      (const_int 0)))
9541    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9542         (neg:HI (match_dup 1)))]
9543   "ix86_unary_operator_ok (NEG, HImode, operands)"
9544   "neg{w}\t%0"
9545   [(set_attr "type" "negnot")
9546    (set_attr "mode" "HI")])
9547
9548 (define_expand "negqi2"
9549   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9550                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9551               (clobber (reg:CC FLAGS_REG))])]
9552   "TARGET_QIMODE_MATH"
9553   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9554
9555 (define_insn "*negqi2_1"
9556   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9557         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9558    (clobber (reg:CC FLAGS_REG))]
9559   "ix86_unary_operator_ok (NEG, QImode, operands)"
9560   "neg{b}\t%0"
9561   [(set_attr "type" "negnot")
9562    (set_attr "mode" "QI")])
9563
9564 (define_insn "*negqi2_cmpz"
9565   [(set (reg:CCZ FLAGS_REG)
9566         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9567                      (const_int 0)))
9568    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9569         (neg:QI (match_dup 1)))]
9570   "ix86_unary_operator_ok (NEG, QImode, operands)"
9571   "neg{b}\t%0"
9572   [(set_attr "type" "negnot")
9573    (set_attr "mode" "QI")])
9574
9575 ;; Changing of sign for FP values is doable using integer unit too.
9576
9577 (define_expand "negsf2"
9578   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9579         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9580   "TARGET_80387 || TARGET_SSE_MATH"
9581   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9582
9583 (define_expand "abssf2"
9584   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9585         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9586   "TARGET_80387 || TARGET_SSE_MATH"
9587   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9588
9589 (define_insn "*absnegsf2_mixed"
9590   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#fr,x#fr,f#xr,rm#xf")
9591         (match_operator:SF 3 "absneg_operator"
9592           [(match_operand:SF 1 "nonimmediate_operand" "0    ,x#fr,0   ,0")]))
9593    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm   ,0   ,X   ,X"))
9594    (clobber (reg:CC FLAGS_REG))]
9595   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9596    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9597   "#")
9598
9599 (define_insn "*absnegsf2_sse"
9600   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#r,x#r,rm#x")
9601         (match_operator:SF 3 "absneg_operator"
9602           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#r,0")]))
9603    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X"))
9604    (clobber (reg:CC FLAGS_REG))]
9605   "TARGET_SSE_MATH
9606    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9607   "#")
9608
9609 (define_insn "*absnegsf2_i387"
9610   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9611         (match_operator:SF 3 "absneg_operator"
9612           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9613    (use (match_operand 2 "" ""))
9614    (clobber (reg:CC FLAGS_REG))]
9615   "TARGET_80387 && !TARGET_SSE_MATH
9616    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9617   "#")
9618
9619 (define_expand "negdf2"
9620   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9621         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9622   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9623   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9624
9625 (define_expand "absdf2"
9626   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9627         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9628   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9629   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9630
9631 (define_insn "*absnegdf2_mixed"
9632   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#fr,Y#fr,f#Yr,rm#Yf")
9633         (match_operator:DF 3 "absneg_operator"
9634           [(match_operand:DF 1 "nonimmediate_operand" "0    ,Y#fr,0   ,0")]))
9635    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym   ,0   ,X   ,X"))
9636    (clobber (reg:CC FLAGS_REG))]
9637   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9638    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9639   "#")
9640
9641 (define_insn "*absnegdf2_sse"
9642   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#r,Y#r,rm#Y")
9643         (match_operator:DF 3 "absneg_operator"
9644           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#r,0")]))
9645    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X"))
9646    (clobber (reg:CC FLAGS_REG))]
9647   "TARGET_SSE2 && TARGET_SSE_MATH
9648    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9649   "#")
9650
9651 (define_insn "*absnegdf2_i387"
9652   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9653         (match_operator:DF 3 "absneg_operator"
9654           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9655    (use (match_operand 2 "" ""))
9656    (clobber (reg:CC FLAGS_REG))]
9657   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9658    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9659   "#")
9660
9661 (define_expand "negxf2"
9662   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9663         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9664   "TARGET_80387"
9665   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9666
9667 (define_expand "absxf2"
9668   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9669         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9670   "TARGET_80387"
9671   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9672
9673 (define_insn "*absnegxf2_i387"
9674   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9675         (match_operator:XF 3 "absneg_operator"
9676           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9677    (use (match_operand 2 "" ""))
9678    (clobber (reg:CC FLAGS_REG))]
9679   "TARGET_80387
9680    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9681   "#")
9682
9683 ;; Splitters for fp abs and neg.
9684
9685 (define_split
9686   [(set (match_operand 0 "fp_register_operand" "")
9687         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9688    (use (match_operand 2 "" ""))
9689    (clobber (reg:CC FLAGS_REG))]
9690   "reload_completed"
9691   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9692
9693 (define_split
9694   [(set (match_operand 0 "register_operand" "")
9695         (match_operator 3 "absneg_operator"
9696           [(match_operand 1 "register_operand" "")]))
9697    (use (match_operand 2 "nonimmediate_operand" ""))
9698    (clobber (reg:CC FLAGS_REG))]
9699   "reload_completed && SSE_REG_P (operands[0])"
9700   [(set (match_dup 0) (match_dup 3))]
9701 {
9702   enum machine_mode mode = GET_MODE (operands[0]);
9703   enum machine_mode vmode = GET_MODE (operands[2]);
9704   rtx tmp;
9705   
9706   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9707   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9708   if (operands_match_p (operands[0], operands[2]))
9709     {
9710       tmp = operands[1];
9711       operands[1] = operands[2];
9712       operands[2] = tmp;
9713     }
9714   if (GET_CODE (operands[3]) == ABS)
9715     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9716   else
9717     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9718   operands[3] = tmp;
9719 })
9720
9721 (define_split
9722   [(set (match_operand:SF 0 "register_operand" "")
9723         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9724    (use (match_operand:V4SF 2 "" ""))
9725    (clobber (reg:CC FLAGS_REG))]
9726   "reload_completed"
9727   [(parallel [(set (match_dup 0) (match_dup 1))
9728               (clobber (reg:CC FLAGS_REG))])]
9729
9730   rtx tmp;
9731   operands[0] = gen_lowpart (SImode, operands[0]);
9732   if (GET_CODE (operands[1]) == ABS)
9733     {
9734       tmp = gen_int_mode (0x7fffffff, SImode);
9735       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9736     }
9737   else
9738     {
9739       tmp = gen_int_mode (0x80000000, SImode);
9740       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9741     }
9742   operands[1] = tmp;
9743 })
9744
9745 (define_split
9746   [(set (match_operand:DF 0 "register_operand" "")
9747         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9748    (use (match_operand 2 "" ""))
9749    (clobber (reg:CC FLAGS_REG))]
9750   "reload_completed"
9751   [(parallel [(set (match_dup 0) (match_dup 1))
9752               (clobber (reg:CC FLAGS_REG))])]
9753 {
9754   rtx tmp;
9755   if (TARGET_64BIT)
9756     {
9757       tmp = gen_lowpart (DImode, operands[0]);
9758       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9759       operands[0] = tmp;
9760
9761       if (GET_CODE (operands[1]) == ABS)
9762         tmp = const0_rtx;
9763       else
9764         tmp = gen_rtx_NOT (DImode, tmp);
9765     }
9766   else
9767     {
9768       operands[0] = gen_highpart (SImode, operands[0]);
9769       if (GET_CODE (operands[1]) == ABS)
9770         {
9771           tmp = gen_int_mode (0x7fffffff, SImode);
9772           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9773         }
9774       else
9775         {
9776           tmp = gen_int_mode (0x80000000, SImode);
9777           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9778         }
9779     }
9780   operands[1] = tmp;
9781 })
9782
9783 (define_split
9784   [(set (match_operand:XF 0 "register_operand" "")
9785         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9786    (use (match_operand 2 "" ""))
9787    (clobber (reg:CC FLAGS_REG))]
9788   "reload_completed"
9789   [(parallel [(set (match_dup 0) (match_dup 1))
9790               (clobber (reg:CC FLAGS_REG))])]
9791 {
9792   rtx tmp;
9793   operands[0] = gen_rtx_REG (SImode,
9794                              true_regnum (operands[0])
9795                              + (TARGET_64BIT ? 1 : 2));
9796   if (GET_CODE (operands[1]) == ABS)
9797     {
9798       tmp = GEN_INT (0x7fff);
9799       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9800     }
9801   else
9802     {
9803       tmp = GEN_INT (0x8000);
9804       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9805     }
9806   operands[1] = tmp;
9807 })
9808
9809 (define_split
9810   [(set (match_operand 0 "memory_operand" "")
9811         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9812    (use (match_operand 2 "" ""))
9813    (clobber (reg:CC FLAGS_REG))]
9814   "reload_completed"
9815   [(parallel [(set (match_dup 0) (match_dup 1))
9816               (clobber (reg:CC FLAGS_REG))])]
9817 {
9818   enum machine_mode mode = GET_MODE (operands[0]);
9819   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9820   rtx tmp;
9821
9822   operands[0] = adjust_address (operands[0], QImode, size - 1);
9823   if (GET_CODE (operands[1]) == ABS)
9824     {
9825       tmp = gen_int_mode (0x7f, QImode);
9826       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9827     }
9828   else
9829     {
9830       tmp = gen_int_mode (0x80, QImode);
9831       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9832     }
9833   operands[1] = tmp;
9834 })
9835
9836 ;; Conditionalize these after reload. If they match before reload, we 
9837 ;; lose the clobber and ability to use integer instructions.
9838
9839 (define_insn "*negsf2_1"
9840   [(set (match_operand:SF 0 "register_operand" "=f")
9841         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9842   "TARGET_80387 && reload_completed"
9843   "fchs"
9844   [(set_attr "type" "fsgn")
9845    (set_attr "mode" "SF")])
9846
9847 (define_insn "*negdf2_1"
9848   [(set (match_operand:DF 0 "register_operand" "=f")
9849         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9850   "TARGET_80387 && reload_completed"
9851   "fchs"
9852   [(set_attr "type" "fsgn")
9853    (set_attr "mode" "DF")])
9854
9855 (define_insn "*negxf2_1"
9856   [(set (match_operand:XF 0 "register_operand" "=f")
9857         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9858   "TARGET_80387 && reload_completed"
9859   "fchs"
9860   [(set_attr "type" "fsgn")
9861    (set_attr "mode" "XF")])
9862
9863 (define_insn "*abssf2_1"
9864   [(set (match_operand:SF 0 "register_operand" "=f")
9865         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9866   "TARGET_80387 && reload_completed"
9867   "fabs"
9868   [(set_attr "type" "fsgn")
9869    (set_attr "mode" "SF")])
9870
9871 (define_insn "*absdf2_1"
9872   [(set (match_operand:DF 0 "register_operand" "=f")
9873         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9874   "TARGET_80387 && reload_completed"
9875   "fabs"
9876   [(set_attr "type" "fsgn")
9877    (set_attr "mode" "DF")])
9878
9879 (define_insn "*absxf2_1"
9880   [(set (match_operand:XF 0 "register_operand" "=f")
9881         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9882   "TARGET_80387 && reload_completed"
9883   "fabs"
9884   [(set_attr "type" "fsgn")
9885    (set_attr "mode" "DF")])
9886
9887 (define_insn "*negextendsfdf2"
9888   [(set (match_operand:DF 0 "register_operand" "=f")
9889         (neg:DF (float_extend:DF
9890                   (match_operand:SF 1 "register_operand" "0"))))]
9891   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9892   "fchs"
9893   [(set_attr "type" "fsgn")
9894    (set_attr "mode" "DF")])
9895
9896 (define_insn "*negextenddfxf2"
9897   [(set (match_operand:XF 0 "register_operand" "=f")
9898         (neg:XF (float_extend:XF
9899                   (match_operand:DF 1 "register_operand" "0"))))]
9900   "TARGET_80387"
9901   "fchs"
9902   [(set_attr "type" "fsgn")
9903    (set_attr "mode" "XF")])
9904
9905 (define_insn "*negextendsfxf2"
9906   [(set (match_operand:XF 0 "register_operand" "=f")
9907         (neg:XF (float_extend:XF
9908                   (match_operand:SF 1 "register_operand" "0"))))]
9909   "TARGET_80387"
9910   "fchs"
9911   [(set_attr "type" "fsgn")
9912    (set_attr "mode" "XF")])
9913
9914 (define_insn "*absextendsfdf2"
9915   [(set (match_operand:DF 0 "register_operand" "=f")
9916         (abs:DF (float_extend:DF
9917                   (match_operand:SF 1 "register_operand" "0"))))]
9918   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9919   "fabs"
9920   [(set_attr "type" "fsgn")
9921    (set_attr "mode" "DF")])
9922
9923 (define_insn "*absextenddfxf2"
9924   [(set (match_operand:XF 0 "register_operand" "=f")
9925         (abs:XF (float_extend:XF
9926           (match_operand:DF 1 "register_operand" "0"))))]
9927   "TARGET_80387"
9928   "fabs"
9929   [(set_attr "type" "fsgn")
9930    (set_attr "mode" "XF")])
9931
9932 (define_insn "*absextendsfxf2"
9933   [(set (match_operand:XF 0 "register_operand" "=f")
9934         (abs:XF (float_extend:XF
9935           (match_operand:SF 1 "register_operand" "0"))))]
9936   "TARGET_80387"
9937   "fabs"
9938   [(set_attr "type" "fsgn")
9939    (set_attr "mode" "XF")])
9940 \f
9941 ;; One complement instructions
9942
9943 (define_expand "one_cmpldi2"
9944   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9945         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9946   "TARGET_64BIT"
9947   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9948
9949 (define_insn "*one_cmpldi2_1_rex64"
9950   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9951         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9952   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9953   "not{q}\t%0"
9954   [(set_attr "type" "negnot")
9955    (set_attr "mode" "DI")])
9956
9957 (define_insn "*one_cmpldi2_2_rex64"
9958   [(set (reg FLAGS_REG)
9959         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9960                  (const_int 0)))
9961    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9962         (not:DI (match_dup 1)))]
9963   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9964    && ix86_unary_operator_ok (NOT, DImode, operands)"
9965   "#"
9966   [(set_attr "type" "alu1")
9967    (set_attr "mode" "DI")])
9968
9969 (define_split
9970   [(set (match_operand 0 "flags_reg_operand" "")
9971         (match_operator 2 "compare_operator"
9972           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9973            (const_int 0)]))
9974    (set (match_operand:DI 1 "nonimmediate_operand" "")
9975         (not:DI (match_dup 3)))]
9976   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9977   [(parallel [(set (match_dup 0)
9978                    (match_op_dup 2
9979                      [(xor:DI (match_dup 3) (const_int -1))
9980                       (const_int 0)]))
9981               (set (match_dup 1)
9982                    (xor:DI (match_dup 3) (const_int -1)))])]
9983   "")
9984
9985 (define_expand "one_cmplsi2"
9986   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9987         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9988   ""
9989   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9990
9991 (define_insn "*one_cmplsi2_1"
9992   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9993         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9994   "ix86_unary_operator_ok (NOT, SImode, operands)"
9995   "not{l}\t%0"
9996   [(set_attr "type" "negnot")
9997    (set_attr "mode" "SI")])
9998
9999 ;; ??? Currently never generated - xor is used instead.
10000 (define_insn "*one_cmplsi2_1_zext"
10001   [(set (match_operand:DI 0 "register_operand" "=r")
10002         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10003   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10004   "not{l}\t%k0"
10005   [(set_attr "type" "negnot")
10006    (set_attr "mode" "SI")])
10007
10008 (define_insn "*one_cmplsi2_2"
10009   [(set (reg FLAGS_REG)
10010         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10011                  (const_int 0)))
10012    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10013         (not:SI (match_dup 1)))]
10014   "ix86_match_ccmode (insn, CCNOmode)
10015    && ix86_unary_operator_ok (NOT, SImode, operands)"
10016   "#"
10017   [(set_attr "type" "alu1")
10018    (set_attr "mode" "SI")])
10019
10020 (define_split
10021   [(set (match_operand 0 "flags_reg_operand" "")
10022         (match_operator 2 "compare_operator"
10023           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10024            (const_int 0)]))
10025    (set (match_operand:SI 1 "nonimmediate_operand" "")
10026         (not:SI (match_dup 3)))]
10027   "ix86_match_ccmode (insn, CCNOmode)"
10028   [(parallel [(set (match_dup 0)
10029                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10030                                     (const_int 0)]))
10031               (set (match_dup 1)
10032                    (xor:SI (match_dup 3) (const_int -1)))])]
10033   "")
10034
10035 ;; ??? Currently never generated - xor is used instead.
10036 (define_insn "*one_cmplsi2_2_zext"
10037   [(set (reg FLAGS_REG)
10038         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10039                  (const_int 0)))
10040    (set (match_operand:DI 0 "register_operand" "=r")
10041         (zero_extend:DI (not:SI (match_dup 1))))]
10042   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10043    && ix86_unary_operator_ok (NOT, SImode, operands)"
10044   "#"
10045   [(set_attr "type" "alu1")
10046    (set_attr "mode" "SI")])
10047
10048 (define_split
10049   [(set (match_operand 0 "flags_reg_operand" "")
10050         (match_operator 2 "compare_operator"
10051           [(not:SI (match_operand:SI 3 "register_operand" ""))
10052            (const_int 0)]))
10053    (set (match_operand:DI 1 "register_operand" "")
10054         (zero_extend:DI (not:SI (match_dup 3))))]
10055   "ix86_match_ccmode (insn, CCNOmode)"
10056   [(parallel [(set (match_dup 0)
10057                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10058                                     (const_int 0)]))
10059               (set (match_dup 1)
10060                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10061   "")
10062
10063 (define_expand "one_cmplhi2"
10064   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10065         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10066   "TARGET_HIMODE_MATH"
10067   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10068
10069 (define_insn "*one_cmplhi2_1"
10070   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10071         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10072   "ix86_unary_operator_ok (NOT, HImode, operands)"
10073   "not{w}\t%0"
10074   [(set_attr "type" "negnot")
10075    (set_attr "mode" "HI")])
10076
10077 (define_insn "*one_cmplhi2_2"
10078   [(set (reg FLAGS_REG)
10079         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10080                  (const_int 0)))
10081    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10082         (not:HI (match_dup 1)))]
10083   "ix86_match_ccmode (insn, CCNOmode)
10084    && ix86_unary_operator_ok (NEG, HImode, operands)"
10085   "#"
10086   [(set_attr "type" "alu1")
10087    (set_attr "mode" "HI")])
10088
10089 (define_split
10090   [(set (match_operand 0 "flags_reg_operand" "")
10091         (match_operator 2 "compare_operator"
10092           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10093            (const_int 0)]))
10094    (set (match_operand:HI 1 "nonimmediate_operand" "")
10095         (not:HI (match_dup 3)))]
10096   "ix86_match_ccmode (insn, CCNOmode)"
10097   [(parallel [(set (match_dup 0)
10098                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10099                                     (const_int 0)]))
10100               (set (match_dup 1)
10101                    (xor:HI (match_dup 3) (const_int -1)))])]
10102   "")
10103
10104 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10105 (define_expand "one_cmplqi2"
10106   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10107         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10108   "TARGET_QIMODE_MATH"
10109   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10110
10111 (define_insn "*one_cmplqi2_1"
10112   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10113         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10114   "ix86_unary_operator_ok (NOT, QImode, operands)"
10115   "@
10116    not{b}\t%0
10117    not{l}\t%k0"
10118   [(set_attr "type" "negnot")
10119    (set_attr "mode" "QI,SI")])
10120
10121 (define_insn "*one_cmplqi2_2"
10122   [(set (reg FLAGS_REG)
10123         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10124                  (const_int 0)))
10125    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10126         (not:QI (match_dup 1)))]
10127   "ix86_match_ccmode (insn, CCNOmode)
10128    && ix86_unary_operator_ok (NOT, QImode, operands)"
10129   "#"
10130   [(set_attr "type" "alu1")
10131    (set_attr "mode" "QI")])
10132
10133 (define_split
10134   [(set (match_operand 0 "flags_reg_operand" "")
10135         (match_operator 2 "compare_operator"
10136           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10137            (const_int 0)]))
10138    (set (match_operand:QI 1 "nonimmediate_operand" "")
10139         (not:QI (match_dup 3)))]
10140   "ix86_match_ccmode (insn, CCNOmode)"
10141   [(parallel [(set (match_dup 0)
10142                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10143                                     (const_int 0)]))
10144               (set (match_dup 1)
10145                    (xor:QI (match_dup 3) (const_int -1)))])]
10146   "")
10147 \f
10148 ;; Arithmetic shift instructions
10149
10150 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10151 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10152 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10153 ;; from the assembler input.
10154 ;;
10155 ;; This instruction shifts the target reg/mem as usual, but instead of
10156 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10157 ;; is a left shift double, bits are taken from the high order bits of
10158 ;; reg, else if the insn is a shift right double, bits are taken from the
10159 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10160 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10161 ;;
10162 ;; Since sh[lr]d does not change the `reg' operand, that is done
10163 ;; separately, making all shifts emit pairs of shift double and normal
10164 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10165 ;; support a 63 bit shift, each shift where the count is in a reg expands
10166 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10167 ;;
10168 ;; If the shift count is a constant, we need never emit more than one
10169 ;; shift pair, instead using moves and sign extension for counts greater
10170 ;; than 31.
10171
10172 (define_expand "ashldi3"
10173   [(set (match_operand:DI 0 "shiftdi_operand" "")
10174         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10175                    (match_operand:QI 2 "nonmemory_operand" "")))]
10176   ""
10177   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10178
10179 (define_insn "*ashldi3_1_rex64"
10180   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10181         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10182                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10183    (clobber (reg:CC FLAGS_REG))]
10184   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10185 {
10186   switch (get_attr_type (insn))
10187     {
10188     case TYPE_ALU:
10189       if (operands[2] != const1_rtx)
10190         abort ();
10191       if (!rtx_equal_p (operands[0], operands[1]))
10192         abort ();
10193       return "add{q}\t{%0, %0|%0, %0}";
10194
10195     case TYPE_LEA:
10196       if (GET_CODE (operands[2]) != CONST_INT
10197           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10198         abort ();
10199       operands[1] = gen_rtx_MULT (DImode, operands[1],
10200                                   GEN_INT (1 << INTVAL (operands[2])));
10201       return "lea{q}\t{%a1, %0|%0, %a1}";
10202
10203     default:
10204       if (REG_P (operands[2]))
10205         return "sal{q}\t{%b2, %0|%0, %b2}";
10206       else if (operands[2] == const1_rtx
10207                && (TARGET_SHIFT1 || optimize_size))
10208         return "sal{q}\t%0";
10209       else
10210         return "sal{q}\t{%2, %0|%0, %2}";
10211     }
10212 }
10213   [(set (attr "type")
10214      (cond [(eq_attr "alternative" "1")
10215               (const_string "lea")
10216             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10217                           (const_int 0))
10218                       (match_operand 0 "register_operand" ""))
10219                  (match_operand 2 "const1_operand" ""))
10220               (const_string "alu")
10221            ]
10222            (const_string "ishift")))
10223    (set_attr "mode" "DI")])
10224
10225 ;; Convert lea to the lea pattern to avoid flags dependency.
10226 (define_split
10227   [(set (match_operand:DI 0 "register_operand" "")
10228         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10229                    (match_operand:QI 2 "immediate_operand" "")))
10230    (clobber (reg:CC FLAGS_REG))]
10231   "TARGET_64BIT && reload_completed
10232    && true_regnum (operands[0]) != true_regnum (operands[1])"
10233   [(set (match_dup 0)
10234         (mult:DI (match_dup 1)
10235                  (match_dup 2)))]
10236   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10237
10238 ;; This pattern can't accept a variable shift count, since shifts by
10239 ;; zero don't affect the flags.  We assume that shifts by constant
10240 ;; zero are optimized away.
10241 (define_insn "*ashldi3_cmp_rex64"
10242   [(set (reg FLAGS_REG)
10243         (compare
10244           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10245                      (match_operand:QI 2 "immediate_operand" "e"))
10246           (const_int 0)))
10247    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10248         (ashift:DI (match_dup 1) (match_dup 2)))]
10249   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10250    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10251 {
10252   switch (get_attr_type (insn))
10253     {
10254     case TYPE_ALU:
10255       if (operands[2] != const1_rtx)
10256         abort ();
10257       return "add{q}\t{%0, %0|%0, %0}";
10258
10259     default:
10260       if (REG_P (operands[2]))
10261         return "sal{q}\t{%b2, %0|%0, %b2}";
10262       else if (operands[2] == const1_rtx
10263                && (TARGET_SHIFT1 || optimize_size))
10264         return "sal{q}\t%0";
10265       else
10266         return "sal{q}\t{%2, %0|%0, %2}";
10267     }
10268 }
10269   [(set (attr "type")
10270      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10271                           (const_int 0))
10272                       (match_operand 0 "register_operand" ""))
10273                  (match_operand 2 "const1_operand" ""))
10274               (const_string "alu")
10275            ]
10276            (const_string "ishift")))
10277    (set_attr "mode" "DI")])
10278
10279 (define_insn "*ashldi3_1"
10280   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10281         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10282                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10283    (clobber (reg:CC FLAGS_REG))]
10284   "!TARGET_64BIT"
10285   "#"
10286   [(set_attr "type" "multi")])
10287
10288 ;; By default we don't ask for a scratch register, because when DImode
10289 ;; values are manipulated, registers are already at a premium.  But if
10290 ;; we have one handy, we won't turn it away.
10291 (define_peephole2
10292   [(match_scratch:SI 3 "r")
10293    (parallel [(set (match_operand:DI 0 "register_operand" "")
10294                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10295                               (match_operand:QI 2 "nonmemory_operand" "")))
10296               (clobber (reg:CC FLAGS_REG))])
10297    (match_dup 3)]
10298   "!TARGET_64BIT && TARGET_CMOVE"
10299   [(const_int 0)]
10300   "ix86_split_ashldi (operands, operands[3]); DONE;")
10301
10302 (define_split
10303   [(set (match_operand:DI 0 "register_operand" "")
10304         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10305                    (match_operand:QI 2 "nonmemory_operand" "")))
10306    (clobber (reg:CC FLAGS_REG))]
10307   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10308   [(const_int 0)]
10309   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10310
10311 (define_insn "x86_shld_1"
10312   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10313         (ior:SI (ashift:SI (match_dup 0)
10314                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10315                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10316                   (minus:QI (const_int 32) (match_dup 2)))))
10317    (clobber (reg:CC FLAGS_REG))]
10318   ""
10319   "@
10320    shld{l}\t{%2, %1, %0|%0, %1, %2}
10321    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10322   [(set_attr "type" "ishift")
10323    (set_attr "prefix_0f" "1")
10324    (set_attr "mode" "SI")
10325    (set_attr "pent_pair" "np")
10326    (set_attr "athlon_decode" "vector")])
10327
10328 (define_expand "x86_shift_adj_1"
10329   [(set (reg:CCZ FLAGS_REG)
10330         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10331                              (const_int 32))
10332                      (const_int 0)))
10333    (set (match_operand:SI 0 "register_operand" "")
10334         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10335                          (match_operand:SI 1 "register_operand" "")
10336                          (match_dup 0)))
10337    (set (match_dup 1)
10338         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10339                          (match_operand:SI 3 "register_operand" "r")
10340                          (match_dup 1)))]
10341   "TARGET_CMOVE"
10342   "")
10343
10344 (define_expand "x86_shift_adj_2"
10345   [(use (match_operand:SI 0 "register_operand" ""))
10346    (use (match_operand:SI 1 "register_operand" ""))
10347    (use (match_operand:QI 2 "register_operand" ""))]
10348   ""
10349 {
10350   rtx label = gen_label_rtx ();
10351   rtx tmp;
10352
10353   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10354
10355   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10356   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10357   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10358                               gen_rtx_LABEL_REF (VOIDmode, label),
10359                               pc_rtx);
10360   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10361   JUMP_LABEL (tmp) = label;
10362
10363   emit_move_insn (operands[0], operands[1]);
10364   ix86_expand_clear (operands[1]);
10365
10366   emit_label (label);
10367   LABEL_NUSES (label) = 1;
10368
10369   DONE;
10370 })
10371
10372 (define_expand "ashlsi3"
10373   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10374         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10375                    (match_operand:QI 2 "nonmemory_operand" "")))
10376    (clobber (reg:CC FLAGS_REG))]
10377   ""
10378   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10379
10380 (define_insn "*ashlsi3_1"
10381   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10382         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10383                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10384    (clobber (reg:CC FLAGS_REG))]
10385   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10386 {
10387   switch (get_attr_type (insn))
10388     {
10389     case TYPE_ALU:
10390       if (operands[2] != const1_rtx)
10391         abort ();
10392       if (!rtx_equal_p (operands[0], operands[1]))
10393         abort ();
10394       return "add{l}\t{%0, %0|%0, %0}";
10395
10396     case TYPE_LEA:
10397       return "#";
10398
10399     default:
10400       if (REG_P (operands[2]))
10401         return "sal{l}\t{%b2, %0|%0, %b2}";
10402       else if (operands[2] == const1_rtx
10403                && (TARGET_SHIFT1 || optimize_size))
10404         return "sal{l}\t%0";
10405       else
10406         return "sal{l}\t{%2, %0|%0, %2}";
10407     }
10408 }
10409   [(set (attr "type")
10410      (cond [(eq_attr "alternative" "1")
10411               (const_string "lea")
10412             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10413                           (const_int 0))
10414                       (match_operand 0 "register_operand" ""))
10415                  (match_operand 2 "const1_operand" ""))
10416               (const_string "alu")
10417            ]
10418            (const_string "ishift")))
10419    (set_attr "mode" "SI")])
10420
10421 ;; Convert lea to the lea pattern to avoid flags dependency.
10422 (define_split
10423   [(set (match_operand 0 "register_operand" "")
10424         (ashift (match_operand 1 "index_register_operand" "")
10425                 (match_operand:QI 2 "const_int_operand" "")))
10426    (clobber (reg:CC FLAGS_REG))]
10427   "reload_completed
10428    && true_regnum (operands[0]) != true_regnum (operands[1])
10429    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10430   [(const_int 0)]
10431 {
10432   rtx pat;
10433   enum machine_mode mode = GET_MODE (operands[0]);
10434
10435   if (GET_MODE_SIZE (mode) < 4)
10436     operands[0] = gen_lowpart (SImode, operands[0]);
10437   if (mode != Pmode)
10438     operands[1] = gen_lowpart (Pmode, operands[1]);
10439   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10440
10441   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10442   if (Pmode != SImode)
10443     pat = gen_rtx_SUBREG (SImode, pat, 0);
10444   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10445   DONE;
10446 })
10447
10448 ;; Rare case of shifting RSP is handled by generating move and shift
10449 (define_split
10450   [(set (match_operand 0 "register_operand" "")
10451         (ashift (match_operand 1 "register_operand" "")
10452                 (match_operand:QI 2 "const_int_operand" "")))
10453    (clobber (reg:CC FLAGS_REG))]
10454   "reload_completed
10455    && true_regnum (operands[0]) != true_regnum (operands[1])"
10456   [(const_int 0)]
10457 {
10458   rtx pat, clob;
10459   emit_move_insn (operands[1], operands[0]);
10460   pat = gen_rtx_SET (VOIDmode, operands[0],
10461                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10462                                      operands[0], operands[2]));
10463   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10464   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10465   DONE;
10466 })
10467
10468 (define_insn "*ashlsi3_1_zext"
10469   [(set (match_operand:DI 0 "register_operand" "=r,r")
10470         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10471                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10472    (clobber (reg:CC FLAGS_REG))]
10473   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10474 {
10475   switch (get_attr_type (insn))
10476     {
10477     case TYPE_ALU:
10478       if (operands[2] != const1_rtx)
10479         abort ();
10480       return "add{l}\t{%k0, %k0|%k0, %k0}";
10481
10482     case TYPE_LEA:
10483       return "#";
10484
10485     default:
10486       if (REG_P (operands[2]))
10487         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10488       else if (operands[2] == const1_rtx
10489                && (TARGET_SHIFT1 || optimize_size))
10490         return "sal{l}\t%k0";
10491       else
10492         return "sal{l}\t{%2, %k0|%k0, %2}";
10493     }
10494 }
10495   [(set (attr "type")
10496      (cond [(eq_attr "alternative" "1")
10497               (const_string "lea")
10498             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10499                      (const_int 0))
10500                  (match_operand 2 "const1_operand" ""))
10501               (const_string "alu")
10502            ]
10503            (const_string "ishift")))
10504    (set_attr "mode" "SI")])
10505
10506 ;; Convert lea to the lea pattern to avoid flags dependency.
10507 (define_split
10508   [(set (match_operand:DI 0 "register_operand" "")
10509         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10510                                 (match_operand:QI 2 "const_int_operand" ""))))
10511    (clobber (reg:CC FLAGS_REG))]
10512   "TARGET_64BIT && reload_completed
10513    && true_regnum (operands[0]) != true_regnum (operands[1])"
10514   [(set (match_dup 0) (zero_extend:DI
10515                         (subreg:SI (mult:SI (match_dup 1)
10516                                             (match_dup 2)) 0)))]
10517 {
10518   operands[1] = gen_lowpart (Pmode, operands[1]);
10519   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10520 })
10521
10522 ;; This pattern can't accept a variable shift count, since shifts by
10523 ;; zero don't affect the flags.  We assume that shifts by constant
10524 ;; zero are optimized away.
10525 (define_insn "*ashlsi3_cmp"
10526   [(set (reg FLAGS_REG)
10527         (compare
10528           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10529                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10530           (const_int 0)))
10531    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10532         (ashift:SI (match_dup 1) (match_dup 2)))]
10533   "ix86_match_ccmode (insn, CCGOCmode)
10534    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10535 {
10536   switch (get_attr_type (insn))
10537     {
10538     case TYPE_ALU:
10539       if (operands[2] != const1_rtx)
10540         abort ();
10541       return "add{l}\t{%0, %0|%0, %0}";
10542
10543     default:
10544       if (REG_P (operands[2]))
10545         return "sal{l}\t{%b2, %0|%0, %b2}";
10546       else if (operands[2] == const1_rtx
10547                && (TARGET_SHIFT1 || optimize_size))
10548         return "sal{l}\t%0";
10549       else
10550         return "sal{l}\t{%2, %0|%0, %2}";
10551     }
10552 }
10553   [(set (attr "type")
10554      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10555                           (const_int 0))
10556                       (match_operand 0 "register_operand" ""))
10557                  (match_operand 2 "const1_operand" ""))
10558               (const_string "alu")
10559            ]
10560            (const_string "ishift")))
10561    (set_attr "mode" "SI")])
10562
10563 (define_insn "*ashlsi3_cmp_zext"
10564   [(set (reg FLAGS_REG)
10565         (compare
10566           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10567                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10568           (const_int 0)))
10569    (set (match_operand:DI 0 "register_operand" "=r")
10570         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10571   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10572    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10573 {
10574   switch (get_attr_type (insn))
10575     {
10576     case TYPE_ALU:
10577       if (operands[2] != const1_rtx)
10578         abort ();
10579       return "add{l}\t{%k0, %k0|%k0, %k0}";
10580
10581     default:
10582       if (REG_P (operands[2]))
10583         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10584       else if (operands[2] == const1_rtx
10585                && (TARGET_SHIFT1 || optimize_size))
10586         return "sal{l}\t%k0";
10587       else
10588         return "sal{l}\t{%2, %k0|%k0, %2}";
10589     }
10590 }
10591   [(set (attr "type")
10592      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10593                      (const_int 0))
10594                  (match_operand 2 "const1_operand" ""))
10595               (const_string "alu")
10596            ]
10597            (const_string "ishift")))
10598    (set_attr "mode" "SI")])
10599
10600 (define_expand "ashlhi3"
10601   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10602         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10603                    (match_operand:QI 2 "nonmemory_operand" "")))
10604    (clobber (reg:CC FLAGS_REG))]
10605   "TARGET_HIMODE_MATH"
10606   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10607
10608 (define_insn "*ashlhi3_1_lea"
10609   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10610         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10611                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10612    (clobber (reg:CC FLAGS_REG))]
10613   "!TARGET_PARTIAL_REG_STALL
10614    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10615 {
10616   switch (get_attr_type (insn))
10617     {
10618     case TYPE_LEA:
10619       return "#";
10620     case TYPE_ALU:
10621       if (operands[2] != const1_rtx)
10622         abort ();
10623       return "add{w}\t{%0, %0|%0, %0}";
10624
10625     default:
10626       if (REG_P (operands[2]))
10627         return "sal{w}\t{%b2, %0|%0, %b2}";
10628       else if (operands[2] == const1_rtx
10629                && (TARGET_SHIFT1 || optimize_size))
10630         return "sal{w}\t%0";
10631       else
10632         return "sal{w}\t{%2, %0|%0, %2}";
10633     }
10634 }
10635   [(set (attr "type")
10636      (cond [(eq_attr "alternative" "1")
10637               (const_string "lea")
10638             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10639                           (const_int 0))
10640                       (match_operand 0 "register_operand" ""))
10641                  (match_operand 2 "const1_operand" ""))
10642               (const_string "alu")
10643            ]
10644            (const_string "ishift")))
10645    (set_attr "mode" "HI,SI")])
10646
10647 (define_insn "*ashlhi3_1"
10648   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10649         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10650                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10651    (clobber (reg:CC FLAGS_REG))]
10652   "TARGET_PARTIAL_REG_STALL
10653    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10654 {
10655   switch (get_attr_type (insn))
10656     {
10657     case TYPE_ALU:
10658       if (operands[2] != const1_rtx)
10659         abort ();
10660       return "add{w}\t{%0, %0|%0, %0}";
10661
10662     default:
10663       if (REG_P (operands[2]))
10664         return "sal{w}\t{%b2, %0|%0, %b2}";
10665       else if (operands[2] == const1_rtx
10666                && (TARGET_SHIFT1 || optimize_size))
10667         return "sal{w}\t%0";
10668       else
10669         return "sal{w}\t{%2, %0|%0, %2}";
10670     }
10671 }
10672   [(set (attr "type")
10673      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10674                           (const_int 0))
10675                       (match_operand 0 "register_operand" ""))
10676                  (match_operand 2 "const1_operand" ""))
10677               (const_string "alu")
10678            ]
10679            (const_string "ishift")))
10680    (set_attr "mode" "HI")])
10681
10682 ;; This pattern can't accept a variable shift count, since shifts by
10683 ;; zero don't affect the flags.  We assume that shifts by constant
10684 ;; zero are optimized away.
10685 (define_insn "*ashlhi3_cmp"
10686   [(set (reg FLAGS_REG)
10687         (compare
10688           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10689                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10690           (const_int 0)))
10691    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10692         (ashift:HI (match_dup 1) (match_dup 2)))]
10693   "ix86_match_ccmode (insn, CCGOCmode)
10694    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10695 {
10696   switch (get_attr_type (insn))
10697     {
10698     case TYPE_ALU:
10699       if (operands[2] != const1_rtx)
10700         abort ();
10701       return "add{w}\t{%0, %0|%0, %0}";
10702
10703     default:
10704       if (REG_P (operands[2]))
10705         return "sal{w}\t{%b2, %0|%0, %b2}";
10706       else if (operands[2] == const1_rtx
10707                && (TARGET_SHIFT1 || optimize_size))
10708         return "sal{w}\t%0";
10709       else
10710         return "sal{w}\t{%2, %0|%0, %2}";
10711     }
10712 }
10713   [(set (attr "type")
10714      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10715                           (const_int 0))
10716                       (match_operand 0 "register_operand" ""))
10717                  (match_operand 2 "const1_operand" ""))
10718               (const_string "alu")
10719            ]
10720            (const_string "ishift")))
10721    (set_attr "mode" "HI")])
10722
10723 (define_expand "ashlqi3"
10724   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10725         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10726                    (match_operand:QI 2 "nonmemory_operand" "")))
10727    (clobber (reg:CC FLAGS_REG))]
10728   "TARGET_QIMODE_MATH"
10729   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10730
10731 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10732
10733 (define_insn "*ashlqi3_1_lea"
10734   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10735         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10736                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10737    (clobber (reg:CC FLAGS_REG))]
10738   "!TARGET_PARTIAL_REG_STALL
10739    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10740 {
10741   switch (get_attr_type (insn))
10742     {
10743     case TYPE_LEA:
10744       return "#";
10745     case TYPE_ALU:
10746       if (operands[2] != const1_rtx)
10747         abort ();
10748       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10749         return "add{l}\t{%k0, %k0|%k0, %k0}";
10750       else
10751         return "add{b}\t{%0, %0|%0, %0}";
10752
10753     default:
10754       if (REG_P (operands[2]))
10755         {
10756           if (get_attr_mode (insn) == MODE_SI)
10757             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10758           else
10759             return "sal{b}\t{%b2, %0|%0, %b2}";
10760         }
10761       else if (operands[2] == const1_rtx
10762                && (TARGET_SHIFT1 || optimize_size))
10763         {
10764           if (get_attr_mode (insn) == MODE_SI)
10765             return "sal{l}\t%0";
10766           else
10767             return "sal{b}\t%0";
10768         }
10769       else
10770         {
10771           if (get_attr_mode (insn) == MODE_SI)
10772             return "sal{l}\t{%2, %k0|%k0, %2}";
10773           else
10774             return "sal{b}\t{%2, %0|%0, %2}";
10775         }
10776     }
10777 }
10778   [(set (attr "type")
10779      (cond [(eq_attr "alternative" "2")
10780               (const_string "lea")
10781             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10782                           (const_int 0))
10783                       (match_operand 0 "register_operand" ""))
10784                  (match_operand 2 "const1_operand" ""))
10785               (const_string "alu")
10786            ]
10787            (const_string "ishift")))
10788    (set_attr "mode" "QI,SI,SI")])
10789
10790 (define_insn "*ashlqi3_1"
10791   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10792         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10793                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10794    (clobber (reg:CC FLAGS_REG))]
10795   "TARGET_PARTIAL_REG_STALL
10796    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10797 {
10798   switch (get_attr_type (insn))
10799     {
10800     case TYPE_ALU:
10801       if (operands[2] != const1_rtx)
10802         abort ();
10803       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10804         return "add{l}\t{%k0, %k0|%k0, %k0}";
10805       else
10806         return "add{b}\t{%0, %0|%0, %0}";
10807
10808     default:
10809       if (REG_P (operands[2]))
10810         {
10811           if (get_attr_mode (insn) == MODE_SI)
10812             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10813           else
10814             return "sal{b}\t{%b2, %0|%0, %b2}";
10815         }
10816       else if (operands[2] == const1_rtx
10817                && (TARGET_SHIFT1 || optimize_size))
10818         {
10819           if (get_attr_mode (insn) == MODE_SI)
10820             return "sal{l}\t%0";
10821           else
10822             return "sal{b}\t%0";
10823         }
10824       else
10825         {
10826           if (get_attr_mode (insn) == MODE_SI)
10827             return "sal{l}\t{%2, %k0|%k0, %2}";
10828           else
10829             return "sal{b}\t{%2, %0|%0, %2}";
10830         }
10831     }
10832 }
10833   [(set (attr "type")
10834      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10835                           (const_int 0))
10836                       (match_operand 0 "register_operand" ""))
10837                  (match_operand 2 "const1_operand" ""))
10838               (const_string "alu")
10839            ]
10840            (const_string "ishift")))
10841    (set_attr "mode" "QI,SI")])
10842
10843 ;; This pattern can't accept a variable shift count, since shifts by
10844 ;; zero don't affect the flags.  We assume that shifts by constant
10845 ;; zero are optimized away.
10846 (define_insn "*ashlqi3_cmp"
10847   [(set (reg FLAGS_REG)
10848         (compare
10849           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10850                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10851           (const_int 0)))
10852    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10853         (ashift:QI (match_dup 1) (match_dup 2)))]
10854   "ix86_match_ccmode (insn, CCGOCmode)
10855    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10856 {
10857   switch (get_attr_type (insn))
10858     {
10859     case TYPE_ALU:
10860       if (operands[2] != const1_rtx)
10861         abort ();
10862       return "add{b}\t{%0, %0|%0, %0}";
10863
10864     default:
10865       if (REG_P (operands[2]))
10866         return "sal{b}\t{%b2, %0|%0, %b2}";
10867       else if (operands[2] == const1_rtx
10868                && (TARGET_SHIFT1 || optimize_size))
10869         return "sal{b}\t%0";
10870       else
10871         return "sal{b}\t{%2, %0|%0, %2}";
10872     }
10873 }
10874   [(set (attr "type")
10875      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10876                           (const_int 0))
10877                       (match_operand 0 "register_operand" ""))
10878                  (match_operand 2 "const1_operand" ""))
10879               (const_string "alu")
10880            ]
10881            (const_string "ishift")))
10882    (set_attr "mode" "QI")])
10883
10884 ;; See comment above `ashldi3' about how this works.
10885
10886 (define_expand "ashrdi3"
10887   [(set (match_operand:DI 0 "shiftdi_operand" "")
10888         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10889                      (match_operand:QI 2 "nonmemory_operand" "")))]
10890   ""
10891   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10892
10893 (define_insn "*ashrdi3_63_rex64"
10894   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10895         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10896                      (match_operand:DI 2 "const_int_operand" "i,i")))
10897    (clobber (reg:CC FLAGS_REG))]
10898   "TARGET_64BIT && INTVAL (operands[2]) == 63
10899    && (TARGET_USE_CLTD || optimize_size)
10900    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10901   "@
10902    {cqto|cqo}
10903    sar{q}\t{%2, %0|%0, %2}"
10904   [(set_attr "type" "imovx,ishift")
10905    (set_attr "prefix_0f" "0,*")
10906    (set_attr "length_immediate" "0,*")
10907    (set_attr "modrm" "0,1")
10908    (set_attr "mode" "DI")])
10909
10910 (define_insn "*ashrdi3_1_one_bit_rex64"
10911   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10912         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10913                      (match_operand:QI 2 "const1_operand" "")))
10914    (clobber (reg:CC FLAGS_REG))]
10915   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10916    && (TARGET_SHIFT1 || optimize_size)"
10917   "sar{q}\t%0"
10918   [(set_attr "type" "ishift")
10919    (set (attr "length") 
10920      (if_then_else (match_operand:DI 0 "register_operand" "") 
10921         (const_string "2")
10922         (const_string "*")))])
10923
10924 (define_insn "*ashrdi3_1_rex64"
10925   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10926         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10927                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10928    (clobber (reg:CC FLAGS_REG))]
10929   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10930   "@
10931    sar{q}\t{%2, %0|%0, %2}
10932    sar{q}\t{%b2, %0|%0, %b2}"
10933   [(set_attr "type" "ishift")
10934    (set_attr "mode" "DI")])
10935
10936 ;; This pattern can't accept a variable shift count, since shifts by
10937 ;; zero don't affect the flags.  We assume that shifts by constant
10938 ;; zero are optimized away.
10939 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10940   [(set (reg FLAGS_REG)
10941         (compare
10942           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10943                        (match_operand:QI 2 "const1_operand" ""))
10944           (const_int 0)))
10945    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10946         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10947   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10948    && (TARGET_SHIFT1 || optimize_size)
10949    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10950   "sar{q}\t%0"
10951   [(set_attr "type" "ishift")
10952    (set (attr "length") 
10953      (if_then_else (match_operand:DI 0 "register_operand" "") 
10954         (const_string "2")
10955         (const_string "*")))])
10956
10957 ;; This pattern can't accept a variable shift count, since shifts by
10958 ;; zero don't affect the flags.  We assume that shifts by constant
10959 ;; zero are optimized away.
10960 (define_insn "*ashrdi3_cmp_rex64"
10961   [(set (reg FLAGS_REG)
10962         (compare
10963           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10964                        (match_operand:QI 2 "const_int_operand" "n"))
10965           (const_int 0)))
10966    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10967         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10968   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10969    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10970   "sar{q}\t{%2, %0|%0, %2}"
10971   [(set_attr "type" "ishift")
10972    (set_attr "mode" "DI")])
10973
10974 (define_insn "*ashrdi3_1"
10975   [(set (match_operand:DI 0 "register_operand" "=r")
10976         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10977                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10978    (clobber (reg:CC FLAGS_REG))]
10979   "!TARGET_64BIT"
10980   "#"
10981   [(set_attr "type" "multi")])
10982
10983 ;; By default we don't ask for a scratch register, because when DImode
10984 ;; values are manipulated, registers are already at a premium.  But if
10985 ;; we have one handy, we won't turn it away.
10986 (define_peephole2
10987   [(match_scratch:SI 3 "r")
10988    (parallel [(set (match_operand:DI 0 "register_operand" "")
10989                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10990                                 (match_operand:QI 2 "nonmemory_operand" "")))
10991               (clobber (reg:CC FLAGS_REG))])
10992    (match_dup 3)]
10993   "!TARGET_64BIT && TARGET_CMOVE"
10994   [(const_int 0)]
10995   "ix86_split_ashrdi (operands, operands[3]); DONE;")
10996
10997 (define_split
10998   [(set (match_operand:DI 0 "register_operand" "")
10999         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11000                      (match_operand:QI 2 "nonmemory_operand" "")))
11001    (clobber (reg:CC FLAGS_REG))]
11002   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11003   [(const_int 0)]
11004   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11005
11006 (define_insn "x86_shrd_1"
11007   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11008         (ior:SI (ashiftrt:SI (match_dup 0)
11009                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11010                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11011                   (minus:QI (const_int 32) (match_dup 2)))))
11012    (clobber (reg:CC FLAGS_REG))]
11013   ""
11014   "@
11015    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11016    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11017   [(set_attr "type" "ishift")
11018    (set_attr "prefix_0f" "1")
11019    (set_attr "pent_pair" "np")
11020    (set_attr "mode" "SI")])
11021
11022 (define_expand "x86_shift_adj_3"
11023   [(use (match_operand:SI 0 "register_operand" ""))
11024    (use (match_operand:SI 1 "register_operand" ""))
11025    (use (match_operand:QI 2 "register_operand" ""))]
11026   ""
11027 {
11028   rtx label = gen_label_rtx ();
11029   rtx tmp;
11030
11031   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11032
11033   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11034   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11035   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11036                               gen_rtx_LABEL_REF (VOIDmode, label),
11037                               pc_rtx);
11038   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11039   JUMP_LABEL (tmp) = label;
11040
11041   emit_move_insn (operands[0], operands[1]);
11042   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11043
11044   emit_label (label);
11045   LABEL_NUSES (label) = 1;
11046
11047   DONE;
11048 })
11049
11050 (define_insn "ashrsi3_31"
11051   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11052         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11053                      (match_operand:SI 2 "const_int_operand" "i,i")))
11054    (clobber (reg:CC FLAGS_REG))]
11055   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11056    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11057   "@
11058    {cltd|cdq}
11059    sar{l}\t{%2, %0|%0, %2}"
11060   [(set_attr "type" "imovx,ishift")
11061    (set_attr "prefix_0f" "0,*")
11062    (set_attr "length_immediate" "0,*")
11063    (set_attr "modrm" "0,1")
11064    (set_attr "mode" "SI")])
11065
11066 (define_insn "*ashrsi3_31_zext"
11067   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11068         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11069                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11070    (clobber (reg:CC FLAGS_REG))]
11071   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11072    && INTVAL (operands[2]) == 31
11073    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11074   "@
11075    {cltd|cdq}
11076    sar{l}\t{%2, %k0|%k0, %2}"
11077   [(set_attr "type" "imovx,ishift")
11078    (set_attr "prefix_0f" "0,*")
11079    (set_attr "length_immediate" "0,*")
11080    (set_attr "modrm" "0,1")
11081    (set_attr "mode" "SI")])
11082
11083 (define_expand "ashrsi3"
11084   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11085         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11086                      (match_operand:QI 2 "nonmemory_operand" "")))
11087    (clobber (reg:CC FLAGS_REG))]
11088   ""
11089   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11090
11091 (define_insn "*ashrsi3_1_one_bit"
11092   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11093         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11094                      (match_operand:QI 2 "const1_operand" "")))
11095    (clobber (reg:CC FLAGS_REG))]
11096   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11097    && (TARGET_SHIFT1 || optimize_size)"
11098   "sar{l}\t%0"
11099   [(set_attr "type" "ishift")
11100    (set (attr "length") 
11101      (if_then_else (match_operand:SI 0 "register_operand" "") 
11102         (const_string "2")
11103         (const_string "*")))])
11104
11105 (define_insn "*ashrsi3_1_one_bit_zext"
11106   [(set (match_operand:DI 0 "register_operand" "=r")
11107         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11108                                      (match_operand:QI 2 "const1_operand" ""))))
11109    (clobber (reg:CC FLAGS_REG))]
11110   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11111    && (TARGET_SHIFT1 || optimize_size)"
11112   "sar{l}\t%k0"
11113   [(set_attr "type" "ishift")
11114    (set_attr "length" "2")])
11115
11116 (define_insn "*ashrsi3_1"
11117   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11118         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11119                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11120    (clobber (reg:CC FLAGS_REG))]
11121   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11122   "@
11123    sar{l}\t{%2, %0|%0, %2}
11124    sar{l}\t{%b2, %0|%0, %b2}"
11125   [(set_attr "type" "ishift")
11126    (set_attr "mode" "SI")])
11127
11128 (define_insn "*ashrsi3_1_zext"
11129   [(set (match_operand:DI 0 "register_operand" "=r,r")
11130         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11131                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11132    (clobber (reg:CC FLAGS_REG))]
11133   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11134   "@
11135    sar{l}\t{%2, %k0|%k0, %2}
11136    sar{l}\t{%b2, %k0|%k0, %b2}"
11137   [(set_attr "type" "ishift")
11138    (set_attr "mode" "SI")])
11139
11140 ;; This pattern can't accept a variable shift count, since shifts by
11141 ;; zero don't affect the flags.  We assume that shifts by constant
11142 ;; zero are optimized away.
11143 (define_insn "*ashrsi3_one_bit_cmp"
11144   [(set (reg FLAGS_REG)
11145         (compare
11146           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11147                        (match_operand:QI 2 "const1_operand" ""))
11148           (const_int 0)))
11149    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11150         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11151   "ix86_match_ccmode (insn, CCGOCmode)
11152    && (TARGET_SHIFT1 || optimize_size)
11153    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11154   "sar{l}\t%0"
11155   [(set_attr "type" "ishift")
11156    (set (attr "length") 
11157      (if_then_else (match_operand:SI 0 "register_operand" "") 
11158         (const_string "2")
11159         (const_string "*")))])
11160
11161 (define_insn "*ashrsi3_one_bit_cmp_zext"
11162   [(set (reg FLAGS_REG)
11163         (compare
11164           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11165                        (match_operand:QI 2 "const1_operand" ""))
11166           (const_int 0)))
11167    (set (match_operand:DI 0 "register_operand" "=r")
11168         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11169   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11170    && (TARGET_SHIFT1 || optimize_size)
11171    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11172   "sar{l}\t%k0"
11173   [(set_attr "type" "ishift")
11174    (set_attr "length" "2")])
11175
11176 ;; This pattern can't accept a variable shift count, since shifts by
11177 ;; zero don't affect the flags.  We assume that shifts by constant
11178 ;; zero are optimized away.
11179 (define_insn "*ashrsi3_cmp"
11180   [(set (reg FLAGS_REG)
11181         (compare
11182           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11183                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11184           (const_int 0)))
11185    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11186         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11187   "ix86_match_ccmode (insn, CCGOCmode)
11188    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11189   "sar{l}\t{%2, %0|%0, %2}"
11190   [(set_attr "type" "ishift")
11191    (set_attr "mode" "SI")])
11192
11193 (define_insn "*ashrsi3_cmp_zext"
11194   [(set (reg FLAGS_REG)
11195         (compare
11196           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11197                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11198           (const_int 0)))
11199    (set (match_operand:DI 0 "register_operand" "=r")
11200         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11201   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11202    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11203   "sar{l}\t{%2, %k0|%k0, %2}"
11204   [(set_attr "type" "ishift")
11205    (set_attr "mode" "SI")])
11206
11207 (define_expand "ashrhi3"
11208   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11209         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11210                      (match_operand:QI 2 "nonmemory_operand" "")))
11211    (clobber (reg:CC FLAGS_REG))]
11212   "TARGET_HIMODE_MATH"
11213   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11214
11215 (define_insn "*ashrhi3_1_one_bit"
11216   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11217         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11218                      (match_operand:QI 2 "const1_operand" "")))
11219    (clobber (reg:CC FLAGS_REG))]
11220   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11221    && (TARGET_SHIFT1 || optimize_size)"
11222   "sar{w}\t%0"
11223   [(set_attr "type" "ishift")
11224    (set (attr "length") 
11225      (if_then_else (match_operand 0 "register_operand" "") 
11226         (const_string "2")
11227         (const_string "*")))])
11228
11229 (define_insn "*ashrhi3_1"
11230   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11231         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11232                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11233    (clobber (reg:CC FLAGS_REG))]
11234   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11235   "@
11236    sar{w}\t{%2, %0|%0, %2}
11237    sar{w}\t{%b2, %0|%0, %b2}"
11238   [(set_attr "type" "ishift")
11239    (set_attr "mode" "HI")])
11240
11241 ;; This pattern can't accept a variable shift count, since shifts by
11242 ;; zero don't affect the flags.  We assume that shifts by constant
11243 ;; zero are optimized away.
11244 (define_insn "*ashrhi3_one_bit_cmp"
11245   [(set (reg FLAGS_REG)
11246         (compare
11247           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11248                        (match_operand:QI 2 "const1_operand" ""))
11249           (const_int 0)))
11250    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11251         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11252   "ix86_match_ccmode (insn, CCGOCmode)
11253    && (TARGET_SHIFT1 || optimize_size)
11254    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11255   "sar{w}\t%0"
11256   [(set_attr "type" "ishift")
11257    (set (attr "length") 
11258      (if_then_else (match_operand 0 "register_operand" "") 
11259         (const_string "2")
11260         (const_string "*")))])
11261
11262 ;; This pattern can't accept a variable shift count, since shifts by
11263 ;; zero don't affect the flags.  We assume that shifts by constant
11264 ;; zero are optimized away.
11265 (define_insn "*ashrhi3_cmp"
11266   [(set (reg FLAGS_REG)
11267         (compare
11268           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11269                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11270           (const_int 0)))
11271    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11272         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11273   "ix86_match_ccmode (insn, CCGOCmode)
11274    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11275   "sar{w}\t{%2, %0|%0, %2}"
11276   [(set_attr "type" "ishift")
11277    (set_attr "mode" "HI")])
11278
11279 (define_expand "ashrqi3"
11280   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11281         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11282                      (match_operand:QI 2 "nonmemory_operand" "")))
11283    (clobber (reg:CC FLAGS_REG))]
11284   "TARGET_QIMODE_MATH"
11285   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11286
11287 (define_insn "*ashrqi3_1_one_bit"
11288   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11289         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11290                      (match_operand:QI 2 "const1_operand" "")))
11291    (clobber (reg:CC FLAGS_REG))]
11292   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11293    && (TARGET_SHIFT1 || optimize_size)"
11294   "sar{b}\t%0"
11295   [(set_attr "type" "ishift")
11296    (set (attr "length") 
11297      (if_then_else (match_operand 0 "register_operand" "") 
11298         (const_string "2")
11299         (const_string "*")))])
11300
11301 (define_insn "*ashrqi3_1_one_bit_slp"
11302   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11303         (ashiftrt:QI (match_dup 0)
11304                      (match_operand:QI 1 "const1_operand" "")))
11305    (clobber (reg:CC FLAGS_REG))]
11306   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11307    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11308    && (TARGET_SHIFT1 || optimize_size)"
11309   "sar{b}\t%0"
11310   [(set_attr "type" "ishift1")
11311    (set (attr "length") 
11312      (if_then_else (match_operand 0 "register_operand" "") 
11313         (const_string "2")
11314         (const_string "*")))])
11315
11316 (define_insn "*ashrqi3_1"
11317   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11318         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11319                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11320    (clobber (reg:CC FLAGS_REG))]
11321   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11322   "@
11323    sar{b}\t{%2, %0|%0, %2}
11324    sar{b}\t{%b2, %0|%0, %b2}"
11325   [(set_attr "type" "ishift")
11326    (set_attr "mode" "QI")])
11327
11328 (define_insn "*ashrqi3_1_slp"
11329   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11330         (ashiftrt:QI (match_dup 0)
11331                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11332    (clobber (reg:CC FLAGS_REG))]
11333   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11334    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11335   "@
11336    sar{b}\t{%1, %0|%0, %1}
11337    sar{b}\t{%b1, %0|%0, %b1}"
11338   [(set_attr "type" "ishift1")
11339    (set_attr "mode" "QI")])
11340
11341 ;; This pattern can't accept a variable shift count, since shifts by
11342 ;; zero don't affect the flags.  We assume that shifts by constant
11343 ;; zero are optimized away.
11344 (define_insn "*ashrqi3_one_bit_cmp"
11345   [(set (reg FLAGS_REG)
11346         (compare
11347           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11348                        (match_operand:QI 2 "const1_operand" "I"))
11349           (const_int 0)))
11350    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11351         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11352   "ix86_match_ccmode (insn, CCGOCmode)
11353    && (TARGET_SHIFT1 || optimize_size)
11354    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11355   "sar{b}\t%0"
11356   [(set_attr "type" "ishift")
11357    (set (attr "length") 
11358      (if_then_else (match_operand 0 "register_operand" "") 
11359         (const_string "2")
11360         (const_string "*")))])
11361
11362 ;; This pattern can't accept a variable shift count, since shifts by
11363 ;; zero don't affect the flags.  We assume that shifts by constant
11364 ;; zero are optimized away.
11365 (define_insn "*ashrqi3_cmp"
11366   [(set (reg FLAGS_REG)
11367         (compare
11368           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11369                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11370           (const_int 0)))
11371    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11372         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11373   "ix86_match_ccmode (insn, CCGOCmode)
11374    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11375   "sar{b}\t{%2, %0|%0, %2}"
11376   [(set_attr "type" "ishift")
11377    (set_attr "mode" "QI")])
11378 \f
11379 ;; Logical shift instructions
11380
11381 ;; See comment above `ashldi3' about how this works.
11382
11383 (define_expand "lshrdi3"
11384   [(set (match_operand:DI 0 "shiftdi_operand" "")
11385         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11386                      (match_operand:QI 2 "nonmemory_operand" "")))]
11387   ""
11388   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11389
11390 (define_insn "*lshrdi3_1_one_bit_rex64"
11391   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11392         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11393                      (match_operand:QI 2 "const1_operand" "")))
11394    (clobber (reg:CC FLAGS_REG))]
11395   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11396    && (TARGET_SHIFT1 || optimize_size)"
11397   "shr{q}\t%0"
11398   [(set_attr "type" "ishift")
11399    (set (attr "length") 
11400      (if_then_else (match_operand:DI 0 "register_operand" "") 
11401         (const_string "2")
11402         (const_string "*")))])
11403
11404 (define_insn "*lshrdi3_1_rex64"
11405   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11406         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11407                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11408    (clobber (reg:CC FLAGS_REG))]
11409   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11410   "@
11411    shr{q}\t{%2, %0|%0, %2}
11412    shr{q}\t{%b2, %0|%0, %b2}"
11413   [(set_attr "type" "ishift")
11414    (set_attr "mode" "DI")])
11415
11416 ;; This pattern can't accept a variable shift count, since shifts by
11417 ;; zero don't affect the flags.  We assume that shifts by constant
11418 ;; zero are optimized away.
11419 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11420   [(set (reg FLAGS_REG)
11421         (compare
11422           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11423                        (match_operand:QI 2 "const1_operand" ""))
11424           (const_int 0)))
11425    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11426         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11427   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11428    && (TARGET_SHIFT1 || optimize_size)
11429    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11430   "shr{q}\t%0"
11431   [(set_attr "type" "ishift")
11432    (set (attr "length") 
11433      (if_then_else (match_operand:DI 0 "register_operand" "") 
11434         (const_string "2")
11435         (const_string "*")))])
11436
11437 ;; This pattern can't accept a variable shift count, since shifts by
11438 ;; zero don't affect the flags.  We assume that shifts by constant
11439 ;; zero are optimized away.
11440 (define_insn "*lshrdi3_cmp_rex64"
11441   [(set (reg FLAGS_REG)
11442         (compare
11443           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11444                        (match_operand:QI 2 "const_int_operand" "e"))
11445           (const_int 0)))
11446    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11447         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11448   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11449    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11450   "shr{q}\t{%2, %0|%0, %2}"
11451   [(set_attr "type" "ishift")
11452    (set_attr "mode" "DI")])
11453
11454 (define_insn "*lshrdi3_1"
11455   [(set (match_operand:DI 0 "register_operand" "=r")
11456         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11457                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11458    (clobber (reg:CC FLAGS_REG))]
11459   "!TARGET_64BIT"
11460   "#"
11461   [(set_attr "type" "multi")])
11462
11463 ;; By default we don't ask for a scratch register, because when DImode
11464 ;; values are manipulated, registers are already at a premium.  But if
11465 ;; we have one handy, we won't turn it away.
11466 (define_peephole2
11467   [(match_scratch:SI 3 "r")
11468    (parallel [(set (match_operand:DI 0 "register_operand" "")
11469                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11470                                 (match_operand:QI 2 "nonmemory_operand" "")))
11471               (clobber (reg:CC FLAGS_REG))])
11472    (match_dup 3)]
11473   "!TARGET_64BIT && TARGET_CMOVE"
11474   [(const_int 0)]
11475   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11476
11477 (define_split 
11478   [(set (match_operand:DI 0 "register_operand" "")
11479         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11480                      (match_operand:QI 2 "nonmemory_operand" "")))
11481    (clobber (reg:CC FLAGS_REG))]
11482   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11483   [(const_int 0)]
11484   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11485
11486 (define_expand "lshrsi3"
11487   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11488         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11489                      (match_operand:QI 2 "nonmemory_operand" "")))
11490    (clobber (reg:CC FLAGS_REG))]
11491   ""
11492   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11493
11494 (define_insn "*lshrsi3_1_one_bit"
11495   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11496         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11497                      (match_operand:QI 2 "const1_operand" "")))
11498    (clobber (reg:CC FLAGS_REG))]
11499   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11500    && (TARGET_SHIFT1 || optimize_size)"
11501   "shr{l}\t%0"
11502   [(set_attr "type" "ishift")
11503    (set (attr "length") 
11504      (if_then_else (match_operand:SI 0 "register_operand" "") 
11505         (const_string "2")
11506         (const_string "*")))])
11507
11508 (define_insn "*lshrsi3_1_one_bit_zext"
11509   [(set (match_operand:DI 0 "register_operand" "=r")
11510         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11511                      (match_operand:QI 2 "const1_operand" "")))
11512    (clobber (reg:CC FLAGS_REG))]
11513   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11514    && (TARGET_SHIFT1 || optimize_size)"
11515   "shr{l}\t%k0"
11516   [(set_attr "type" "ishift")
11517    (set_attr "length" "2")])
11518
11519 (define_insn "*lshrsi3_1"
11520   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11521         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11522                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11523    (clobber (reg:CC FLAGS_REG))]
11524   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11525   "@
11526    shr{l}\t{%2, %0|%0, %2}
11527    shr{l}\t{%b2, %0|%0, %b2}"
11528   [(set_attr "type" "ishift")
11529    (set_attr "mode" "SI")])
11530
11531 (define_insn "*lshrsi3_1_zext"
11532   [(set (match_operand:DI 0 "register_operand" "=r,r")
11533         (zero_extend:DI
11534           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_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 (LSHIFTRT, HImode, operands)"
11538   "@
11539    shr{l}\t{%2, %k0|%k0, %2}
11540    shr{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 "*lshrsi3_one_bit_cmp"
11548   [(set (reg FLAGS_REG)
11549         (compare
11550           (lshiftrt: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         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11555   "ix86_match_ccmode (insn, CCGOCmode)
11556    && (TARGET_SHIFT1 || optimize_size)
11557    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11558   "shr{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 "*lshrsi3_cmp_one_bit_zext"
11566   [(set (reg FLAGS_REG)
11567         (compare
11568           (lshiftrt: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         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11573   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11574    && (TARGET_SHIFT1 || optimize_size)
11575    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11576   "shr{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 "*lshrsi3_cmp"
11584   [(set (reg FLAGS_REG)
11585         (compare
11586           (lshiftrt: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         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11591   "ix86_match_ccmode (insn, CCGOCmode)
11592    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11593   "shr{l}\t{%2, %0|%0, %2}"
11594   [(set_attr "type" "ishift")
11595    (set_attr "mode" "SI")])
11596
11597 (define_insn "*lshrsi3_cmp_zext"
11598   [(set (reg FLAGS_REG)
11599         (compare
11600           (lshiftrt: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         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11605   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11606    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11607   "shr{l}\t{%2, %k0|%k0, %2}"
11608   [(set_attr "type" "ishift")
11609    (set_attr "mode" "SI")])
11610
11611 (define_expand "lshrhi3"
11612   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11613         (lshiftrt: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 (LSHIFTRT, HImode, operands); DONE;")
11618
11619 (define_insn "*lshrhi3_1_one_bit"
11620   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11621         (lshiftrt: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 (LSHIFTRT, HImode, operands)
11625    && (TARGET_SHIFT1 || optimize_size)"
11626   "shr{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 "*lshrhi3_1"
11634   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11635         (lshiftrt: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 (LSHIFTRT, HImode, operands)"
11639   "@
11640    shr{w}\t{%2, %0|%0, %2}
11641    shr{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 "*lshrhi3_one_bit_cmp"
11649   [(set (reg FLAGS_REG)
11650         (compare
11651           (lshiftrt: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         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11656   "ix86_match_ccmode (insn, CCGOCmode)
11657    && (TARGET_SHIFT1 || optimize_size)
11658    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11659   "shr{w}\t%0"
11660   [(set_attr "type" "ishift")
11661    (set (attr "length") 
11662      (if_then_else (match_operand:SI 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 "*lshrhi3_cmp"
11670   [(set (reg FLAGS_REG)
11671         (compare
11672           (lshiftrt: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         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11677   "ix86_match_ccmode (insn, CCGOCmode)
11678    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11679   "shr{w}\t{%2, %0|%0, %2}"
11680   [(set_attr "type" "ishift")
11681    (set_attr "mode" "HI")])
11682
11683 (define_expand "lshrqi3"
11684   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11685         (lshiftrt: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 (LSHIFTRT, QImode, operands); DONE;")
11690
11691 (define_insn "*lshrqi3_1_one_bit"
11692   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11693         (lshiftrt: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 (LSHIFTRT, QImode, operands)
11697    && (TARGET_SHIFT1 || optimize_size)"
11698   "shr{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 "*lshrqi3_1_one_bit_slp"
11706   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11707         (lshiftrt:QI (match_dup 0)
11708                      (match_operand:QI 1 "const1_operand" "")))
11709    (clobber (reg:CC FLAGS_REG))]
11710   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11711    && (TARGET_SHIFT1 || optimize_size)"
11712   "shr{b}\t%0"
11713   [(set_attr "type" "ishift1")
11714    (set (attr "length") 
11715      (if_then_else (match_operand 0 "register_operand" "") 
11716         (const_string "2")
11717         (const_string "*")))])
11718
11719 (define_insn "*lshrqi3_1"
11720   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11721         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11722                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11723    (clobber (reg:CC FLAGS_REG))]
11724   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11725   "@
11726    shr{b}\t{%2, %0|%0, %2}
11727    shr{b}\t{%b2, %0|%0, %b2}"
11728   [(set_attr "type" "ishift")
11729    (set_attr "mode" "QI")])
11730
11731 (define_insn "*lshrqi3_1_slp"
11732   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11733         (lshiftrt:QI (match_dup 0)
11734                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11735    (clobber (reg:CC FLAGS_REG))]
11736   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11737    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11738   "@
11739    shr{b}\t{%1, %0|%0, %1}
11740    shr{b}\t{%b1, %0|%0, %b1}"
11741   [(set_attr "type" "ishift1")
11742    (set_attr "mode" "QI")])
11743
11744 ;; This pattern can't accept a variable shift count, since shifts by
11745 ;; zero don't affect the flags.  We assume that shifts by constant
11746 ;; zero are optimized away.
11747 (define_insn "*lshrqi2_one_bit_cmp"
11748   [(set (reg FLAGS_REG)
11749         (compare
11750           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11751                        (match_operand:QI 2 "const1_operand" ""))
11752           (const_int 0)))
11753    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11754         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11755   "ix86_match_ccmode (insn, CCGOCmode)
11756    && (TARGET_SHIFT1 || optimize_size)
11757    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11758   "shr{b}\t%0"
11759   [(set_attr "type" "ishift")
11760    (set (attr "length") 
11761      (if_then_else (match_operand:SI 0 "register_operand" "") 
11762         (const_string "2")
11763         (const_string "*")))])
11764
11765 ;; This pattern can't accept a variable shift count, since shifts by
11766 ;; zero don't affect the flags.  We assume that shifts by constant
11767 ;; zero are optimized away.
11768 (define_insn "*lshrqi2_cmp"
11769   [(set (reg FLAGS_REG)
11770         (compare
11771           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11772                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11773           (const_int 0)))
11774    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11775         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11776   "ix86_match_ccmode (insn, CCGOCmode)
11777    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11778   "shr{b}\t{%2, %0|%0, %2}"
11779   [(set_attr "type" "ishift")
11780    (set_attr "mode" "QI")])
11781 \f
11782 ;; Rotate instructions
11783
11784 (define_expand "rotldi3"
11785   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11786         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11787                    (match_operand:QI 2 "nonmemory_operand" "")))
11788    (clobber (reg:CC FLAGS_REG))]
11789   "TARGET_64BIT"
11790   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11791
11792 (define_insn "*rotlsi3_1_one_bit_rex64"
11793   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11794         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11795                    (match_operand:QI 2 "const1_operand" "")))
11796    (clobber (reg:CC FLAGS_REG))]
11797   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11798    && (TARGET_SHIFT1 || optimize_size)"
11799   "rol{q}\t%0"
11800   [(set_attr "type" "rotate")
11801    (set (attr "length") 
11802      (if_then_else (match_operand:DI 0 "register_operand" "") 
11803         (const_string "2")
11804         (const_string "*")))])
11805
11806 (define_insn "*rotldi3_1_rex64"
11807   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11808         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11809                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11810    (clobber (reg:CC FLAGS_REG))]
11811   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11812   "@
11813    rol{q}\t{%2, %0|%0, %2}
11814    rol{q}\t{%b2, %0|%0, %b2}"
11815   [(set_attr "type" "rotate")
11816    (set_attr "mode" "DI")])
11817
11818 (define_expand "rotlsi3"
11819   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11820         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11821                    (match_operand:QI 2 "nonmemory_operand" "")))
11822    (clobber (reg:CC FLAGS_REG))]
11823   ""
11824   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11825
11826 (define_insn "*rotlsi3_1_one_bit"
11827   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11828         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11829                    (match_operand:QI 2 "const1_operand" "")))
11830    (clobber (reg:CC FLAGS_REG))]
11831   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11832    && (TARGET_SHIFT1 || optimize_size)"
11833   "rol{l}\t%0"
11834   [(set_attr "type" "rotate")
11835    (set (attr "length") 
11836      (if_then_else (match_operand:SI 0 "register_operand" "") 
11837         (const_string "2")
11838         (const_string "*")))])
11839
11840 (define_insn "*rotlsi3_1_one_bit_zext"
11841   [(set (match_operand:DI 0 "register_operand" "=r")
11842         (zero_extend:DI
11843           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11844                      (match_operand:QI 2 "const1_operand" ""))))
11845    (clobber (reg:CC FLAGS_REG))]
11846   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11847    && (TARGET_SHIFT1 || optimize_size)"
11848   "rol{l}\t%k0"
11849   [(set_attr "type" "rotate")
11850    (set_attr "length" "2")])
11851
11852 (define_insn "*rotlsi3_1"
11853   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11854         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11855                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11856    (clobber (reg:CC FLAGS_REG))]
11857   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11858   "@
11859    rol{l}\t{%2, %0|%0, %2}
11860    rol{l}\t{%b2, %0|%0, %b2}"
11861   [(set_attr "type" "rotate")
11862    (set_attr "mode" "SI")])
11863
11864 (define_insn "*rotlsi3_1_zext"
11865   [(set (match_operand:DI 0 "register_operand" "=r,r")
11866         (zero_extend:DI
11867           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11868                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11869    (clobber (reg:CC FLAGS_REG))]
11870   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11871   "@
11872    rol{l}\t{%2, %k0|%k0, %2}
11873    rol{l}\t{%b2, %k0|%k0, %b2}"
11874   [(set_attr "type" "rotate")
11875    (set_attr "mode" "SI")])
11876
11877 (define_expand "rotlhi3"
11878   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11879         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11880                    (match_operand:QI 2 "nonmemory_operand" "")))
11881    (clobber (reg:CC FLAGS_REG))]
11882   "TARGET_HIMODE_MATH"
11883   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11884
11885 (define_insn "*rotlhi3_1_one_bit"
11886   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11887         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11888                    (match_operand:QI 2 "const1_operand" "")))
11889    (clobber (reg:CC FLAGS_REG))]
11890   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11891    && (TARGET_SHIFT1 || optimize_size)"
11892   "rol{w}\t%0"
11893   [(set_attr "type" "rotate")
11894    (set (attr "length") 
11895      (if_then_else (match_operand 0 "register_operand" "") 
11896         (const_string "2")
11897         (const_string "*")))])
11898
11899 (define_insn "*rotlhi3_1"
11900   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11901         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11902                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11903    (clobber (reg:CC FLAGS_REG))]
11904   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11905   "@
11906    rol{w}\t{%2, %0|%0, %2}
11907    rol{w}\t{%b2, %0|%0, %b2}"
11908   [(set_attr "type" "rotate")
11909    (set_attr "mode" "HI")])
11910
11911 (define_expand "rotlqi3"
11912   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11913         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11914                    (match_operand:QI 2 "nonmemory_operand" "")))
11915    (clobber (reg:CC FLAGS_REG))]
11916   "TARGET_QIMODE_MATH"
11917   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11918
11919 (define_insn "*rotlqi3_1_one_bit_slp"
11920   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11921         (rotate:QI (match_dup 0)
11922                    (match_operand:QI 1 "const1_operand" "")))
11923    (clobber (reg:CC FLAGS_REG))]
11924   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11925    && (TARGET_SHIFT1 || optimize_size)"
11926   "rol{b}\t%0"
11927   [(set_attr "type" "rotate1")
11928    (set (attr "length") 
11929      (if_then_else (match_operand 0 "register_operand" "") 
11930         (const_string "2")
11931         (const_string "*")))])
11932
11933 (define_insn "*rotlqi3_1_one_bit"
11934   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11935         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11936                    (match_operand:QI 2 "const1_operand" "")))
11937    (clobber (reg:CC FLAGS_REG))]
11938   "ix86_binary_operator_ok (ROTATE, QImode, operands)
11939    && (TARGET_SHIFT1 || optimize_size)"
11940   "rol{b}\t%0"
11941   [(set_attr "type" "rotate")
11942    (set (attr "length") 
11943      (if_then_else (match_operand 0 "register_operand" "") 
11944         (const_string "2")
11945         (const_string "*")))])
11946
11947 (define_insn "*rotlqi3_1_slp"
11948   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11949         (rotate:QI (match_dup 0)
11950                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
11951    (clobber (reg:CC FLAGS_REG))]
11952   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11953    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11954   "@
11955    rol{b}\t{%1, %0|%0, %1}
11956    rol{b}\t{%b1, %0|%0, %b1}"
11957   [(set_attr "type" "rotate1")
11958    (set_attr "mode" "QI")])
11959
11960 (define_insn "*rotlqi3_1"
11961   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11962         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11963                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11964    (clobber (reg:CC FLAGS_REG))]
11965   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11966   "@
11967    rol{b}\t{%2, %0|%0, %2}
11968    rol{b}\t{%b2, %0|%0, %b2}"
11969   [(set_attr "type" "rotate")
11970    (set_attr "mode" "QI")])
11971
11972 (define_expand "rotrdi3"
11973   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11974         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11975                      (match_operand:QI 2 "nonmemory_operand" "")))
11976    (clobber (reg:CC FLAGS_REG))]
11977   "TARGET_64BIT"
11978   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11979
11980 (define_insn "*rotrdi3_1_one_bit_rex64"
11981   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11982         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11983                      (match_operand:QI 2 "const1_operand" "")))
11984    (clobber (reg:CC FLAGS_REG))]
11985   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11986    && (TARGET_SHIFT1 || optimize_size)"
11987   "ror{q}\t%0"
11988   [(set_attr "type" "rotate")
11989    (set (attr "length") 
11990      (if_then_else (match_operand:DI 0 "register_operand" "") 
11991         (const_string "2")
11992         (const_string "*")))])
11993
11994 (define_insn "*rotrdi3_1_rex64"
11995   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11996         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11997                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11998    (clobber (reg:CC FLAGS_REG))]
11999   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12000   "@
12001    ror{q}\t{%2, %0|%0, %2}
12002    ror{q}\t{%b2, %0|%0, %b2}"
12003   [(set_attr "type" "rotate")
12004    (set_attr "mode" "DI")])
12005
12006 (define_expand "rotrsi3"
12007   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12008         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12009                      (match_operand:QI 2 "nonmemory_operand" "")))
12010    (clobber (reg:CC FLAGS_REG))]
12011   ""
12012   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12013
12014 (define_insn "*rotrsi3_1_one_bit"
12015   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12016         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12017                      (match_operand:QI 2 "const1_operand" "")))
12018    (clobber (reg:CC FLAGS_REG))]
12019   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12020    && (TARGET_SHIFT1 || optimize_size)"
12021   "ror{l}\t%0"
12022   [(set_attr "type" "rotate")
12023    (set (attr "length") 
12024      (if_then_else (match_operand:SI 0 "register_operand" "") 
12025         (const_string "2")
12026         (const_string "*")))])
12027
12028 (define_insn "*rotrsi3_1_one_bit_zext"
12029   [(set (match_operand:DI 0 "register_operand" "=r")
12030         (zero_extend:DI
12031           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12032                        (match_operand:QI 2 "const1_operand" ""))))
12033    (clobber (reg:CC FLAGS_REG))]
12034   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12035    && (TARGET_SHIFT1 || optimize_size)"
12036   "ror{l}\t%k0"
12037   [(set_attr "type" "rotate")
12038    (set (attr "length") 
12039      (if_then_else (match_operand:SI 0 "register_operand" "") 
12040         (const_string "2")
12041         (const_string "*")))])
12042
12043 (define_insn "*rotrsi3_1"
12044   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12045         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12046                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12047    (clobber (reg:CC FLAGS_REG))]
12048   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12049   "@
12050    ror{l}\t{%2, %0|%0, %2}
12051    ror{l}\t{%b2, %0|%0, %b2}"
12052   [(set_attr "type" "rotate")
12053    (set_attr "mode" "SI")])
12054
12055 (define_insn "*rotrsi3_1_zext"
12056   [(set (match_operand:DI 0 "register_operand" "=r,r")
12057         (zero_extend:DI
12058           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12059                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12060    (clobber (reg:CC FLAGS_REG))]
12061   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12062   "@
12063    ror{l}\t{%2, %k0|%k0, %2}
12064    ror{l}\t{%b2, %k0|%k0, %b2}"
12065   [(set_attr "type" "rotate")
12066    (set_attr "mode" "SI")])
12067
12068 (define_expand "rotrhi3"
12069   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12070         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12071                      (match_operand:QI 2 "nonmemory_operand" "")))
12072    (clobber (reg:CC FLAGS_REG))]
12073   "TARGET_HIMODE_MATH"
12074   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12075
12076 (define_insn "*rotrhi3_one_bit"
12077   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12078         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12079                      (match_operand:QI 2 "const1_operand" "")))
12080    (clobber (reg:CC FLAGS_REG))]
12081   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12082    && (TARGET_SHIFT1 || optimize_size)"
12083   "ror{w}\t%0"
12084   [(set_attr "type" "rotate")
12085    (set (attr "length") 
12086      (if_then_else (match_operand 0 "register_operand" "") 
12087         (const_string "2")
12088         (const_string "*")))])
12089
12090 (define_insn "*rotrhi3"
12091   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12092         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12093                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12094    (clobber (reg:CC FLAGS_REG))]
12095   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12096   "@
12097    ror{w}\t{%2, %0|%0, %2}
12098    ror{w}\t{%b2, %0|%0, %b2}"
12099   [(set_attr "type" "rotate")
12100    (set_attr "mode" "HI")])
12101
12102 (define_expand "rotrqi3"
12103   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12104         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12105                      (match_operand:QI 2 "nonmemory_operand" "")))
12106    (clobber (reg:CC FLAGS_REG))]
12107   "TARGET_QIMODE_MATH"
12108   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12109
12110 (define_insn "*rotrqi3_1_one_bit"
12111   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12112         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12113                      (match_operand:QI 2 "const1_operand" "")))
12114    (clobber (reg:CC FLAGS_REG))]
12115   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12116    && (TARGET_SHIFT1 || optimize_size)"
12117   "ror{b}\t%0"
12118   [(set_attr "type" "rotate")
12119    (set (attr "length") 
12120      (if_then_else (match_operand 0 "register_operand" "") 
12121         (const_string "2")
12122         (const_string "*")))])
12123
12124 (define_insn "*rotrqi3_1_one_bit_slp"
12125   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12126         (rotatert:QI (match_dup 0)
12127                      (match_operand:QI 1 "const1_operand" "")))
12128    (clobber (reg:CC FLAGS_REG))]
12129   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12130    && (TARGET_SHIFT1 || optimize_size)"
12131   "ror{b}\t%0"
12132   [(set_attr "type" "rotate1")
12133    (set (attr "length") 
12134      (if_then_else (match_operand 0 "register_operand" "") 
12135         (const_string "2")
12136         (const_string "*")))])
12137
12138 (define_insn "*rotrqi3_1"
12139   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12140         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12141                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12142    (clobber (reg:CC FLAGS_REG))]
12143   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12144   "@
12145    ror{b}\t{%2, %0|%0, %2}
12146    ror{b}\t{%b2, %0|%0, %b2}"
12147   [(set_attr "type" "rotate")
12148    (set_attr "mode" "QI")])
12149
12150 (define_insn "*rotrqi3_1_slp"
12151   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12152         (rotatert:QI (match_dup 0)
12153                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12154    (clobber (reg:CC FLAGS_REG))]
12155   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12156    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12157   "@
12158    ror{b}\t{%1, %0|%0, %1}
12159    ror{b}\t{%b1, %0|%0, %b1}"
12160   [(set_attr "type" "rotate1")
12161    (set_attr "mode" "QI")])
12162 \f
12163 ;; Bit set / bit test instructions
12164
12165 (define_expand "extv"
12166   [(set (match_operand:SI 0 "register_operand" "")
12167         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12168                          (match_operand:SI 2 "immediate_operand" "")
12169                          (match_operand:SI 3 "immediate_operand" "")))]
12170   ""
12171 {
12172   /* Handle extractions from %ah et al.  */
12173   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12174     FAIL;
12175
12176   /* From mips.md: extract_bit_field doesn't verify that our source
12177      matches the predicate, so check it again here.  */
12178   if (! ext_register_operand (operands[1], VOIDmode))
12179     FAIL;
12180 })
12181
12182 (define_expand "extzv"
12183   [(set (match_operand:SI 0 "register_operand" "")
12184         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12185                          (match_operand:SI 2 "immediate_operand" "")
12186                          (match_operand:SI 3 "immediate_operand" "")))]
12187   ""
12188 {
12189   /* Handle extractions from %ah et al.  */
12190   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12191     FAIL;
12192
12193   /* From mips.md: extract_bit_field doesn't verify that our source
12194      matches the predicate, so check it again here.  */
12195   if (! ext_register_operand (operands[1], VOIDmode))
12196     FAIL;
12197 })
12198
12199 (define_expand "insv"
12200   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12201                       (match_operand 1 "immediate_operand" "")
12202                       (match_operand 2 "immediate_operand" ""))
12203         (match_operand 3 "register_operand" ""))]
12204   ""
12205 {
12206   /* Handle extractions from %ah et al.  */
12207   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12208     FAIL;
12209
12210   /* From mips.md: insert_bit_field doesn't verify that our source
12211      matches the predicate, so check it again here.  */
12212   if (! ext_register_operand (operands[0], VOIDmode))
12213     FAIL;
12214
12215   if (TARGET_64BIT)
12216     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12217   else
12218     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12219
12220   DONE;
12221 })
12222
12223 ;; %%% bts, btr, btc, bt.
12224 ;; In general these instructions are *slow* when applied to memory,
12225 ;; since they enforce atomic operation.  When applied to registers,
12226 ;; it depends on the cpu implementation.  They're never faster than
12227 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12228 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12229 ;; within the instruction itself, so operating on bits in the high
12230 ;; 32-bits of a register becomes easier.
12231 ;;
12232 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12233 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12234 ;; negdf respectively, so they can never be disabled entirely.
12235
12236 (define_insn "*btsq"
12237   [(set (zero_extract:DI (match_operand 0 "register_operand" "+r")
12238                          (const_int 1)
12239                          (match_operand 1 "const_0_to_63_operand" ""))
12240         (const_int 1))
12241    (clobber (reg:CC FLAGS_REG))]
12242   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12243   "bts{q} %1,%0"
12244   [(set_attr "type" "alu1")])
12245
12246 (define_insn "*btrq"
12247   [(set (zero_extract:DI (match_operand 0 "register_operand" "+r")
12248                          (const_int 1)
12249                          (match_operand 1 "const_0_to_63_operand" ""))
12250         (const_int 0))
12251    (clobber (reg:CC FLAGS_REG))]
12252   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12253   "btr{q} %1,%0"
12254   [(set_attr "type" "alu1")])
12255
12256 (define_insn "*btcq"
12257   [(set (zero_extract:DI (match_operand 0 "register_operand" "+r")
12258                          (const_int 1)
12259                          (match_operand 1 "const_0_to_63_operand" ""))
12260         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12261    (clobber (reg:CC FLAGS_REG))]
12262   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12263   "btc{q} %1,%0"
12264   [(set_attr "type" "alu1")])
12265
12266 ;; Allow Nocona to avoid these instructions if a register is available.
12267
12268 (define_peephole2
12269   [(match_scratch:DI 2 "r")
12270    (parallel [(set (zero_extract:DI
12271                      (match_operand 0 "register_operand" "")
12272                      (const_int 1)
12273                      (match_operand 1 "const_0_to_63_operand" ""))
12274                    (const_int 1))
12275               (clobber (reg:CC FLAGS_REG))])]
12276   "TARGET_64BIT && !TARGET_USE_BT"
12277   [(const_int 0)]
12278 {
12279   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12280   rtx op1;
12281
12282   if (HOST_BITS_PER_WIDE_INT >= 64)
12283     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12284   else if (i < HOST_BITS_PER_WIDE_INT)
12285     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12286   else
12287     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12288
12289   op1 = immed_double_const (lo, hi, DImode);
12290   if (i >= 31)
12291     {
12292       emit_move_insn (operands[2], op1);
12293       op1 = operands[2];
12294     }
12295
12296   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12297   DONE;
12298 })
12299
12300 (define_peephole2
12301   [(match_scratch:DI 2 "r")
12302    (parallel [(set (zero_extract:DI
12303                      (match_operand 0 "register_operand" "")
12304                      (const_int 1)
12305                      (match_operand 1 "const_0_to_63_operand" ""))
12306                    (const_int 0))
12307               (clobber (reg:CC FLAGS_REG))])]
12308   "TARGET_64BIT && !TARGET_USE_BT"
12309   [(const_int 0)]
12310 {
12311   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12312   rtx op1;
12313
12314   if (HOST_BITS_PER_WIDE_INT >= 64)
12315     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12316   else if (i < HOST_BITS_PER_WIDE_INT)
12317     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12318   else
12319     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12320
12321   op1 = immed_double_const (~lo, ~hi, DImode);
12322   if (i >= 32)
12323     {
12324       emit_move_insn (operands[2], op1);
12325       op1 = operands[2];
12326     }
12327
12328   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12329   DONE;
12330 })
12331
12332 (define_peephole2
12333   [(match_scratch:DI 2 "r")
12334    (parallel [(set (zero_extract:DI
12335                      (match_operand 0 "register_operand" "")
12336                      (const_int 1)
12337                      (match_operand 1 "const_0_to_63_operand" ""))
12338               (not:DI (zero_extract:DI
12339                         (match_dup 0) (const_int 1) (match_dup 1))))
12340               (clobber (reg:CC FLAGS_REG))])]
12341   "TARGET_64BIT && !TARGET_USE_BT"
12342   [(const_int 0)]
12343 {
12344   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12345   rtx op1;
12346
12347   if (HOST_BITS_PER_WIDE_INT >= 64)
12348     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12349   else if (i < HOST_BITS_PER_WIDE_INT)
12350     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12351   else
12352     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12353
12354   op1 = immed_double_const (lo, hi, DImode);
12355   if (i >= 31)
12356     {
12357       emit_move_insn (operands[2], op1);
12358       op1 = operands[2];
12359     }
12360
12361   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12362   DONE;
12363 })
12364 \f
12365 ;; Store-flag instructions.
12366
12367 ;; For all sCOND expanders, also expand the compare or test insn that
12368 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12369
12370 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12371 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12372 ;; way, which can later delete the movzx if only QImode is needed.
12373
12374 (define_expand "seq"
12375   [(set (match_operand:QI 0 "register_operand" "")
12376         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12377   ""
12378   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12379
12380 (define_expand "sne"
12381   [(set (match_operand:QI 0 "register_operand" "")
12382         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12383   ""
12384   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12385
12386 (define_expand "sgt"
12387   [(set (match_operand:QI 0 "register_operand" "")
12388         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12389   ""
12390   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12391
12392 (define_expand "sgtu"
12393   [(set (match_operand:QI 0 "register_operand" "")
12394         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12395   ""
12396   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12397
12398 (define_expand "slt"
12399   [(set (match_operand:QI 0 "register_operand" "")
12400         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12401   ""
12402   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12403
12404 (define_expand "sltu"
12405   [(set (match_operand:QI 0 "register_operand" "")
12406         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12407   ""
12408   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12409
12410 (define_expand "sge"
12411   [(set (match_operand:QI 0 "register_operand" "")
12412         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12413   ""
12414   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12415
12416 (define_expand "sgeu"
12417   [(set (match_operand:QI 0 "register_operand" "")
12418         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12419   ""
12420   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12421
12422 (define_expand "sle"
12423   [(set (match_operand:QI 0 "register_operand" "")
12424         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12425   ""
12426   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12427
12428 (define_expand "sleu"
12429   [(set (match_operand:QI 0 "register_operand" "")
12430         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12431   ""
12432   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12433
12434 (define_expand "sunordered"
12435   [(set (match_operand:QI 0 "register_operand" "")
12436         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12437   "TARGET_80387 || TARGET_SSE"
12438   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12439
12440 (define_expand "sordered"
12441   [(set (match_operand:QI 0 "register_operand" "")
12442         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12443   "TARGET_80387"
12444   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12445
12446 (define_expand "suneq"
12447   [(set (match_operand:QI 0 "register_operand" "")
12448         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12449   "TARGET_80387 || TARGET_SSE"
12450   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12451
12452 (define_expand "sunge"
12453   [(set (match_operand:QI 0 "register_operand" "")
12454         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12455   "TARGET_80387 || TARGET_SSE"
12456   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12457
12458 (define_expand "sungt"
12459   [(set (match_operand:QI 0 "register_operand" "")
12460         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12461   "TARGET_80387 || TARGET_SSE"
12462   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12463
12464 (define_expand "sunle"
12465   [(set (match_operand:QI 0 "register_operand" "")
12466         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12467   "TARGET_80387 || TARGET_SSE"
12468   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12469
12470 (define_expand "sunlt"
12471   [(set (match_operand:QI 0 "register_operand" "")
12472         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12473   "TARGET_80387 || TARGET_SSE"
12474   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12475
12476 (define_expand "sltgt"
12477   [(set (match_operand:QI 0 "register_operand" "")
12478         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12479   "TARGET_80387 || TARGET_SSE"
12480   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12481
12482 (define_insn "*setcc_1"
12483   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12484         (match_operator:QI 1 "ix86_comparison_operator"
12485           [(reg FLAGS_REG) (const_int 0)]))]
12486   ""
12487   "set%C1\t%0"
12488   [(set_attr "type" "setcc")
12489    (set_attr "mode" "QI")])
12490
12491 (define_insn "*setcc_2"
12492   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12493         (match_operator:QI 1 "ix86_comparison_operator"
12494           [(reg FLAGS_REG) (const_int 0)]))]
12495   ""
12496   "set%C1\t%0"
12497   [(set_attr "type" "setcc")
12498    (set_attr "mode" "QI")])
12499
12500 ;; In general it is not safe to assume too much about CCmode registers,
12501 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12502 ;; conditions this is safe on x86, so help combine not create
12503 ;;
12504 ;;      seta    %al
12505 ;;      testb   %al, %al
12506 ;;      sete    %al
12507
12508 (define_split 
12509   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12510         (ne:QI (match_operator 1 "ix86_comparison_operator"
12511                  [(reg FLAGS_REG) (const_int 0)])
12512             (const_int 0)))]
12513   ""
12514   [(set (match_dup 0) (match_dup 1))]
12515 {
12516   PUT_MODE (operands[1], QImode);
12517 })
12518
12519 (define_split 
12520   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12521         (ne:QI (match_operator 1 "ix86_comparison_operator"
12522                  [(reg FLAGS_REG) (const_int 0)])
12523             (const_int 0)))]
12524   ""
12525   [(set (match_dup 0) (match_dup 1))]
12526 {
12527   PUT_MODE (operands[1], QImode);
12528 })
12529
12530 (define_split 
12531   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12532         (eq:QI (match_operator 1 "ix86_comparison_operator"
12533                  [(reg FLAGS_REG) (const_int 0)])
12534             (const_int 0)))]
12535   ""
12536   [(set (match_dup 0) (match_dup 1))]
12537 {
12538   rtx new_op1 = copy_rtx (operands[1]);
12539   operands[1] = new_op1;
12540   PUT_MODE (new_op1, QImode);
12541   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12542                                              GET_MODE (XEXP (new_op1, 0))));
12543
12544   /* Make sure that (a) the CCmode we have for the flags is strong
12545      enough for the reversed compare or (b) we have a valid FP compare.  */
12546   if (! ix86_comparison_operator (new_op1, VOIDmode))
12547     FAIL;
12548 })
12549
12550 (define_split 
12551   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12552         (eq:QI (match_operator 1 "ix86_comparison_operator"
12553                  [(reg FLAGS_REG) (const_int 0)])
12554             (const_int 0)))]
12555   ""
12556   [(set (match_dup 0) (match_dup 1))]
12557 {
12558   rtx new_op1 = copy_rtx (operands[1]);
12559   operands[1] = new_op1;
12560   PUT_MODE (new_op1, QImode);
12561   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12562                                              GET_MODE (XEXP (new_op1, 0))));
12563
12564   /* Make sure that (a) the CCmode we have for the flags is strong
12565      enough for the reversed compare or (b) we have a valid FP compare.  */
12566   if (! ix86_comparison_operator (new_op1, VOIDmode))
12567     FAIL;
12568 })
12569
12570 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12571 ;; subsequent logical operations are used to imitate conditional moves.
12572 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12573 ;; it directly.  Further holding this value in pseudo register might bring
12574 ;; problem in implicit normalization in spill code.
12575 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12576 ;; instructions after reload by splitting the conditional move patterns.
12577
12578 (define_insn "*sse_setccsf"
12579   [(set (match_operand:SF 0 "register_operand" "=x")
12580         (match_operator:SF 1 "sse_comparison_operator"
12581           [(match_operand:SF 2 "register_operand" "0")
12582            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12583   "TARGET_SSE && reload_completed"
12584   "cmp%D1ss\t{%3, %0|%0, %3}"
12585   [(set_attr "type" "ssecmp")
12586    (set_attr "mode" "SF")])
12587
12588 (define_insn "*sse_setccdf"
12589   [(set (match_operand:DF 0 "register_operand" "=Y")
12590         (match_operator:DF 1 "sse_comparison_operator"
12591           [(match_operand:DF 2 "register_operand" "0")
12592            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12593   "TARGET_SSE2 && reload_completed"
12594   "cmp%D1sd\t{%3, %0|%0, %3}"
12595   [(set_attr "type" "ssecmp")
12596    (set_attr "mode" "DF")])
12597 \f
12598 ;; Basic conditional jump instructions.
12599 ;; We ignore the overflow flag for signed branch instructions.
12600
12601 ;; For all bCOND expanders, also expand the compare or test insn that
12602 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12603
12604 (define_expand "beq"
12605   [(set (pc)
12606         (if_then_else (match_dup 1)
12607                       (label_ref (match_operand 0 "" ""))
12608                       (pc)))]
12609   ""
12610   "ix86_expand_branch (EQ, operands[0]); DONE;")
12611
12612 (define_expand "bne"
12613   [(set (pc)
12614         (if_then_else (match_dup 1)
12615                       (label_ref (match_operand 0 "" ""))
12616                       (pc)))]
12617   ""
12618   "ix86_expand_branch (NE, operands[0]); DONE;")
12619
12620 (define_expand "bgt"
12621   [(set (pc)
12622         (if_then_else (match_dup 1)
12623                       (label_ref (match_operand 0 "" ""))
12624                       (pc)))]
12625   ""
12626   "ix86_expand_branch (GT, operands[0]); DONE;")
12627
12628 (define_expand "bgtu"
12629   [(set (pc)
12630         (if_then_else (match_dup 1)
12631                       (label_ref (match_operand 0 "" ""))
12632                       (pc)))]
12633   ""
12634   "ix86_expand_branch (GTU, operands[0]); DONE;")
12635
12636 (define_expand "blt"
12637   [(set (pc)
12638         (if_then_else (match_dup 1)
12639                       (label_ref (match_operand 0 "" ""))
12640                       (pc)))]
12641   ""
12642   "ix86_expand_branch (LT, operands[0]); DONE;")
12643
12644 (define_expand "bltu"
12645   [(set (pc)
12646         (if_then_else (match_dup 1)
12647                       (label_ref (match_operand 0 "" ""))
12648                       (pc)))]
12649   ""
12650   "ix86_expand_branch (LTU, operands[0]); DONE;")
12651
12652 (define_expand "bge"
12653   [(set (pc)
12654         (if_then_else (match_dup 1)
12655                       (label_ref (match_operand 0 "" ""))
12656                       (pc)))]
12657   ""
12658   "ix86_expand_branch (GE, operands[0]); DONE;")
12659
12660 (define_expand "bgeu"
12661   [(set (pc)
12662         (if_then_else (match_dup 1)
12663                       (label_ref (match_operand 0 "" ""))
12664                       (pc)))]
12665   ""
12666   "ix86_expand_branch (GEU, operands[0]); DONE;")
12667
12668 (define_expand "ble"
12669   [(set (pc)
12670         (if_then_else (match_dup 1)
12671                       (label_ref (match_operand 0 "" ""))
12672                       (pc)))]
12673   ""
12674   "ix86_expand_branch (LE, operands[0]); DONE;")
12675
12676 (define_expand "bleu"
12677   [(set (pc)
12678         (if_then_else (match_dup 1)
12679                       (label_ref (match_operand 0 "" ""))
12680                       (pc)))]
12681   ""
12682   "ix86_expand_branch (LEU, operands[0]); DONE;")
12683
12684 (define_expand "bunordered"
12685   [(set (pc)
12686         (if_then_else (match_dup 1)
12687                       (label_ref (match_operand 0 "" ""))
12688                       (pc)))]
12689   "TARGET_80387 || TARGET_SSE"
12690   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12691
12692 (define_expand "bordered"
12693   [(set (pc)
12694         (if_then_else (match_dup 1)
12695                       (label_ref (match_operand 0 "" ""))
12696                       (pc)))]
12697   "TARGET_80387 || TARGET_SSE"
12698   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12699
12700 (define_expand "buneq"
12701   [(set (pc)
12702         (if_then_else (match_dup 1)
12703                       (label_ref (match_operand 0 "" ""))
12704                       (pc)))]
12705   "TARGET_80387 || TARGET_SSE"
12706   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12707
12708 (define_expand "bunge"
12709   [(set (pc)
12710         (if_then_else (match_dup 1)
12711                       (label_ref (match_operand 0 "" ""))
12712                       (pc)))]
12713   "TARGET_80387 || TARGET_SSE"
12714   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12715
12716 (define_expand "bungt"
12717   [(set (pc)
12718         (if_then_else (match_dup 1)
12719                       (label_ref (match_operand 0 "" ""))
12720                       (pc)))]
12721   "TARGET_80387 || TARGET_SSE"
12722   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12723
12724 (define_expand "bunle"
12725   [(set (pc)
12726         (if_then_else (match_dup 1)
12727                       (label_ref (match_operand 0 "" ""))
12728                       (pc)))]
12729   "TARGET_80387 || TARGET_SSE"
12730   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12731
12732 (define_expand "bunlt"
12733   [(set (pc)
12734         (if_then_else (match_dup 1)
12735                       (label_ref (match_operand 0 "" ""))
12736                       (pc)))]
12737   "TARGET_80387 || TARGET_SSE"
12738   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12739
12740 (define_expand "bltgt"
12741   [(set (pc)
12742         (if_then_else (match_dup 1)
12743                       (label_ref (match_operand 0 "" ""))
12744                       (pc)))]
12745   "TARGET_80387 || TARGET_SSE"
12746   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12747
12748 (define_insn "*jcc_1"
12749   [(set (pc)
12750         (if_then_else (match_operator 1 "ix86_comparison_operator"
12751                                       [(reg FLAGS_REG) (const_int 0)])
12752                       (label_ref (match_operand 0 "" ""))
12753                       (pc)))]
12754   ""
12755   "%+j%C1\t%l0"
12756   [(set_attr "type" "ibr")
12757    (set_attr "modrm" "0")
12758    (set (attr "length")
12759            (if_then_else (and (ge (minus (match_dup 0) (pc))
12760                                   (const_int -126))
12761                               (lt (minus (match_dup 0) (pc))
12762                                   (const_int 128)))
12763              (const_int 2)
12764              (const_int 6)))])
12765
12766 (define_insn "*jcc_2"
12767   [(set (pc)
12768         (if_then_else (match_operator 1 "ix86_comparison_operator"
12769                                       [(reg FLAGS_REG) (const_int 0)])
12770                       (pc)
12771                       (label_ref (match_operand 0 "" ""))))]
12772   ""
12773   "%+j%c1\t%l0"
12774   [(set_attr "type" "ibr")
12775    (set_attr "modrm" "0")
12776    (set (attr "length")
12777            (if_then_else (and (ge (minus (match_dup 0) (pc))
12778                                   (const_int -126))
12779                               (lt (minus (match_dup 0) (pc))
12780                                   (const_int 128)))
12781              (const_int 2)
12782              (const_int 6)))])
12783
12784 ;; In general it is not safe to assume too much about CCmode registers,
12785 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12786 ;; conditions this is safe on x86, so help combine not create
12787 ;;
12788 ;;      seta    %al
12789 ;;      testb   %al, %al
12790 ;;      je      Lfoo
12791
12792 (define_split 
12793   [(set (pc)
12794         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12795                                       [(reg FLAGS_REG) (const_int 0)])
12796                           (const_int 0))
12797                       (label_ref (match_operand 1 "" ""))
12798                       (pc)))]
12799   ""
12800   [(set (pc)
12801         (if_then_else (match_dup 0)
12802                       (label_ref (match_dup 1))
12803                       (pc)))]
12804 {
12805   PUT_MODE (operands[0], VOIDmode);
12806 })
12807   
12808 (define_split 
12809   [(set (pc)
12810         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12811                                       [(reg FLAGS_REG) (const_int 0)])
12812                           (const_int 0))
12813                       (label_ref (match_operand 1 "" ""))
12814                       (pc)))]
12815   ""
12816   [(set (pc)
12817         (if_then_else (match_dup 0)
12818                       (label_ref (match_dup 1))
12819                       (pc)))]
12820 {
12821   rtx new_op0 = copy_rtx (operands[0]);
12822   operands[0] = new_op0;
12823   PUT_MODE (new_op0, VOIDmode);
12824   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12825                                              GET_MODE (XEXP (new_op0, 0))));
12826
12827   /* Make sure that (a) the CCmode we have for the flags is strong
12828      enough for the reversed compare or (b) we have a valid FP compare.  */
12829   if (! ix86_comparison_operator (new_op0, VOIDmode))
12830     FAIL;
12831 })
12832
12833 ;; Define combination compare-and-branch fp compare instructions to use
12834 ;; during early optimization.  Splitting the operation apart early makes
12835 ;; for bad code when we want to reverse the operation.
12836
12837 (define_insn "*fp_jcc_1"
12838   [(set (pc)
12839         (if_then_else (match_operator 0 "comparison_operator"
12840                         [(match_operand 1 "register_operand" "f")
12841                          (match_operand 2 "register_operand" "f")])
12842           (label_ref (match_operand 3 "" ""))
12843           (pc)))
12844    (clobber (reg:CCFP FPSR_REG))
12845    (clobber (reg:CCFP FLAGS_REG))]
12846   "TARGET_CMOVE && TARGET_80387
12847    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12848    && FLOAT_MODE_P (GET_MODE (operands[1]))
12849    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12850    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12851   "#")
12852
12853 (define_insn "*fp_jcc_1_sse"
12854   [(set (pc)
12855         (if_then_else (match_operator 0 "comparison_operator"
12856                         [(match_operand 1 "register_operand" "f#x,x#f")
12857                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12858           (label_ref (match_operand 3 "" ""))
12859           (pc)))
12860    (clobber (reg:CCFP FPSR_REG))
12861    (clobber (reg:CCFP FLAGS_REG))]
12862   "TARGET_80387
12863    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12864    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12865    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12866   "#")
12867
12868 (define_insn "*fp_jcc_1_sse_only"
12869   [(set (pc)
12870         (if_then_else (match_operator 0 "comparison_operator"
12871                         [(match_operand 1 "register_operand" "x")
12872                          (match_operand 2 "nonimmediate_operand" "xm")])
12873           (label_ref (match_operand 3 "" ""))
12874           (pc)))
12875    (clobber (reg:CCFP FPSR_REG))
12876    (clobber (reg:CCFP FLAGS_REG))]
12877   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12878    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12879    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12880   "#")
12881
12882 (define_insn "*fp_jcc_2"
12883   [(set (pc)
12884         (if_then_else (match_operator 0 "comparison_operator"
12885                         [(match_operand 1 "register_operand" "f")
12886                          (match_operand 2 "register_operand" "f")])
12887           (pc)
12888           (label_ref (match_operand 3 "" ""))))
12889    (clobber (reg:CCFP FPSR_REG))
12890    (clobber (reg:CCFP FLAGS_REG))]
12891   "TARGET_CMOVE && TARGET_80387
12892    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12893    && FLOAT_MODE_P (GET_MODE (operands[1]))
12894    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12895    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12896   "#")
12897
12898 (define_insn "*fp_jcc_2_sse"
12899   [(set (pc)
12900         (if_then_else (match_operator 0 "comparison_operator"
12901                         [(match_operand 1 "register_operand" "f#x,x#f")
12902                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12903           (pc)
12904           (label_ref (match_operand 3 "" ""))))
12905    (clobber (reg:CCFP FPSR_REG))
12906    (clobber (reg:CCFP FLAGS_REG))]
12907   "TARGET_80387
12908    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12909    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12910    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12911   "#")
12912
12913 (define_insn "*fp_jcc_2_sse_only"
12914   [(set (pc)
12915         (if_then_else (match_operator 0 "comparison_operator"
12916                         [(match_operand 1 "register_operand" "x")
12917                          (match_operand 2 "nonimmediate_operand" "xm")])
12918           (pc)
12919           (label_ref (match_operand 3 "" ""))))
12920    (clobber (reg:CCFP FPSR_REG))
12921    (clobber (reg:CCFP FLAGS_REG))]
12922   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12923    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12924    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12925   "#")
12926
12927 (define_insn "*fp_jcc_3"
12928   [(set (pc)
12929         (if_then_else (match_operator 0 "comparison_operator"
12930                         [(match_operand 1 "register_operand" "f")
12931                          (match_operand 2 "nonimmediate_operand" "fm")])
12932           (label_ref (match_operand 3 "" ""))
12933           (pc)))
12934    (clobber (reg:CCFP FPSR_REG))
12935    (clobber (reg:CCFP FLAGS_REG))
12936    (clobber (match_scratch:HI 4 "=a"))]
12937   "TARGET_80387
12938    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12939    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12940    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12941    && SELECT_CC_MODE (GET_CODE (operands[0]),
12942                       operands[1], operands[2]) == CCFPmode
12943    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12944   "#")
12945
12946 (define_insn "*fp_jcc_4"
12947   [(set (pc)
12948         (if_then_else (match_operator 0 "comparison_operator"
12949                         [(match_operand 1 "register_operand" "f")
12950                          (match_operand 2 "nonimmediate_operand" "fm")])
12951           (pc)
12952           (label_ref (match_operand 3 "" ""))))
12953    (clobber (reg:CCFP FPSR_REG))
12954    (clobber (reg:CCFP FLAGS_REG))
12955    (clobber (match_scratch:HI 4 "=a"))]
12956   "TARGET_80387
12957    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12958    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12959    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12960    && SELECT_CC_MODE (GET_CODE (operands[0]),
12961                       operands[1], operands[2]) == CCFPmode
12962    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12963   "#")
12964
12965 (define_insn "*fp_jcc_5"
12966   [(set (pc)
12967         (if_then_else (match_operator 0 "comparison_operator"
12968                         [(match_operand 1 "register_operand" "f")
12969                          (match_operand 2 "register_operand" "f")])
12970           (label_ref (match_operand 3 "" ""))
12971           (pc)))
12972    (clobber (reg:CCFP FPSR_REG))
12973    (clobber (reg:CCFP FLAGS_REG))
12974    (clobber (match_scratch:HI 4 "=a"))]
12975   "TARGET_80387
12976    && FLOAT_MODE_P (GET_MODE (operands[1]))
12977    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12978    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12979   "#")
12980
12981 (define_insn "*fp_jcc_6"
12982   [(set (pc)
12983         (if_then_else (match_operator 0 "comparison_operator"
12984                         [(match_operand 1 "register_operand" "f")
12985                          (match_operand 2 "register_operand" "f")])
12986           (pc)
12987           (label_ref (match_operand 3 "" ""))))
12988    (clobber (reg:CCFP FPSR_REG))
12989    (clobber (reg:CCFP FLAGS_REG))
12990    (clobber (match_scratch:HI 4 "=a"))]
12991   "TARGET_80387
12992    && FLOAT_MODE_P (GET_MODE (operands[1]))
12993    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12994    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12995   "#")
12996
12997 (define_insn "*fp_jcc_7"
12998   [(set (pc)
12999         (if_then_else (match_operator 0 "comparison_operator"
13000                         [(match_operand 1 "register_operand" "f")
13001                          (match_operand 2 "const_double_operand" "C")])
13002           (label_ref (match_operand 3 "" ""))
13003           (pc)))
13004    (clobber (reg:CCFP FPSR_REG))
13005    (clobber (reg:CCFP FLAGS_REG))
13006    (clobber (match_scratch:HI 4 "=a"))]
13007   "TARGET_80387
13008    && FLOAT_MODE_P (GET_MODE (operands[1]))
13009    && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
13010    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13011    && SELECT_CC_MODE (GET_CODE (operands[0]),
13012                       operands[1], operands[2]) == CCFPmode
13013    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13014   "#")
13015
13016 ;; The order of operands in *fp_jcc_8 is forced by combine in
13017 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13018 ;; with a precedence over other operators and is always put in the first
13019 ;; place. Swap condition and operands to match ficom instruction.
13020
13021 (define_insn "*fp_jcc_8"
13022   [(set (pc)
13023         (if_then_else (match_operator 0 "comparison_operator"
13024                         [(match_operator 1 "float_operator"
13025                            [(match_operand:SI 2 "nonimmediate_operand" "m,?r")])
13026                            (match_operand 3 "register_operand" "f,f")])
13027           (label_ref (match_operand 4 "" ""))
13028           (pc)))
13029    (clobber (reg:CCFP FPSR_REG))
13030    (clobber (reg:CCFP FLAGS_REG))
13031    (clobber (match_scratch:HI 5 "=a,a"))]
13032   "TARGET_80387 && TARGET_USE_FIOP
13033    && FLOAT_MODE_P (GET_MODE (operands[3]))
13034    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13035    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13036    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13037    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13038   "#")
13039
13040 (define_split
13041   [(set (pc)
13042         (if_then_else (match_operator 0 "comparison_operator"
13043                         [(match_operand 1 "register_operand" "")
13044                          (match_operand 2 "nonimmediate_operand" "")])
13045           (match_operand 3 "" "")
13046           (match_operand 4 "" "")))
13047    (clobber (reg:CCFP FPSR_REG))
13048    (clobber (reg:CCFP FLAGS_REG))]
13049   "reload_completed"
13050   [(const_int 0)]
13051 {
13052   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13053                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13054   DONE;
13055 })
13056
13057 (define_split
13058   [(set (pc)
13059         (if_then_else (match_operator 0 "comparison_operator"
13060                         [(match_operand 1 "register_operand" "")
13061                          (match_operand 2 "general_operand" "")])
13062           (match_operand 3 "" "")
13063           (match_operand 4 "" "")))
13064    (clobber (reg:CCFP FPSR_REG))
13065    (clobber (reg:CCFP FLAGS_REG))
13066    (clobber (match_scratch:HI 5 "=a"))]
13067   "reload_completed"
13068   [(const_int 0)]
13069 {
13070   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13071                         operands[3], operands[4], operands[5], NULL_RTX);
13072   DONE;
13073 })
13074
13075 (define_split
13076   [(set (pc)
13077         (if_then_else (match_operator 0 "comparison_operator"
13078                         [(match_operator 1 "float_operator"
13079                            [(match_operand:SI 2 "memory_operand" "")])
13080                            (match_operand 3 "register_operand" "")])
13081           (match_operand 4 "" "")
13082           (match_operand 5 "" "")))
13083    (clobber (reg:CCFP FPSR_REG))
13084    (clobber (reg:CCFP FLAGS_REG))
13085    (clobber (match_scratch:HI 6 "=a"))]
13086   "reload_completed"
13087   [(const_int 0)]
13088 {
13089   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13090   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13091                         operands[3], operands[7],
13092                         operands[4], operands[5], operands[6], NULL_RTX);
13093   DONE;
13094 })
13095
13096 ;; %%% Kill this when reload knows how to do it.
13097 (define_split
13098   [(set (pc)
13099         (if_then_else (match_operator 0 "comparison_operator"
13100                         [(match_operator 1 "float_operator"
13101                            [(match_operand:SI 2 "register_operand" "")])
13102                            (match_operand 3 "register_operand" "")])
13103           (match_operand 4 "" "")
13104           (match_operand 5 "" "")))
13105    (clobber (reg:CCFP FPSR_REG))
13106    (clobber (reg:CCFP FLAGS_REG))
13107    (clobber (match_scratch:HI 6 "=a"))]
13108   "reload_completed"
13109   [(const_int 0)]
13110 {
13111   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13112   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13113   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13114                         operands[3], operands[7],
13115                         operands[4], operands[5], operands[6], operands[2]);
13116   DONE;
13117 })
13118 \f
13119 ;; Unconditional and other jump instructions
13120
13121 (define_insn "jump"
13122   [(set (pc)
13123         (label_ref (match_operand 0 "" "")))]
13124   ""
13125   "jmp\t%l0"
13126   [(set_attr "type" "ibr")
13127    (set (attr "length")
13128            (if_then_else (and (ge (minus (match_dup 0) (pc))
13129                                   (const_int -126))
13130                               (lt (minus (match_dup 0) (pc))
13131                                   (const_int 128)))
13132              (const_int 2)
13133              (const_int 5)))
13134    (set_attr "modrm" "0")])
13135
13136 (define_expand "indirect_jump"
13137   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13138   ""
13139   "")
13140
13141 (define_insn "*indirect_jump"
13142   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13143   "!TARGET_64BIT"
13144   "jmp\t%A0"
13145   [(set_attr "type" "ibr")
13146    (set_attr "length_immediate" "0")])
13147
13148 (define_insn "*indirect_jump_rtx64"
13149   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13150   "TARGET_64BIT"
13151   "jmp\t%A0"
13152   [(set_attr "type" "ibr")
13153    (set_attr "length_immediate" "0")])
13154
13155 (define_expand "tablejump"
13156   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13157               (use (label_ref (match_operand 1 "" "")))])]
13158   ""
13159 {
13160   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13161      relative.  Convert the relative address to an absolute address.  */
13162   if (flag_pic)
13163     {
13164       rtx op0, op1;
13165       enum rtx_code code;
13166
13167       if (TARGET_64BIT)
13168         {
13169           code = PLUS;
13170           op0 = operands[0];
13171           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13172         }
13173       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13174         {
13175           code = PLUS;
13176           op0 = operands[0];
13177           op1 = pic_offset_table_rtx;
13178         }
13179       else
13180         {
13181           code = MINUS;
13182           op0 = pic_offset_table_rtx;
13183           op1 = operands[0];
13184         }
13185
13186       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13187                                          OPTAB_DIRECT);
13188     }
13189 })
13190
13191 (define_insn "*tablejump_1"
13192   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13193    (use (label_ref (match_operand 1 "" "")))]
13194   "!TARGET_64BIT"
13195   "jmp\t%A0"
13196   [(set_attr "type" "ibr")
13197    (set_attr "length_immediate" "0")])
13198
13199 (define_insn "*tablejump_1_rtx64"
13200   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13201    (use (label_ref (match_operand 1 "" "")))]
13202   "TARGET_64BIT"
13203   "jmp\t%A0"
13204   [(set_attr "type" "ibr")
13205    (set_attr "length_immediate" "0")])
13206 \f
13207 ;; Loop instruction
13208 ;;
13209 ;; This is all complicated by the fact that since this is a jump insn
13210 ;; we must handle our own reloads.
13211
13212 (define_expand "doloop_end"
13213   [(use (match_operand 0 "" ""))        ; loop pseudo
13214    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13215    (use (match_operand 2 "" ""))        ; max iterations
13216    (use (match_operand 3 "" ""))        ; loop level 
13217    (use (match_operand 4 "" ""))]       ; label
13218   "!TARGET_64BIT && TARGET_USE_LOOP"
13219   "                                 
13220 {
13221   /* Only use cloop on innermost loops.  */
13222   if (INTVAL (operands[3]) > 1)
13223     FAIL;
13224   if (GET_MODE (operands[0]) != SImode)
13225     FAIL;
13226   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13227                                            operands[0]));
13228   DONE;
13229 }")
13230
13231 (define_insn "doloop_end_internal"
13232   [(set (pc)
13233         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13234                           (const_int 1))
13235                       (label_ref (match_operand 0 "" ""))
13236                       (pc)))
13237    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13238         (plus:SI (match_dup 1)
13239                  (const_int -1)))
13240    (clobber (match_scratch:SI 3 "=X,X,r"))
13241    (clobber (reg:CC FLAGS_REG))]
13242   "!TARGET_64BIT && TARGET_USE_LOOP
13243    && (reload_in_progress || reload_completed
13244        || register_operand (operands[2], VOIDmode))"
13245 {
13246   if (which_alternative != 0)
13247     return "#";
13248   if (get_attr_length (insn) == 2)
13249     return "%+loop\t%l0";
13250   else
13251     return "dec{l}\t%1\;%+jne\t%l0";
13252 }
13253   [(set (attr "length")
13254         (if_then_else (and (eq_attr "alternative" "0")
13255                            (and (ge (minus (match_dup 0) (pc))
13256                                     (const_int -126))
13257                                 (lt (minus (match_dup 0) (pc))
13258                                     (const_int 128))))
13259                       (const_int 2)
13260                       (const_int 16)))
13261    ;; We don't know the type before shorten branches.  Optimistically expect
13262    ;; the loop instruction to match.
13263    (set (attr "type") (const_string "ibr"))])
13264
13265 (define_split
13266   [(set (pc)
13267         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13268                           (const_int 1))
13269                       (match_operand 0 "" "")
13270                       (pc)))
13271    (set (match_dup 1)
13272         (plus:SI (match_dup 1)
13273                  (const_int -1)))
13274    (clobber (match_scratch:SI 2 ""))
13275    (clobber (reg:CC FLAGS_REG))]
13276   "!TARGET_64BIT && TARGET_USE_LOOP
13277    && reload_completed
13278    && REGNO (operands[1]) != 2"
13279   [(parallel [(set (reg:CCZ FLAGS_REG)
13280                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13281                                  (const_int 0)))
13282               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13283    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13284                            (match_dup 0)
13285                            (pc)))]
13286   "")
13287   
13288 (define_split
13289   [(set (pc)
13290         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13291                           (const_int 1))
13292                       (match_operand 0 "" "")
13293                       (pc)))
13294    (set (match_operand:SI 2 "nonimmediate_operand" "")
13295         (plus:SI (match_dup 1)
13296                  (const_int -1)))
13297    (clobber (match_scratch:SI 3 ""))
13298    (clobber (reg:CC FLAGS_REG))]
13299   "!TARGET_64BIT && TARGET_USE_LOOP
13300    && reload_completed
13301    && (! REG_P (operands[2])
13302        || ! rtx_equal_p (operands[1], operands[2]))"
13303   [(set (match_dup 3) (match_dup 1))
13304    (parallel [(set (reg:CCZ FLAGS_REG)
13305                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13306                                 (const_int 0)))
13307               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13308    (set (match_dup 2) (match_dup 3))
13309    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13310                            (match_dup 0)
13311                            (pc)))]
13312   "")
13313
13314 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13315
13316 (define_peephole2
13317   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13318    (set (match_operand:QI 1 "register_operand" "")
13319         (match_operator:QI 2 "ix86_comparison_operator"
13320           [(reg FLAGS_REG) (const_int 0)]))
13321    (set (match_operand 3 "q_regs_operand" "")
13322         (zero_extend (match_dup 1)))]
13323   "(peep2_reg_dead_p (3, operands[1])
13324     || operands_match_p (operands[1], operands[3]))
13325    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13326   [(set (match_dup 4) (match_dup 0))
13327    (set (strict_low_part (match_dup 5))
13328         (match_dup 2))]
13329 {
13330   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13331   operands[5] = gen_lowpart (QImode, operands[3]);
13332   ix86_expand_clear (operands[3]);
13333 })
13334
13335 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13336
13337 (define_peephole2
13338   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13339    (set (match_operand:QI 1 "register_operand" "")
13340         (match_operator:QI 2 "ix86_comparison_operator"
13341           [(reg FLAGS_REG) (const_int 0)]))
13342    (parallel [(set (match_operand 3 "q_regs_operand" "")
13343                    (zero_extend (match_dup 1)))
13344               (clobber (reg:CC FLAGS_REG))])]
13345   "(peep2_reg_dead_p (3, operands[1])
13346     || operands_match_p (operands[1], operands[3]))
13347    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13348   [(set (match_dup 4) (match_dup 0))
13349    (set (strict_low_part (match_dup 5))
13350         (match_dup 2))]
13351 {
13352   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13353   operands[5] = gen_lowpart (QImode, operands[3]);
13354   ix86_expand_clear (operands[3]);
13355 })
13356 \f
13357 ;; Call instructions.
13358
13359 ;; The predicates normally associated with named expanders are not properly
13360 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13361 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13362
13363 ;; Call subroutine returning no value.
13364
13365 (define_expand "call_pop"
13366   [(parallel [(call (match_operand:QI 0 "" "")
13367                     (match_operand:SI 1 "" ""))
13368               (set (reg:SI SP_REG)
13369                    (plus:SI (reg:SI SP_REG)
13370                             (match_operand:SI 3 "" "")))])]
13371   "!TARGET_64BIT"
13372 {
13373   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13374   DONE;
13375 })
13376
13377 (define_insn "*call_pop_0"
13378   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13379          (match_operand:SI 1 "" ""))
13380    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13381                             (match_operand:SI 2 "immediate_operand" "")))]
13382   "!TARGET_64BIT"
13383 {
13384   if (SIBLING_CALL_P (insn))
13385     return "jmp\t%P0";
13386   else
13387     return "call\t%P0";
13388 }
13389   [(set_attr "type" "call")])
13390   
13391 (define_insn "*call_pop_1"
13392   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13393          (match_operand:SI 1 "" ""))
13394    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13395                             (match_operand:SI 2 "immediate_operand" "i")))]
13396   "!TARGET_64BIT"
13397 {
13398   if (constant_call_address_operand (operands[0], Pmode))
13399     {
13400       if (SIBLING_CALL_P (insn))
13401         return "jmp\t%P0";
13402       else
13403         return "call\t%P0";
13404     }
13405   if (SIBLING_CALL_P (insn))
13406     return "jmp\t%A0";
13407   else
13408     return "call\t%A0";
13409 }
13410   [(set_attr "type" "call")])
13411
13412 (define_expand "call"
13413   [(call (match_operand:QI 0 "" "")
13414          (match_operand 1 "" ""))
13415    (use (match_operand 2 "" ""))]
13416   ""
13417 {
13418   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13419   DONE;
13420 })
13421
13422 (define_expand "sibcall"
13423   [(call (match_operand:QI 0 "" "")
13424          (match_operand 1 "" ""))
13425    (use (match_operand 2 "" ""))]
13426   ""
13427 {
13428   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13429   DONE;
13430 })
13431
13432 (define_insn "*call_0"
13433   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13434          (match_operand 1 "" ""))]
13435   ""
13436 {
13437   if (SIBLING_CALL_P (insn))
13438     return "jmp\t%P0";
13439   else
13440     return "call\t%P0";
13441 }
13442   [(set_attr "type" "call")])
13443
13444 (define_insn "*call_1"
13445   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13446          (match_operand 1 "" ""))]
13447   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13448 {
13449   if (constant_call_address_operand (operands[0], Pmode))
13450     return "call\t%P0";
13451   return "call\t%A0";
13452 }
13453   [(set_attr "type" "call")])
13454
13455 (define_insn "*sibcall_1"
13456   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13457          (match_operand 1 "" ""))]
13458   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13459 {
13460   if (constant_call_address_operand (operands[0], Pmode))
13461     return "jmp\t%P0";
13462   return "jmp\t%A0";
13463 }
13464   [(set_attr "type" "call")])
13465
13466 (define_insn "*call_1_rex64"
13467   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13468          (match_operand 1 "" ""))]
13469   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13470 {
13471   if (constant_call_address_operand (operands[0], Pmode))
13472     return "call\t%P0";
13473   return "call\t%A0";
13474 }
13475   [(set_attr "type" "call")])
13476
13477 (define_insn "*sibcall_1_rex64"
13478   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13479          (match_operand 1 "" ""))]
13480   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13481   "jmp\t%P0"
13482   [(set_attr "type" "call")])
13483
13484 (define_insn "*sibcall_1_rex64_v"
13485   [(call (mem:QI (reg:DI 40))
13486          (match_operand 0 "" ""))]
13487   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13488   "jmp\t*%%r11"
13489   [(set_attr "type" "call")])
13490
13491
13492 ;; Call subroutine, returning value in operand 0
13493
13494 (define_expand "call_value_pop"
13495   [(parallel [(set (match_operand 0 "" "")
13496                    (call (match_operand:QI 1 "" "")
13497                          (match_operand:SI 2 "" "")))
13498               (set (reg:SI SP_REG)
13499                    (plus:SI (reg:SI SP_REG)
13500                             (match_operand:SI 4 "" "")))])]
13501   "!TARGET_64BIT"
13502 {
13503   ix86_expand_call (operands[0], operands[1], operands[2],
13504                     operands[3], operands[4], 0);
13505   DONE;
13506 })
13507
13508 (define_expand "call_value"
13509   [(set (match_operand 0 "" "")
13510         (call (match_operand:QI 1 "" "")
13511               (match_operand:SI 2 "" "")))
13512    (use (match_operand:SI 3 "" ""))]
13513   ;; Operand 2 not used on the i386.
13514   ""
13515 {
13516   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13517   DONE;
13518 })
13519
13520 (define_expand "sibcall_value"
13521   [(set (match_operand 0 "" "")
13522         (call (match_operand:QI 1 "" "")
13523               (match_operand:SI 2 "" "")))
13524    (use (match_operand:SI 3 "" ""))]
13525   ;; Operand 2 not used on the i386.
13526   ""
13527 {
13528   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13529   DONE;
13530 })
13531
13532 ;; Call subroutine returning any type.
13533
13534 (define_expand "untyped_call"
13535   [(parallel [(call (match_operand 0 "" "")
13536                     (const_int 0))
13537               (match_operand 1 "" "")
13538               (match_operand 2 "" "")])]
13539   ""
13540 {
13541   int i;
13542
13543   /* In order to give reg-stack an easier job in validating two
13544      coprocessor registers as containing a possible return value,
13545      simply pretend the untyped call returns a complex long double
13546      value.  */
13547
13548   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13549                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13550                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13551                     NULL, 0);
13552
13553   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13554     {
13555       rtx set = XVECEXP (operands[2], 0, i);
13556       emit_move_insn (SET_DEST (set), SET_SRC (set));
13557     }
13558
13559   /* The optimizer does not know that the call sets the function value
13560      registers we stored in the result block.  We avoid problems by
13561      claiming that all hard registers are used and clobbered at this
13562      point.  */
13563   emit_insn (gen_blockage (const0_rtx));
13564
13565   DONE;
13566 })
13567 \f
13568 ;; Prologue and epilogue instructions
13569
13570 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13571 ;; all of memory.  This blocks insns from being moved across this point.
13572
13573 (define_insn "blockage"
13574   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13575   ""
13576   ""
13577   [(set_attr "length" "0")])
13578
13579 ;; Insn emitted into the body of a function to return from a function.
13580 ;; This is only done if the function's epilogue is known to be simple.
13581 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13582
13583 (define_expand "return"
13584   [(return)]
13585   "ix86_can_use_return_insn_p ()"
13586 {
13587   if (current_function_pops_args)
13588     {
13589       rtx popc = GEN_INT (current_function_pops_args);
13590       emit_jump_insn (gen_return_pop_internal (popc));
13591       DONE;
13592     }
13593 })
13594
13595 (define_insn "return_internal"
13596   [(return)]
13597   "reload_completed"
13598   "ret"
13599   [(set_attr "length" "1")
13600    (set_attr "length_immediate" "0")
13601    (set_attr "modrm" "0")])
13602
13603 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13604 ;; instruction Athlon and K8 have.
13605
13606 (define_insn "return_internal_long"
13607   [(return)
13608    (unspec [(const_int 0)] UNSPEC_REP)]
13609   "reload_completed"
13610   "rep {;} ret"
13611   [(set_attr "length" "1")
13612    (set_attr "length_immediate" "0")
13613    (set_attr "prefix_rep" "1")
13614    (set_attr "modrm" "0")])
13615
13616 (define_insn "return_pop_internal"
13617   [(return)
13618    (use (match_operand:SI 0 "const_int_operand" ""))]
13619   "reload_completed"
13620   "ret\t%0"
13621   [(set_attr "length" "3")
13622    (set_attr "length_immediate" "2")
13623    (set_attr "modrm" "0")])
13624
13625 (define_insn "return_indirect_internal"
13626   [(return)
13627    (use (match_operand:SI 0 "register_operand" "r"))]
13628   "reload_completed"
13629   "jmp\t%A0"
13630   [(set_attr "type" "ibr")
13631    (set_attr "length_immediate" "0")])
13632
13633 (define_insn "nop"
13634   [(const_int 0)]
13635   ""
13636   "nop"
13637   [(set_attr "length" "1")
13638    (set_attr "length_immediate" "0")
13639    (set_attr "modrm" "0")])
13640
13641 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13642 ;; branch prediction penalty for the third jump in a 16-byte
13643 ;; block on K8.
13644
13645 (define_insn "align"
13646   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13647   ""
13648 {
13649 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13650   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13651 #else
13652   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13653      The align insn is used to avoid 3 jump instructions in the row to improve
13654      branch prediction and the benefits hardly outweight the cost of extra 8
13655      nops on the average inserted by full alignment pseudo operation.  */
13656 #endif
13657   return "";
13658 }
13659   [(set_attr "length" "16")])
13660
13661 (define_expand "prologue"
13662   [(const_int 1)]
13663   ""
13664   "ix86_expand_prologue (); DONE;")
13665
13666 (define_insn "set_got"
13667   [(set (match_operand:SI 0 "register_operand" "=r")
13668         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13669    (clobber (reg:CC FLAGS_REG))]
13670   "!TARGET_64BIT"
13671   { return output_set_got (operands[0]); }
13672   [(set_attr "type" "multi")
13673    (set_attr "length" "12")])
13674
13675 (define_expand "epilogue"
13676   [(const_int 1)]
13677   ""
13678   "ix86_expand_epilogue (1); DONE;")
13679
13680 (define_expand "sibcall_epilogue"
13681   [(const_int 1)]
13682   ""
13683   "ix86_expand_epilogue (0); DONE;")
13684
13685 (define_expand "eh_return"
13686   [(use (match_operand 0 "register_operand" ""))]
13687   ""
13688 {
13689   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13690
13691   /* Tricky bit: we write the address of the handler to which we will
13692      be returning into someone else's stack frame, one word below the
13693      stack address we wish to restore.  */
13694   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13695   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13696   tmp = gen_rtx_MEM (Pmode, tmp);
13697   emit_move_insn (tmp, ra);
13698
13699   if (Pmode == SImode)
13700     emit_jump_insn (gen_eh_return_si (sa));
13701   else
13702     emit_jump_insn (gen_eh_return_di (sa));
13703   emit_barrier ();
13704   DONE;
13705 })
13706
13707 (define_insn_and_split "eh_return_si"
13708   [(set (pc) 
13709         (unspec [(match_operand:SI 0 "register_operand" "c")]
13710                  UNSPEC_EH_RETURN))]
13711   "!TARGET_64BIT"
13712   "#"
13713   "reload_completed"
13714   [(const_int 1)]
13715   "ix86_expand_epilogue (2); DONE;")
13716
13717 (define_insn_and_split "eh_return_di"
13718   [(set (pc) 
13719         (unspec [(match_operand:DI 0 "register_operand" "c")]
13720                  UNSPEC_EH_RETURN))]
13721   "TARGET_64BIT"
13722   "#"
13723   "reload_completed"
13724   [(const_int 1)]
13725   "ix86_expand_epilogue (2); DONE;")
13726
13727 (define_insn "leave"
13728   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13729    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13730    (clobber (mem:BLK (scratch)))]
13731   "!TARGET_64BIT"
13732   "leave"
13733   [(set_attr "type" "leave")])
13734
13735 (define_insn "leave_rex64"
13736   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13737    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13738    (clobber (mem:BLK (scratch)))]
13739   "TARGET_64BIT"
13740   "leave"
13741   [(set_attr "type" "leave")])
13742 \f
13743 (define_expand "ffssi2"
13744   [(parallel
13745      [(set (match_operand:SI 0 "register_operand" "") 
13746            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13747       (clobber (match_scratch:SI 2 ""))
13748       (clobber (reg:CC FLAGS_REG))])]
13749   ""
13750   "")
13751
13752 (define_insn_and_split "*ffs_cmove"
13753   [(set (match_operand:SI 0 "register_operand" "=r") 
13754         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13755    (clobber (match_scratch:SI 2 "=&r"))
13756    (clobber (reg:CC FLAGS_REG))]
13757   "TARGET_CMOVE"
13758   "#"
13759   "&& reload_completed"
13760   [(set (match_dup 2) (const_int -1))
13761    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13762               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13763    (set (match_dup 0) (if_then_else:SI
13764                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13765                         (match_dup 2)
13766                         (match_dup 0)))
13767    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13768               (clobber (reg:CC FLAGS_REG))])]
13769   "")
13770
13771 (define_insn_and_split "*ffs_no_cmove"
13772   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13773         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13774    (clobber (match_scratch:SI 2 "=&q"))
13775    (clobber (reg:CC FLAGS_REG))]
13776   ""
13777   "#"
13778   "reload_completed"
13779   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13780               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13781    (set (strict_low_part (match_dup 3))
13782         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13783    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13784               (clobber (reg:CC FLAGS_REG))])
13785    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13786               (clobber (reg:CC FLAGS_REG))])
13787    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13788               (clobber (reg:CC FLAGS_REG))])]
13789 {
13790   operands[3] = gen_lowpart (QImode, operands[2]);
13791   ix86_expand_clear (operands[2]);
13792 })
13793
13794 (define_insn "*ffssi_1"
13795   [(set (reg:CCZ FLAGS_REG)
13796         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13797                      (const_int 0)))
13798    (set (match_operand:SI 0 "register_operand" "=r")
13799         (ctz:SI (match_dup 1)))]
13800   ""
13801   "bsf{l}\t{%1, %0|%0, %1}"
13802   [(set_attr "prefix_0f" "1")])
13803
13804 (define_expand "ffsdi2"
13805   [(parallel
13806      [(set (match_operand:DI 0 "register_operand" "") 
13807            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13808       (clobber (match_scratch:DI 2 ""))
13809       (clobber (reg:CC FLAGS_REG))])]
13810   "TARGET_64BIT && TARGET_CMOVE"
13811   "")
13812
13813 (define_insn_and_split "*ffs_rex64"
13814   [(set (match_operand:DI 0 "register_operand" "=r") 
13815         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13816    (clobber (match_scratch:DI 2 "=&r"))
13817    (clobber (reg:CC FLAGS_REG))]
13818   "TARGET_64BIT && TARGET_CMOVE"
13819   "#"
13820   "&& reload_completed"
13821   [(set (match_dup 2) (const_int -1))
13822    (parallel [(set (reg:CCZ FLAGS_REG)
13823                    (compare:CCZ (match_dup 1) (const_int 0)))
13824               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13825    (set (match_dup 0) (if_then_else:DI
13826                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13827                         (match_dup 2)
13828                         (match_dup 0)))
13829    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13830               (clobber (reg:CC FLAGS_REG))])]
13831   "")
13832
13833 (define_insn "*ffsdi_1"
13834   [(set (reg:CCZ FLAGS_REG)
13835         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13836                      (const_int 0)))
13837    (set (match_operand:DI 0 "register_operand" "=r")
13838         (ctz:DI (match_dup 1)))]
13839   "TARGET_64BIT"
13840   "bsf{q}\t{%1, %0|%0, %1}"
13841   [(set_attr "prefix_0f" "1")])
13842
13843 (define_insn "ctzsi2"
13844   [(set (match_operand:SI 0 "register_operand" "=r")
13845         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13846    (clobber (reg:CC FLAGS_REG))]
13847   ""
13848   "bsf{l}\t{%1, %0|%0, %1}"
13849   [(set_attr "prefix_0f" "1")])
13850
13851 (define_insn "ctzdi2"
13852   [(set (match_operand:DI 0 "register_operand" "=r")
13853         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13854    (clobber (reg:CC FLAGS_REG))]
13855   "TARGET_64BIT"
13856   "bsf{q}\t{%1, %0|%0, %1}"
13857   [(set_attr "prefix_0f" "1")])
13858
13859 (define_expand "clzsi2"
13860   [(parallel
13861      [(set (match_operand:SI 0 "register_operand" "")
13862            (minus:SI (const_int 31)
13863                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13864       (clobber (reg:CC FLAGS_REG))])
13865    (parallel
13866      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13867       (clobber (reg:CC FLAGS_REG))])]
13868   ""
13869   "")
13870
13871 (define_insn "*bsr"
13872   [(set (match_operand:SI 0 "register_operand" "=r")
13873         (minus:SI (const_int 31)
13874                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13875    (clobber (reg:CC FLAGS_REG))]
13876   ""
13877   "bsr{l}\t{%1, %0|%0, %1}"
13878   [(set_attr "prefix_0f" "1")])
13879
13880 (define_expand "clzdi2"
13881   [(parallel
13882      [(set (match_operand:DI 0 "register_operand" "")
13883            (minus:DI (const_int 63)
13884                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13885       (clobber (reg:CC FLAGS_REG))])
13886    (parallel
13887      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13888       (clobber (reg:CC FLAGS_REG))])]
13889   "TARGET_64BIT"
13890   "")
13891
13892 (define_insn "*bsr_rex64"
13893   [(set (match_operand:DI 0 "register_operand" "=r")
13894         (minus:DI (const_int 63)
13895                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13896    (clobber (reg:CC FLAGS_REG))]
13897   "TARGET_64BIT"
13898   "bsr{q}\t{%1, %0|%0, %1}"
13899   [(set_attr "prefix_0f" "1")])
13900 \f
13901 ;; Thread-local storage patterns for ELF.
13902 ;;
13903 ;; Note that these code sequences must appear exactly as shown
13904 ;; in order to allow linker relaxation.
13905
13906 (define_insn "*tls_global_dynamic_32_gnu"
13907   [(set (match_operand:SI 0 "register_operand" "=a")
13908         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13909                     (match_operand:SI 2 "tls_symbolic_operand" "")
13910                     (match_operand:SI 3 "call_insn_operand" "")]
13911                     UNSPEC_TLS_GD))
13912    (clobber (match_scratch:SI 4 "=d"))
13913    (clobber (match_scratch:SI 5 "=c"))
13914    (clobber (reg:CC FLAGS_REG))]
13915   "!TARGET_64BIT && TARGET_GNU_TLS"
13916   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13917   [(set_attr "type" "multi")
13918    (set_attr "length" "12")])
13919
13920 (define_insn "*tls_global_dynamic_32_sun"
13921   [(set (match_operand:SI 0 "register_operand" "=a")
13922         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13923                     (match_operand:SI 2 "tls_symbolic_operand" "")
13924                     (match_operand:SI 3 "call_insn_operand" "")]
13925                     UNSPEC_TLS_GD))
13926    (clobber (match_scratch:SI 4 "=d"))
13927    (clobber (match_scratch:SI 5 "=c"))
13928    (clobber (reg:CC FLAGS_REG))]
13929   "!TARGET_64BIT && TARGET_SUN_TLS"
13930   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13931         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13932   [(set_attr "type" "multi")
13933    (set_attr "length" "14")])
13934
13935 (define_expand "tls_global_dynamic_32"
13936   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13937                    (unspec:SI
13938                     [(match_dup 2)
13939                      (match_operand:SI 1 "tls_symbolic_operand" "")
13940                      (match_dup 3)]
13941                     UNSPEC_TLS_GD))
13942               (clobber (match_scratch:SI 4 ""))
13943               (clobber (match_scratch:SI 5 ""))
13944               (clobber (reg:CC FLAGS_REG))])]
13945   ""
13946 {
13947   if (flag_pic)
13948     operands[2] = pic_offset_table_rtx;
13949   else
13950     {
13951       operands[2] = gen_reg_rtx (Pmode);
13952       emit_insn (gen_set_got (operands[2]));
13953     }
13954   operands[3] = ix86_tls_get_addr ();
13955 })
13956
13957 (define_insn "*tls_global_dynamic_64"
13958   [(set (match_operand:DI 0 "register_operand" "=a")
13959         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13960                       (match_operand:DI 3 "" "")))
13961    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13962               UNSPEC_TLS_GD)]
13963   "TARGET_64BIT"
13964   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13965   [(set_attr "type" "multi")
13966    (set_attr "length" "16")])
13967
13968 (define_expand "tls_global_dynamic_64"
13969   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13970                    (call (mem:QI (match_dup 2)) (const_int 0)))
13971               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13972                          UNSPEC_TLS_GD)])]
13973   ""
13974 {
13975   operands[2] = ix86_tls_get_addr ();
13976 })
13977
13978 (define_insn "*tls_local_dynamic_base_32_gnu"
13979   [(set (match_operand:SI 0 "register_operand" "=a")
13980         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13981                     (match_operand:SI 2 "call_insn_operand" "")]
13982                    UNSPEC_TLS_LD_BASE))
13983    (clobber (match_scratch:SI 3 "=d"))
13984    (clobber (match_scratch:SI 4 "=c"))
13985    (clobber (reg:CC FLAGS_REG))]
13986   "!TARGET_64BIT && TARGET_GNU_TLS"
13987   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13988   [(set_attr "type" "multi")
13989    (set_attr "length" "11")])
13990
13991 (define_insn "*tls_local_dynamic_base_32_sun"
13992   [(set (match_operand:SI 0 "register_operand" "=a")
13993         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13994                     (match_operand:SI 2 "call_insn_operand" "")]
13995                    UNSPEC_TLS_LD_BASE))
13996    (clobber (match_scratch:SI 3 "=d"))
13997    (clobber (match_scratch:SI 4 "=c"))
13998    (clobber (reg:CC FLAGS_REG))]
13999   "!TARGET_64BIT && TARGET_SUN_TLS"
14000   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14001         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14002   [(set_attr "type" "multi")
14003    (set_attr "length" "13")])
14004
14005 (define_expand "tls_local_dynamic_base_32"
14006   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14007                    (unspec:SI [(match_dup 1) (match_dup 2)]
14008                               UNSPEC_TLS_LD_BASE))
14009               (clobber (match_scratch:SI 3 ""))
14010               (clobber (match_scratch:SI 4 ""))
14011               (clobber (reg:CC FLAGS_REG))])]
14012   ""
14013 {
14014   if (flag_pic)
14015     operands[1] = pic_offset_table_rtx;
14016   else
14017     {
14018       operands[1] = gen_reg_rtx (Pmode);
14019       emit_insn (gen_set_got (operands[1]));
14020     }
14021   operands[2] = ix86_tls_get_addr ();
14022 })
14023
14024 (define_insn "*tls_local_dynamic_base_64"
14025   [(set (match_operand:DI 0 "register_operand" "=a")
14026         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14027                       (match_operand:DI 2 "" "")))
14028    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14029   "TARGET_64BIT"
14030   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14031   [(set_attr "type" "multi")
14032    (set_attr "length" "12")])
14033
14034 (define_expand "tls_local_dynamic_base_64"
14035   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14036                    (call (mem:QI (match_dup 1)) (const_int 0)))
14037               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14038   ""
14039 {
14040   operands[1] = ix86_tls_get_addr ();
14041 })
14042
14043 ;; Local dynamic of a single variable is a lose.  Show combine how
14044 ;; to convert that back to global dynamic.
14045
14046 (define_insn_and_split "*tls_local_dynamic_32_once"
14047   [(set (match_operand:SI 0 "register_operand" "=a")
14048         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14049                              (match_operand:SI 2 "call_insn_operand" "")]
14050                             UNSPEC_TLS_LD_BASE)
14051                  (const:SI (unspec:SI
14052                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14053                             UNSPEC_DTPOFF))))
14054    (clobber (match_scratch:SI 4 "=d"))
14055    (clobber (match_scratch:SI 5 "=c"))
14056    (clobber (reg:CC FLAGS_REG))]
14057   ""
14058   "#"
14059   ""
14060   [(parallel [(set (match_dup 0)
14061                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14062                               UNSPEC_TLS_GD))
14063               (clobber (match_dup 4))
14064               (clobber (match_dup 5))
14065               (clobber (reg:CC FLAGS_REG))])]
14066   "")
14067
14068 ;; Load and add the thread base pointer from %gs:0.
14069
14070 (define_insn "*load_tp_si"
14071   [(set (match_operand:SI 0 "register_operand" "=r")
14072         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14073   "!TARGET_64BIT"
14074   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14075   [(set_attr "type" "imov")
14076    (set_attr "modrm" "0")
14077    (set_attr "length" "7")
14078    (set_attr "memory" "load")
14079    (set_attr "imm_disp" "false")])
14080
14081 (define_insn "*add_tp_si"
14082   [(set (match_operand:SI 0 "register_operand" "=r")
14083         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14084                  (match_operand:SI 1 "register_operand" "0")))
14085    (clobber (reg:CC FLAGS_REG))]
14086   "!TARGET_64BIT"
14087   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14088   [(set_attr "type" "alu")
14089    (set_attr "modrm" "0")
14090    (set_attr "length" "7")
14091    (set_attr "memory" "load")
14092    (set_attr "imm_disp" "false")])
14093
14094 (define_insn "*load_tp_di"
14095   [(set (match_operand:DI 0 "register_operand" "=r")
14096         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14097   "TARGET_64BIT"
14098   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14099   [(set_attr "type" "imov")
14100    (set_attr "modrm" "0")
14101    (set_attr "length" "7")
14102    (set_attr "memory" "load")
14103    (set_attr "imm_disp" "false")])
14104
14105 (define_insn "*add_tp_di"
14106   [(set (match_operand:DI 0 "register_operand" "=r")
14107         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14108                  (match_operand:DI 1 "register_operand" "0")))
14109    (clobber (reg:CC FLAGS_REG))]
14110   "TARGET_64BIT"
14111   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14112   [(set_attr "type" "alu")
14113    (set_attr "modrm" "0")
14114    (set_attr "length" "7")
14115    (set_attr "memory" "load")
14116    (set_attr "imm_disp" "false")])
14117 \f
14118 ;; These patterns match the binary 387 instructions for addM3, subM3,
14119 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14120 ;; SFmode.  The first is the normal insn, the second the same insn but
14121 ;; with one operand a conversion, and the third the same insn but with
14122 ;; the other operand a conversion.  The conversion may be SFmode or
14123 ;; SImode if the target mode DFmode, but only SImode if the target mode
14124 ;; is SFmode.
14125
14126 ;; Gcc is slightly more smart about handling normal two address instructions
14127 ;; so use special patterns for add and mull.
14128
14129 (define_insn "*fop_sf_comm_mixed"
14130   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14131         (match_operator:SF 3 "binary_fp_operator"
14132                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14133                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14134   "TARGET_MIX_SSE_I387
14135    && COMMUTATIVE_ARITH_P (operands[3])
14136    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14137   "* return output_387_binary_op (insn, operands);"
14138   [(set (attr "type") 
14139         (if_then_else (eq_attr "alternative" "1")
14140            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14141               (const_string "ssemul")
14142               (const_string "sseadd"))
14143            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14144               (const_string "fmul")
14145               (const_string "fop"))))
14146    (set_attr "mode" "SF")])
14147
14148 (define_insn "*fop_sf_comm_sse"
14149   [(set (match_operand:SF 0 "register_operand" "=x")
14150         (match_operator:SF 3 "binary_fp_operator"
14151                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14152                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14153   "TARGET_SSE_MATH
14154    && COMMUTATIVE_ARITH_P (operands[3])
14155    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14156   "* return output_387_binary_op (insn, operands);"
14157   [(set (attr "type") 
14158         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14159            (const_string "ssemul")
14160            (const_string "sseadd")))
14161    (set_attr "mode" "SF")])
14162
14163 (define_insn "*fop_sf_comm_i387"
14164   [(set (match_operand:SF 0 "register_operand" "=f")
14165         (match_operator:SF 3 "binary_fp_operator"
14166                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14167                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14168   "TARGET_80387
14169    && COMMUTATIVE_ARITH_P (operands[3])
14170    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14171   "* return output_387_binary_op (insn, operands);"
14172   [(set (attr "type") 
14173         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14174            (const_string "fmul")
14175            (const_string "fop")))
14176    (set_attr "mode" "SF")])
14177
14178 (define_insn "*fop_sf_1_mixed"
14179   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14180         (match_operator:SF 3 "binary_fp_operator"
14181                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14182                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14183   "TARGET_MIX_SSE_I387
14184    && !COMMUTATIVE_ARITH_P (operands[3])
14185    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14186   "* return output_387_binary_op (insn, operands);"
14187   [(set (attr "type") 
14188         (cond [(and (eq_attr "alternative" "2")
14189                     (match_operand:SF 3 "mult_operator" ""))
14190                  (const_string "ssemul")
14191                (and (eq_attr "alternative" "2")
14192                     (match_operand:SF 3 "div_operator" ""))
14193                  (const_string "ssediv")
14194                (eq_attr "alternative" "2")
14195                  (const_string "sseadd")
14196                (match_operand:SF 3 "mult_operator" "") 
14197                  (const_string "fmul")
14198                (match_operand:SF 3 "div_operator" "") 
14199                  (const_string "fdiv")
14200               ]
14201               (const_string "fop")))
14202    (set_attr "mode" "SF")])
14203
14204 (define_insn "*fop_sf_1_sse"
14205   [(set (match_operand:SF 0 "register_operand" "=x")
14206         (match_operator:SF 3 "binary_fp_operator"
14207                         [(match_operand:SF 1 "register_operand" "0")
14208                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14209   "TARGET_SSE_MATH
14210    && !COMMUTATIVE_ARITH_P (operands[3])"
14211   "* return output_387_binary_op (insn, operands);"
14212   [(set (attr "type") 
14213         (cond [(match_operand:SF 3 "mult_operator" "")
14214                  (const_string "ssemul")
14215                (match_operand:SF 3 "div_operator" "")
14216                  (const_string "ssediv")
14217               ]
14218               (const_string "sseadd")))
14219    (set_attr "mode" "SF")])
14220
14221 (define_insn "*fop_sf_1_i387"
14222   [(set (match_operand:SF 0 "register_operand" "=f,f")
14223         (match_operator:SF 3 "binary_fp_operator"
14224                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14225                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14226   "TARGET_80387
14227    && !COMMUTATIVE_ARITH_P (operands[3])
14228    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14229   "* return output_387_binary_op (insn, operands);"
14230   [(set (attr "type") 
14231         (cond [(match_operand:SF 3 "mult_operator" "") 
14232                  (const_string "fmul")
14233                (match_operand:SF 3 "div_operator" "") 
14234                  (const_string "fdiv")
14235               ]
14236               (const_string "fop")))
14237    (set_attr "mode" "SF")])
14238
14239
14240 ;; ??? Add SSE splitters for these!
14241 (define_insn "*fop_sf_2_i387"
14242   [(set (match_operand:SF 0 "register_operand" "=f,f")
14243         (match_operator:SF 3 "binary_fp_operator"
14244           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14245            (match_operand:SF 2 "register_operand" "0,0")]))]
14246   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14247   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14248   [(set (attr "type") 
14249         (cond [(match_operand:SF 3 "mult_operator" "") 
14250                  (const_string "fmul")
14251                (match_operand:SF 3 "div_operator" "") 
14252                  (const_string "fdiv")
14253               ]
14254               (const_string "fop")))
14255    (set_attr "fp_int_src" "true")
14256    (set_attr "mode" "SI")])
14257
14258 (define_insn "*fop_sf_3_i387"
14259   [(set (match_operand:SF 0 "register_operand" "=f,f")
14260         (match_operator:SF 3 "binary_fp_operator"
14261           [(match_operand:SF 1 "register_operand" "0,0")
14262            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14263   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14264   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14265   [(set (attr "type") 
14266         (cond [(match_operand:SF 3 "mult_operator" "") 
14267                  (const_string "fmul")
14268                (match_operand:SF 3 "div_operator" "") 
14269                  (const_string "fdiv")
14270               ]
14271               (const_string "fop")))
14272    (set_attr "fp_int_src" "true")
14273    (set_attr "mode" "SI")])
14274
14275 (define_insn "*fop_df_comm_mixed"
14276   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14277         (match_operator:DF 3 "binary_fp_operator"
14278                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14279                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14280   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14281    && COMMUTATIVE_ARITH_P (operands[3])
14282    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14283   "* return output_387_binary_op (insn, operands);"
14284   [(set (attr "type") 
14285         (if_then_else (eq_attr "alternative" "1")
14286            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14287               (const_string "ssemul")
14288               (const_string "sseadd"))
14289            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14290               (const_string "fmul")
14291               (const_string "fop"))))
14292    (set_attr "mode" "DF")])
14293
14294 (define_insn "*fop_df_comm_sse"
14295   [(set (match_operand:DF 0 "register_operand" "=Y")
14296         (match_operator:DF 3 "binary_fp_operator"
14297                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14298                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14299   "TARGET_SSE2 && TARGET_SSE_MATH
14300    && COMMUTATIVE_ARITH_P (operands[3])
14301    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14302   "* return output_387_binary_op (insn, operands);"
14303   [(set (attr "type") 
14304         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14305            (const_string "ssemul")
14306            (const_string "sseadd")))
14307    (set_attr "mode" "DF")])
14308
14309 (define_insn "*fop_df_comm_i387"
14310   [(set (match_operand:DF 0 "register_operand" "=f")
14311         (match_operator:DF 3 "binary_fp_operator"
14312                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14313                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14314   "TARGET_80387
14315    && COMMUTATIVE_ARITH_P (operands[3])
14316    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14317   "* return output_387_binary_op (insn, operands);"
14318   [(set (attr "type") 
14319         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14320            (const_string "fmul")
14321            (const_string "fop")))
14322    (set_attr "mode" "DF")])
14323
14324 (define_insn "*fop_df_1_mixed"
14325   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14326         (match_operator:DF 3 "binary_fp_operator"
14327                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14328                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14329   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14330    && !COMMUTATIVE_ARITH_P (operands[3])
14331    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14332   "* return output_387_binary_op (insn, operands);"
14333   [(set (attr "type") 
14334         (cond [(and (eq_attr "alternative" "2")
14335                     (match_operand:SF 3 "mult_operator" ""))
14336                  (const_string "ssemul")
14337                (and (eq_attr "alternative" "2")
14338                     (match_operand:SF 3 "div_operator" ""))
14339                  (const_string "ssediv")
14340                (eq_attr "alternative" "2")
14341                  (const_string "sseadd")
14342                (match_operand:DF 3 "mult_operator" "") 
14343                  (const_string "fmul")
14344                (match_operand:DF 3 "div_operator" "") 
14345                  (const_string "fdiv")
14346               ]
14347               (const_string "fop")))
14348    (set_attr "mode" "DF")])
14349
14350 (define_insn "*fop_df_1_sse"
14351   [(set (match_operand:DF 0 "register_operand" "=Y")
14352         (match_operator:DF 3 "binary_fp_operator"
14353                         [(match_operand:DF 1 "register_operand" "0")
14354                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14355   "TARGET_SSE2 && TARGET_SSE_MATH
14356    && !COMMUTATIVE_ARITH_P (operands[3])"
14357   "* return output_387_binary_op (insn, operands);"
14358   [(set_attr "mode" "DF")
14359    (set (attr "type") 
14360         (cond [(match_operand:SF 3 "mult_operator" "")
14361                  (const_string "ssemul")
14362                (match_operand:SF 3 "div_operator" "")
14363                  (const_string "ssediv")
14364               ]
14365               (const_string "sseadd")))])
14366
14367 (define_insn "*fop_df_1_i387"
14368   [(set (match_operand:DF 0 "register_operand" "=f,f")
14369         (match_operator:DF 3 "binary_fp_operator"
14370                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14371                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14372   "TARGET_80387
14373    && !COMMUTATIVE_ARITH_P (operands[3])
14374    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14375   "* return output_387_binary_op (insn, operands);"
14376   [(set (attr "type") 
14377         (cond [(match_operand:DF 3 "mult_operator" "") 
14378                  (const_string "fmul")
14379                (match_operand:DF 3 "div_operator" "")
14380                  (const_string "fdiv")
14381               ]
14382               (const_string "fop")))
14383    (set_attr "mode" "DF")])
14384
14385 ;; ??? Add SSE splitters for these!
14386 (define_insn "*fop_df_2_i387"
14387   [(set (match_operand:DF 0 "register_operand" "=f,f")
14388         (match_operator:DF 3 "binary_fp_operator"
14389            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14390             (match_operand:DF 2 "register_operand" "0,0")]))]
14391   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14392   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14393   [(set (attr "type") 
14394         (cond [(match_operand:DF 3 "mult_operator" "") 
14395                  (const_string "fmul")
14396                (match_operand:DF 3 "div_operator" "") 
14397                  (const_string "fdiv")
14398               ]
14399               (const_string "fop")))
14400    (set_attr "fp_int_src" "true")
14401    (set_attr "mode" "SI")])
14402
14403 (define_insn "*fop_df_3_i387"
14404   [(set (match_operand:DF 0 "register_operand" "=f,f")
14405         (match_operator:DF 3 "binary_fp_operator"
14406            [(match_operand:DF 1 "register_operand" "0,0")
14407             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14408   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14409   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14410   [(set (attr "type") 
14411         (cond [(match_operand:DF 3 "mult_operator" "") 
14412                  (const_string "fmul")
14413                (match_operand:DF 3 "div_operator" "") 
14414                  (const_string "fdiv")
14415               ]
14416               (const_string "fop")))
14417    (set_attr "fp_int_src" "true")
14418    (set_attr "mode" "SI")])
14419
14420 (define_insn "*fop_df_4_i387"
14421   [(set (match_operand:DF 0 "register_operand" "=f,f")
14422         (match_operator:DF 3 "binary_fp_operator"
14423            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14424             (match_operand:DF 2 "register_operand" "0,f")]))]
14425   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14426    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14427   "* return output_387_binary_op (insn, operands);"
14428   [(set (attr "type") 
14429         (cond [(match_operand:DF 3 "mult_operator" "") 
14430                  (const_string "fmul")
14431                (match_operand:DF 3 "div_operator" "") 
14432                  (const_string "fdiv")
14433               ]
14434               (const_string "fop")))
14435    (set_attr "mode" "SF")])
14436
14437 (define_insn "*fop_df_5_i387"
14438   [(set (match_operand:DF 0 "register_operand" "=f,f")
14439         (match_operator:DF 3 "binary_fp_operator"
14440           [(match_operand:DF 1 "register_operand" "0,f")
14441            (float_extend:DF
14442             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14443   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14444   "* return output_387_binary_op (insn, operands);"
14445   [(set (attr "type") 
14446         (cond [(match_operand:DF 3 "mult_operator" "") 
14447                  (const_string "fmul")
14448                (match_operand:DF 3 "div_operator" "") 
14449                  (const_string "fdiv")
14450               ]
14451               (const_string "fop")))
14452    (set_attr "mode" "SF")])
14453
14454 (define_insn "*fop_df_6_i387"
14455   [(set (match_operand:DF 0 "register_operand" "=f,f")
14456         (match_operator:DF 3 "binary_fp_operator"
14457           [(float_extend:DF
14458             (match_operand:SF 1 "register_operand" "0,f"))
14459            (float_extend:DF
14460             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14461   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14462   "* return output_387_binary_op (insn, operands);"
14463   [(set (attr "type") 
14464         (cond [(match_operand:DF 3 "mult_operator" "") 
14465                  (const_string "fmul")
14466                (match_operand:DF 3 "div_operator" "") 
14467                  (const_string "fdiv")
14468               ]
14469               (const_string "fop")))
14470    (set_attr "mode" "SF")])
14471
14472 (define_insn "*fop_xf_comm_i387"
14473   [(set (match_operand:XF 0 "register_operand" "=f")
14474         (match_operator:XF 3 "binary_fp_operator"
14475                         [(match_operand:XF 1 "register_operand" "%0")
14476                          (match_operand:XF 2 "register_operand" "f")]))]
14477   "TARGET_80387
14478    && COMMUTATIVE_ARITH_P (operands[3])"
14479   "* return output_387_binary_op (insn, operands);"
14480   [(set (attr "type") 
14481         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14482            (const_string "fmul")
14483            (const_string "fop")))
14484    (set_attr "mode" "XF")])
14485
14486 (define_insn "*fop_xf_1_i387"
14487   [(set (match_operand:XF 0 "register_operand" "=f,f")
14488         (match_operator:XF 3 "binary_fp_operator"
14489                         [(match_operand:XF 1 "register_operand" "0,f")
14490                          (match_operand:XF 2 "register_operand" "f,0")]))]
14491   "TARGET_80387
14492    && !COMMUTATIVE_ARITH_P (operands[3])"
14493   "* return output_387_binary_op (insn, operands);"
14494   [(set (attr "type") 
14495         (cond [(match_operand:XF 3 "mult_operator" "") 
14496                  (const_string "fmul")
14497                (match_operand:XF 3 "div_operator" "") 
14498                  (const_string "fdiv")
14499               ]
14500               (const_string "fop")))
14501    (set_attr "mode" "XF")])
14502
14503 (define_insn "*fop_xf_2_i387"
14504   [(set (match_operand:XF 0 "register_operand" "=f,f")
14505         (match_operator:XF 3 "binary_fp_operator"
14506            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14507             (match_operand:XF 2 "register_operand" "0,0")]))]
14508   "TARGET_80387 && TARGET_USE_FIOP"
14509   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14510   [(set (attr "type") 
14511         (cond [(match_operand:XF 3 "mult_operator" "") 
14512                  (const_string "fmul")
14513                (match_operand:XF 3 "div_operator" "") 
14514                  (const_string "fdiv")
14515               ]
14516               (const_string "fop")))
14517    (set_attr "fp_int_src" "true")
14518    (set_attr "mode" "SI")])
14519
14520 (define_insn "*fop_xf_3_i387"
14521   [(set (match_operand:XF 0 "register_operand" "=f,f")
14522         (match_operator:XF 3 "binary_fp_operator"
14523           [(match_operand:XF 1 "register_operand" "0,0")
14524            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14525   "TARGET_80387 && TARGET_USE_FIOP"
14526   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14527   [(set (attr "type") 
14528         (cond [(match_operand:XF 3 "mult_operator" "") 
14529                  (const_string "fmul")
14530                (match_operand:XF 3 "div_operator" "") 
14531                  (const_string "fdiv")
14532               ]
14533               (const_string "fop")))
14534    (set_attr "fp_int_src" "true")
14535    (set_attr "mode" "SI")])
14536
14537 (define_insn "*fop_xf_4_i387"
14538   [(set (match_operand:XF 0 "register_operand" "=f,f")
14539         (match_operator:XF 3 "binary_fp_operator"
14540            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14541             (match_operand:XF 2 "register_operand" "0,f")]))]
14542   "TARGET_80387"
14543   "* return output_387_binary_op (insn, operands);"
14544   [(set (attr "type") 
14545         (cond [(match_operand:XF 3 "mult_operator" "") 
14546                  (const_string "fmul")
14547                (match_operand:XF 3 "div_operator" "") 
14548                  (const_string "fdiv")
14549               ]
14550               (const_string "fop")))
14551    (set_attr "mode" "SF")])
14552
14553 (define_insn "*fop_xf_5_i387"
14554   [(set (match_operand:XF 0 "register_operand" "=f,f")
14555         (match_operator:XF 3 "binary_fp_operator"
14556           [(match_operand:XF 1 "register_operand" "0,f")
14557            (float_extend:XF
14558             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14559   "TARGET_80387"
14560   "* return output_387_binary_op (insn, operands);"
14561   [(set (attr "type") 
14562         (cond [(match_operand:XF 3 "mult_operator" "") 
14563                  (const_string "fmul")
14564                (match_operand:XF 3 "div_operator" "") 
14565                  (const_string "fdiv")
14566               ]
14567               (const_string "fop")))
14568    (set_attr "mode" "SF")])
14569
14570 (define_insn "*fop_xf_6_i387"
14571   [(set (match_operand:XF 0 "register_operand" "=f,f")
14572         (match_operator:XF 3 "binary_fp_operator"
14573           [(float_extend:XF
14574             (match_operand 1 "register_operand" "0,f"))
14575            (float_extend:XF
14576             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14577   "TARGET_80387"
14578   "* return output_387_binary_op (insn, operands);"
14579   [(set (attr "type") 
14580         (cond [(match_operand:XF 3 "mult_operator" "") 
14581                  (const_string "fmul")
14582                (match_operand:XF 3 "div_operator" "") 
14583                  (const_string "fdiv")
14584               ]
14585               (const_string "fop")))
14586    (set_attr "mode" "SF")])
14587
14588 (define_split
14589   [(set (match_operand 0 "register_operand" "")
14590         (match_operator 3 "binary_fp_operator"
14591            [(float (match_operand:SI 1 "register_operand" ""))
14592             (match_operand 2 "register_operand" "")]))]
14593   "TARGET_80387 && reload_completed
14594    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14595   [(const_int 0)]
14596
14597   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14598   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14599   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14600                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14601                                           GET_MODE (operands[3]),
14602                                           operands[4],
14603                                           operands[2])));
14604   ix86_free_from_memory (GET_MODE (operands[1]));
14605   DONE;
14606 })
14607
14608 (define_split
14609   [(set (match_operand 0 "register_operand" "")
14610         (match_operator 3 "binary_fp_operator"
14611            [(match_operand 1 "register_operand" "")
14612             (float (match_operand:SI 2 "register_operand" ""))]))]
14613   "TARGET_80387 && reload_completed
14614    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14615   [(const_int 0)]
14616 {
14617   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14618   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14619   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14620                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14621                                           GET_MODE (operands[3]),
14622                                           operands[1],
14623                                           operands[4])));
14624   ix86_free_from_memory (GET_MODE (operands[2]));
14625   DONE;
14626 })
14627 \f
14628 ;; FPU special functions.
14629
14630 (define_expand "sqrtsf2"
14631   [(set (match_operand:SF 0 "register_operand" "")
14632         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14633   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14634 {
14635   if (!TARGET_SSE_MATH)
14636     operands[1] = force_reg (SFmode, operands[1]);
14637 })
14638
14639 (define_insn "*sqrtsf2_mixed"
14640   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14641         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14642   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14643   "@
14644    fsqrt
14645    sqrtss\t{%1, %0|%0, %1}"
14646   [(set_attr "type" "fpspc,sse")
14647    (set_attr "mode" "SF,SF")
14648    (set_attr "athlon_decode" "direct,*")])
14649
14650 (define_insn "*sqrtsf2_sse"
14651   [(set (match_operand:SF 0 "register_operand" "=x")
14652         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14653   "TARGET_SSE_MATH"
14654   "sqrtss\t{%1, %0|%0, %1}"
14655   [(set_attr "type" "sse")
14656    (set_attr "mode" "SF")
14657    (set_attr "athlon_decode" "*")])
14658
14659 (define_insn "*sqrtsf2_i387"
14660   [(set (match_operand:SF 0 "register_operand" "=f")
14661         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14662   "TARGET_USE_FANCY_MATH_387"
14663   "fsqrt"
14664   [(set_attr "type" "fpspc")
14665    (set_attr "mode" "SF")
14666    (set_attr "athlon_decode" "direct")])
14667
14668 (define_expand "sqrtdf2"
14669   [(set (match_operand:DF 0 "register_operand" "")
14670         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14671   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14672 {
14673   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14674     operands[1] = force_reg (DFmode, operands[1]);
14675 })
14676
14677 (define_insn "*sqrtdf2_mixed"
14678   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14679         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14680   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14681   "@
14682    fsqrt
14683    sqrtsd\t{%1, %0|%0, %1}"
14684   [(set_attr "type" "fpspc,sse")
14685    (set_attr "mode" "DF,DF")
14686    (set_attr "athlon_decode" "direct,*")])
14687
14688 (define_insn "*sqrtdf2_sse"
14689   [(set (match_operand:DF 0 "register_operand" "=Y")
14690         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14691   "TARGET_SSE2 && TARGET_SSE_MATH"
14692   "sqrtsd\t{%1, %0|%0, %1}"
14693   [(set_attr "type" "sse")
14694    (set_attr "mode" "DF")
14695    (set_attr "athlon_decode" "*")])
14696
14697 (define_insn "*sqrtdf2_i387"
14698   [(set (match_operand:DF 0 "register_operand" "=f")
14699         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14700   "TARGET_USE_FANCY_MATH_387"
14701   "fsqrt"
14702   [(set_attr "type" "fpspc")
14703    (set_attr "mode" "DF")
14704    (set_attr "athlon_decode" "direct")])
14705
14706 (define_insn "*sqrtextendsfdf2_i387"
14707   [(set (match_operand:DF 0 "register_operand" "=f")
14708         (sqrt:DF (float_extend:DF
14709                   (match_operand:SF 1 "register_operand" "0"))))]
14710   "TARGET_USE_FANCY_MATH_387
14711    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14712   "fsqrt"
14713   [(set_attr "type" "fpspc")
14714    (set_attr "mode" "DF")
14715    (set_attr "athlon_decode" "direct")])
14716
14717 (define_insn "sqrtxf2"
14718   [(set (match_operand:XF 0 "register_operand" "=f")
14719         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14720   "TARGET_USE_FANCY_MATH_387 
14721    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14722   "fsqrt"
14723   [(set_attr "type" "fpspc")
14724    (set_attr "mode" "XF")
14725    (set_attr "athlon_decode" "direct")])
14726
14727 (define_insn "*sqrtextendsfxf2_i387"
14728   [(set (match_operand:XF 0 "register_operand" "=f")
14729         (sqrt:XF (float_extend:XF
14730                   (match_operand:SF 1 "register_operand" "0"))))]
14731   "TARGET_USE_FANCY_MATH_387"
14732   "fsqrt"
14733   [(set_attr "type" "fpspc")
14734    (set_attr "mode" "XF")
14735    (set_attr "athlon_decode" "direct")])
14736
14737 (define_insn "*sqrtextenddfxf2_i387"
14738   [(set (match_operand:XF 0 "register_operand" "=f")
14739         (sqrt:XF (float_extend:XF
14740                   (match_operand:DF 1 "register_operand" "0"))))]
14741   "TARGET_USE_FANCY_MATH_387"
14742   "fsqrt"
14743   [(set_attr "type" "fpspc")
14744    (set_attr "mode" "XF")
14745    (set_attr "athlon_decode" "direct")])
14746
14747 (define_insn "fpremxf4"
14748   [(set (match_operand:XF 0 "register_operand" "=f")
14749         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14750                     (match_operand:XF 3 "register_operand" "1")]
14751                    UNSPEC_FPREM_F))
14752    (set (match_operand:XF 1 "register_operand" "=u")
14753         (unspec:XF [(match_dup 2) (match_dup 3)]
14754                    UNSPEC_FPREM_U))
14755    (set (reg:CCFP FPSR_REG)
14756         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14757   "TARGET_USE_FANCY_MATH_387
14758    && flag_unsafe_math_optimizations"
14759   "fprem"
14760   [(set_attr "type" "fpspc")
14761    (set_attr "mode" "XF")])
14762
14763 (define_expand "fmodsf3"
14764   [(use (match_operand:SF 0 "register_operand" ""))
14765    (use (match_operand:SF 1 "register_operand" ""))
14766    (use (match_operand:SF 2 "register_operand" ""))]
14767   "TARGET_USE_FANCY_MATH_387
14768    && flag_unsafe_math_optimizations"
14769 {
14770   rtx label = gen_label_rtx ();
14771
14772   rtx op1 = gen_reg_rtx (XFmode);
14773   rtx op2 = gen_reg_rtx (XFmode);
14774
14775   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14776   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14777
14778   emit_label (label);
14779
14780   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14781   ix86_emit_fp_unordered_jump (label);
14782
14783   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
14784   DONE;
14785 })
14786
14787 (define_expand "fmoddf3"
14788   [(use (match_operand:DF 0 "register_operand" ""))
14789    (use (match_operand:DF 1 "register_operand" ""))
14790    (use (match_operand:DF 2 "register_operand" ""))]
14791   "TARGET_USE_FANCY_MATH_387
14792    && flag_unsafe_math_optimizations"
14793 {
14794   rtx label = gen_label_rtx ();
14795
14796   rtx op1 = gen_reg_rtx (XFmode);
14797   rtx op2 = gen_reg_rtx (XFmode);
14798
14799   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14800   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14801
14802   emit_label (label);
14803
14804   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14805   ix86_emit_fp_unordered_jump (label);
14806
14807   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
14808   DONE;
14809 })
14810
14811 (define_expand "fmodxf3"
14812   [(use (match_operand:XF 0 "register_operand" ""))
14813    (use (match_operand:XF 1 "register_operand" ""))
14814    (use (match_operand:XF 2 "register_operand" ""))]
14815   "TARGET_USE_FANCY_MATH_387
14816    && flag_unsafe_math_optimizations"
14817 {
14818   rtx label = gen_label_rtx ();
14819
14820   emit_label (label);
14821
14822   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14823                            operands[1], operands[2]));
14824   ix86_emit_fp_unordered_jump (label);
14825
14826   emit_move_insn (operands[0], operands[1]);
14827   DONE;
14828 })
14829
14830 (define_insn "fprem1xf4"
14831   [(set (match_operand:XF 0 "register_operand" "=f")
14832         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14833                     (match_operand:XF 3 "register_operand" "1")]
14834                    UNSPEC_FPREM1_F))
14835    (set (match_operand:XF 1 "register_operand" "=u")
14836         (unspec:XF [(match_dup 2) (match_dup 3)]
14837                    UNSPEC_FPREM1_U))
14838    (set (reg:CCFP FPSR_REG)
14839         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14840   "TARGET_USE_FANCY_MATH_387
14841    && flag_unsafe_math_optimizations"
14842   "fprem1"
14843   [(set_attr "type" "fpspc")
14844    (set_attr "mode" "XF")])
14845
14846 (define_expand "dremsf3"
14847   [(use (match_operand:SF 0 "register_operand" ""))
14848    (use (match_operand:SF 1 "register_operand" ""))
14849    (use (match_operand:SF 2 "register_operand" ""))]
14850   "TARGET_USE_FANCY_MATH_387
14851    && flag_unsafe_math_optimizations"
14852 {
14853   rtx label = gen_label_rtx ();
14854
14855   rtx op1 = gen_reg_rtx (XFmode);
14856   rtx op2 = gen_reg_rtx (XFmode);
14857
14858   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14859   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14860
14861   emit_label (label);
14862
14863   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14864   ix86_emit_fp_unordered_jump (label);
14865
14866   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
14867   DONE;
14868 })
14869
14870 (define_expand "dremdf3"
14871   [(use (match_operand:DF 0 "register_operand" ""))
14872    (use (match_operand:DF 1 "register_operand" ""))
14873    (use (match_operand:DF 2 "register_operand" ""))]
14874   "TARGET_USE_FANCY_MATH_387
14875    && flag_unsafe_math_optimizations"
14876 {
14877   rtx label = gen_label_rtx ();
14878
14879   rtx op1 = gen_reg_rtx (XFmode);
14880   rtx op2 = gen_reg_rtx (XFmode);
14881
14882   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14883   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14884
14885   emit_label (label);
14886
14887   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14888   ix86_emit_fp_unordered_jump (label);
14889
14890   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
14891   DONE;
14892 })
14893
14894 (define_expand "dremxf3"
14895   [(use (match_operand:XF 0 "register_operand" ""))
14896    (use (match_operand:XF 1 "register_operand" ""))
14897    (use (match_operand:XF 2 "register_operand" ""))]
14898   "TARGET_USE_FANCY_MATH_387
14899    && flag_unsafe_math_optimizations"
14900 {
14901   rtx label = gen_label_rtx ();
14902
14903   emit_label (label);
14904
14905   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14906                             operands[1], operands[2]));
14907   ix86_emit_fp_unordered_jump (label);
14908
14909   emit_move_insn (operands[0], operands[1]);
14910   DONE;
14911 })
14912
14913 (define_insn "*sindf2"
14914   [(set (match_operand:DF 0 "register_operand" "=f")
14915         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14916   "TARGET_USE_FANCY_MATH_387
14917    && flag_unsafe_math_optimizations"
14918   "fsin"
14919   [(set_attr "type" "fpspc")
14920    (set_attr "mode" "DF")])
14921
14922 (define_insn "*sinsf2"
14923   [(set (match_operand:SF 0 "register_operand" "=f")
14924         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14925   "TARGET_USE_FANCY_MATH_387
14926    && flag_unsafe_math_optimizations"
14927   "fsin"
14928   [(set_attr "type" "fpspc")
14929    (set_attr "mode" "SF")])
14930
14931 (define_insn "*sinextendsfdf2"
14932   [(set (match_operand:DF 0 "register_operand" "=f")
14933         (unspec:DF [(float_extend:DF
14934                      (match_operand:SF 1 "register_operand" "0"))]
14935                    UNSPEC_SIN))]
14936   "TARGET_USE_FANCY_MATH_387
14937    && flag_unsafe_math_optimizations"
14938   "fsin"
14939   [(set_attr "type" "fpspc")
14940    (set_attr "mode" "DF")])
14941
14942 (define_insn "*sinxf2"
14943   [(set (match_operand:XF 0 "register_operand" "=f")
14944         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14945   "TARGET_USE_FANCY_MATH_387
14946    && flag_unsafe_math_optimizations"
14947   "fsin"
14948   [(set_attr "type" "fpspc")
14949    (set_attr "mode" "XF")])
14950
14951 (define_insn "*cosdf2"
14952   [(set (match_operand:DF 0 "register_operand" "=f")
14953         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14954   "TARGET_USE_FANCY_MATH_387
14955    && flag_unsafe_math_optimizations"
14956   "fcos"
14957   [(set_attr "type" "fpspc")
14958    (set_attr "mode" "DF")])
14959
14960 (define_insn "*cossf2"
14961   [(set (match_operand:SF 0 "register_operand" "=f")
14962         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14963   "TARGET_USE_FANCY_MATH_387
14964    && flag_unsafe_math_optimizations"
14965   "fcos"
14966   [(set_attr "type" "fpspc")
14967    (set_attr "mode" "SF")])
14968
14969 (define_insn "*cosextendsfdf2"
14970   [(set (match_operand:DF 0 "register_operand" "=f")
14971         (unspec:DF [(float_extend:DF
14972                      (match_operand:SF 1 "register_operand" "0"))]
14973                    UNSPEC_COS))]
14974   "TARGET_USE_FANCY_MATH_387
14975    && flag_unsafe_math_optimizations"
14976   "fcos"
14977   [(set_attr "type" "fpspc")
14978    (set_attr "mode" "DF")])
14979
14980 (define_insn "*cosxf2"
14981   [(set (match_operand:XF 0 "register_operand" "=f")
14982         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14983   "TARGET_USE_FANCY_MATH_387
14984    && flag_unsafe_math_optimizations"
14985   "fcos"
14986   [(set_attr "type" "fpspc")
14987    (set_attr "mode" "XF")])
14988
14989 ;; With sincos pattern defined, sin and cos builtin function will be
14990 ;; expanded to sincos pattern with one of its outputs left unused. 
14991 ;; Cse pass  will detected, if two sincos patterns can be combined,
14992 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14993 ;; depending on the unused output.
14994
14995 (define_insn "sincosdf3"
14996   [(set (match_operand:DF 0 "register_operand" "=f")
14997         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14998                    UNSPEC_SINCOS_COS))
14999    (set (match_operand:DF 1 "register_operand" "=u")
15000         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15001   "TARGET_USE_FANCY_MATH_387
15002    && flag_unsafe_math_optimizations"
15003   "fsincos"
15004   [(set_attr "type" "fpspc")
15005    (set_attr "mode" "DF")])
15006
15007 (define_split
15008   [(set (match_operand:DF 0 "register_operand" "")
15009         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15010                    UNSPEC_SINCOS_COS))
15011    (set (match_operand:DF 1 "register_operand" "")
15012         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15013   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15014    && !reload_completed && !reload_in_progress"
15015   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15016   "")
15017
15018 (define_split
15019   [(set (match_operand:DF 0 "register_operand" "")
15020         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15021                    UNSPEC_SINCOS_COS))
15022    (set (match_operand:DF 1 "register_operand" "")
15023         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15024   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15025    && !reload_completed && !reload_in_progress"
15026   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15027   "")
15028
15029 (define_insn "sincossf3"
15030   [(set (match_operand:SF 0 "register_operand" "=f")
15031         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15032                    UNSPEC_SINCOS_COS))
15033    (set (match_operand:SF 1 "register_operand" "=u")
15034         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15035   "TARGET_USE_FANCY_MATH_387
15036    && flag_unsafe_math_optimizations"
15037   "fsincos"
15038   [(set_attr "type" "fpspc")
15039    (set_attr "mode" "SF")])
15040
15041 (define_split
15042   [(set (match_operand:SF 0 "register_operand" "")
15043         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15044                    UNSPEC_SINCOS_COS))
15045    (set (match_operand:SF 1 "register_operand" "")
15046         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15047   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15048    && !reload_completed && !reload_in_progress"
15049   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15050   "")
15051
15052 (define_split
15053   [(set (match_operand:SF 0 "register_operand" "")
15054         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15055                    UNSPEC_SINCOS_COS))
15056    (set (match_operand:SF 1 "register_operand" "")
15057         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15058   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15059    && !reload_completed && !reload_in_progress"
15060   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15061   "")
15062
15063 (define_insn "*sincosextendsfdf3"
15064   [(set (match_operand:DF 0 "register_operand" "=f")
15065         (unspec:DF [(float_extend:DF
15066                      (match_operand:SF 2 "register_operand" "0"))]
15067                    UNSPEC_SINCOS_COS))
15068    (set (match_operand:DF 1 "register_operand" "=u")
15069         (unspec:DF [(float_extend:DF
15070                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15071   "TARGET_USE_FANCY_MATH_387
15072    && flag_unsafe_math_optimizations"
15073   "fsincos"
15074   [(set_attr "type" "fpspc")
15075    (set_attr "mode" "DF")])
15076
15077 (define_split
15078   [(set (match_operand:DF 0 "register_operand" "")
15079         (unspec:DF [(float_extend:DF
15080                      (match_operand:SF 2 "register_operand" ""))]
15081                    UNSPEC_SINCOS_COS))
15082    (set (match_operand:DF 1 "register_operand" "")
15083         (unspec:DF [(float_extend:DF
15084                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15085   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15086    && !reload_completed && !reload_in_progress"
15087   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15088                                    (match_dup 2))] UNSPEC_SIN))]
15089   "")
15090
15091 (define_split
15092   [(set (match_operand:DF 0 "register_operand" "")
15093         (unspec:DF [(float_extend:DF
15094                      (match_operand:SF 2 "register_operand" ""))]
15095                    UNSPEC_SINCOS_COS))
15096    (set (match_operand:DF 1 "register_operand" "")
15097         (unspec:DF [(float_extend:DF
15098                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15099   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15100    && !reload_completed && !reload_in_progress"
15101   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15102                                    (match_dup 2))] UNSPEC_COS))]
15103   "")
15104
15105 (define_insn "sincosxf3"
15106   [(set (match_operand:XF 0 "register_operand" "=f")
15107         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15108                    UNSPEC_SINCOS_COS))
15109    (set (match_operand:XF 1 "register_operand" "=u")
15110         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15111   "TARGET_USE_FANCY_MATH_387
15112    && flag_unsafe_math_optimizations"
15113   "fsincos"
15114   [(set_attr "type" "fpspc")
15115    (set_attr "mode" "XF")])
15116
15117 (define_split
15118   [(set (match_operand:XF 0 "register_operand" "")
15119         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15120                    UNSPEC_SINCOS_COS))
15121    (set (match_operand:XF 1 "register_operand" "")
15122         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15123   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15124    && !reload_completed && !reload_in_progress"
15125   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15126   "")
15127
15128 (define_split
15129   [(set (match_operand:XF 0 "register_operand" "")
15130         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15131                    UNSPEC_SINCOS_COS))
15132    (set (match_operand:XF 1 "register_operand" "")
15133         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15134   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15135    && !reload_completed && !reload_in_progress"
15136   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15137   "")
15138
15139 (define_insn "*tandf3_1"
15140   [(set (match_operand:DF 0 "register_operand" "=f")
15141         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15142                    UNSPEC_TAN_ONE))
15143    (set (match_operand:DF 1 "register_operand" "=u")
15144         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15145   "TARGET_USE_FANCY_MATH_387
15146    && flag_unsafe_math_optimizations"
15147   "fptan"
15148   [(set_attr "type" "fpspc")
15149    (set_attr "mode" "DF")])
15150
15151 ;; optimize sequence: fptan
15152 ;;                    fstp    %st(0)
15153 ;;                    fld1
15154 ;; into fptan insn.
15155
15156 (define_peephole2
15157   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15158                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15159                              UNSPEC_TAN_ONE))
15160              (set (match_operand:DF 1 "register_operand" "")
15161                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15162    (set (match_dup 0)
15163         (match_operand:DF 3 "immediate_operand" ""))]
15164   "standard_80387_constant_p (operands[3]) == 2"
15165   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15166              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15167   "")
15168
15169 (define_expand "tandf2"
15170   [(parallel [(set (match_dup 2)
15171                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15172                               UNSPEC_TAN_ONE))
15173               (set (match_operand:DF 0 "register_operand" "")
15174                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15175   "TARGET_USE_FANCY_MATH_387
15176    && flag_unsafe_math_optimizations"
15177 {
15178   operands[2] = gen_reg_rtx (DFmode);
15179 })
15180
15181 (define_insn "*tansf3_1"
15182   [(set (match_operand:SF 0 "register_operand" "=f")
15183         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15184                    UNSPEC_TAN_ONE))
15185    (set (match_operand:SF 1 "register_operand" "=u")
15186         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15187   "TARGET_USE_FANCY_MATH_387
15188    && flag_unsafe_math_optimizations"
15189   "fptan"
15190   [(set_attr "type" "fpspc")
15191    (set_attr "mode" "SF")])
15192
15193 ;; optimize sequence: fptan
15194 ;;                    fstp    %st(0)
15195 ;;                    fld1
15196 ;; into fptan insn.
15197
15198 (define_peephole2
15199   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15200                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15201                              UNSPEC_TAN_ONE))
15202              (set (match_operand:SF 1 "register_operand" "")
15203                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15204    (set (match_dup 0)
15205         (match_operand:SF 3 "immediate_operand" ""))]
15206   "standard_80387_constant_p (operands[3]) == 2"
15207   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15208              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15209   "")
15210
15211 (define_expand "tansf2"
15212   [(parallel [(set (match_dup 2)
15213                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15214                               UNSPEC_TAN_ONE))
15215               (set (match_operand:SF 0 "register_operand" "")
15216                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15217   "TARGET_USE_FANCY_MATH_387
15218    && flag_unsafe_math_optimizations"
15219 {
15220   operands[2] = gen_reg_rtx (SFmode);
15221 })
15222
15223 (define_insn "*tanxf3_1"
15224   [(set (match_operand:XF 0 "register_operand" "=f")
15225         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15226                    UNSPEC_TAN_ONE))
15227    (set (match_operand:XF 1 "register_operand" "=u")
15228         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15229   "TARGET_USE_FANCY_MATH_387
15230    && flag_unsafe_math_optimizations"
15231   "fptan"
15232   [(set_attr "type" "fpspc")
15233    (set_attr "mode" "XF")])
15234
15235 ;; optimize sequence: fptan
15236 ;;                    fstp    %st(0)
15237 ;;                    fld1
15238 ;; into fptan insn.
15239
15240 (define_peephole2
15241   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15242                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15243                              UNSPEC_TAN_ONE))
15244              (set (match_operand:XF 1 "register_operand" "")
15245                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15246    (set (match_dup 0)
15247         (match_operand:XF 3 "immediate_operand" ""))]
15248   "standard_80387_constant_p (operands[3]) == 2"
15249   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15250              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15251   "")
15252
15253 (define_expand "tanxf2"
15254   [(parallel [(set (match_dup 2)
15255                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15256                               UNSPEC_TAN_ONE))
15257               (set (match_operand:XF 0 "register_operand" "")
15258                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15259   "TARGET_USE_FANCY_MATH_387
15260    && flag_unsafe_math_optimizations"
15261 {
15262   operands[2] = gen_reg_rtx (XFmode);
15263 })
15264
15265 (define_insn "atan2df3_1"
15266   [(set (match_operand:DF 0 "register_operand" "=f")
15267         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15268                     (match_operand:DF 1 "register_operand" "u")]
15269                    UNSPEC_FPATAN))
15270    (clobber (match_scratch:DF 3 "=1"))]
15271   "TARGET_USE_FANCY_MATH_387
15272    && flag_unsafe_math_optimizations"
15273   "fpatan"
15274   [(set_attr "type" "fpspc")
15275    (set_attr "mode" "DF")])
15276
15277 (define_expand "atan2df3"
15278   [(use (match_operand:DF 0 "register_operand" "=f"))
15279    (use (match_operand:DF 2 "register_operand" "0"))
15280    (use (match_operand:DF 1 "register_operand" "u"))]
15281   "TARGET_USE_FANCY_MATH_387
15282    && flag_unsafe_math_optimizations"
15283 {
15284   rtx copy = gen_reg_rtx (DFmode);
15285   emit_move_insn (copy, operands[1]);
15286   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15287   DONE;
15288 })
15289
15290 (define_expand "atandf2"
15291   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15292                    (unspec:DF [(match_dup 2)
15293                                (match_operand:DF 1 "register_operand" "")]
15294                     UNSPEC_FPATAN))
15295               (clobber (match_scratch:DF 3 ""))])]
15296   "TARGET_USE_FANCY_MATH_387
15297    && flag_unsafe_math_optimizations"
15298 {
15299   operands[2] = gen_reg_rtx (DFmode);
15300   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15301 })
15302
15303 (define_insn "atan2sf3_1"
15304   [(set (match_operand:SF 0 "register_operand" "=f")
15305         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15306                     (match_operand:SF 1 "register_operand" "u")]
15307                    UNSPEC_FPATAN))
15308    (clobber (match_scratch:SF 3 "=1"))]
15309   "TARGET_USE_FANCY_MATH_387
15310    && flag_unsafe_math_optimizations"
15311   "fpatan"
15312   [(set_attr "type" "fpspc")
15313    (set_attr "mode" "SF")])
15314
15315 (define_expand "atan2sf3"
15316   [(use (match_operand:SF 0 "register_operand" "=f"))
15317    (use (match_operand:SF 2 "register_operand" "0"))
15318    (use (match_operand:SF 1 "register_operand" "u"))]
15319   "TARGET_USE_FANCY_MATH_387
15320    && flag_unsafe_math_optimizations"
15321 {
15322   rtx copy = gen_reg_rtx (SFmode);
15323   emit_move_insn (copy, operands[1]);
15324   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15325   DONE;
15326 })
15327
15328 (define_expand "atansf2"
15329   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15330                    (unspec:SF [(match_dup 2)
15331                                (match_operand:SF 1 "register_operand" "")]
15332                     UNSPEC_FPATAN))
15333               (clobber (match_scratch:SF 3 ""))])]
15334   "TARGET_USE_FANCY_MATH_387
15335    && flag_unsafe_math_optimizations"
15336 {
15337   operands[2] = gen_reg_rtx (SFmode);
15338   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15339 })
15340
15341 (define_insn "atan2xf3_1"
15342   [(set (match_operand:XF 0 "register_operand" "=f")
15343         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15344                     (match_operand:XF 1 "register_operand" "u")]
15345                    UNSPEC_FPATAN))
15346    (clobber (match_scratch:XF 3 "=1"))]
15347   "TARGET_USE_FANCY_MATH_387
15348    && flag_unsafe_math_optimizations"
15349   "fpatan"
15350   [(set_attr "type" "fpspc")
15351    (set_attr "mode" "XF")])
15352
15353 (define_expand "atan2xf3"
15354   [(use (match_operand:XF 0 "register_operand" "=f"))
15355    (use (match_operand:XF 2 "register_operand" "0"))
15356    (use (match_operand:XF 1 "register_operand" "u"))]
15357   "TARGET_USE_FANCY_MATH_387
15358    && flag_unsafe_math_optimizations"
15359 {
15360   rtx copy = gen_reg_rtx (XFmode);
15361   emit_move_insn (copy, operands[1]);
15362   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15363   DONE;
15364 })
15365
15366 (define_expand "atanxf2"
15367   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15368                    (unspec:XF [(match_dup 2)
15369                                (match_operand:XF 1 "register_operand" "")]
15370                     UNSPEC_FPATAN))
15371               (clobber (match_scratch:XF 3 ""))])]
15372   "TARGET_USE_FANCY_MATH_387
15373    && flag_unsafe_math_optimizations"
15374 {
15375   operands[2] = gen_reg_rtx (XFmode);
15376   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15377 })
15378
15379 (define_expand "asindf2"
15380   [(set (match_dup 2)
15381         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15382    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15383    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15384    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15385    (parallel [(set (match_dup 7)
15386                    (unspec:XF [(match_dup 6) (match_dup 2)]
15387                               UNSPEC_FPATAN))
15388               (clobber (match_scratch:XF 8 ""))])
15389    (set (match_operand:DF 0 "register_operand" "")
15390         (float_truncate:DF (match_dup 7)))]
15391   "TARGET_USE_FANCY_MATH_387
15392    && flag_unsafe_math_optimizations"
15393 {
15394   int i;
15395
15396   for (i=2; i<8; i++)
15397     operands[i] = gen_reg_rtx (XFmode);
15398
15399   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15400 })
15401
15402 (define_expand "asinsf2"
15403   [(set (match_dup 2)
15404         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15405    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15406    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15407    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15408    (parallel [(set (match_dup 7)
15409                    (unspec:XF [(match_dup 6) (match_dup 2)]
15410                               UNSPEC_FPATAN))
15411               (clobber (match_scratch:XF 8 ""))])
15412    (set (match_operand:SF 0 "register_operand" "")
15413         (float_truncate:SF (match_dup 7)))]
15414   "TARGET_USE_FANCY_MATH_387
15415    && flag_unsafe_math_optimizations"
15416 {
15417   int i;
15418
15419   for (i=2; i<8; i++)
15420     operands[i] = gen_reg_rtx (XFmode);
15421
15422   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15423 })
15424
15425 (define_expand "asinxf2"
15426   [(set (match_dup 2)
15427         (mult:XF (match_operand:XF 1 "register_operand" "")
15428                  (match_dup 1)))
15429    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15430    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15431    (parallel [(set (match_operand:XF 0 "register_operand" "")
15432                    (unspec:XF [(match_dup 5) (match_dup 1)]
15433                               UNSPEC_FPATAN))
15434               (clobber (match_scratch:XF 6 ""))])]
15435   "TARGET_USE_FANCY_MATH_387
15436    && flag_unsafe_math_optimizations"
15437 {
15438   int i;
15439
15440   for (i=2; i<6; i++)
15441     operands[i] = gen_reg_rtx (XFmode);
15442
15443   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15444 })
15445
15446 (define_expand "acosdf2"
15447   [(set (match_dup 2)
15448         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15449    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15450    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15451    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15452    (parallel [(set (match_dup 7)
15453                    (unspec:XF [(match_dup 2) (match_dup 6)]
15454                               UNSPEC_FPATAN))
15455               (clobber (match_scratch:XF 8 ""))])
15456    (set (match_operand:DF 0 "register_operand" "")
15457         (float_truncate:DF (match_dup 7)))]
15458   "TARGET_USE_FANCY_MATH_387
15459    && flag_unsafe_math_optimizations"
15460 {
15461   int i;
15462
15463   for (i=2; i<8; i++)
15464     operands[i] = gen_reg_rtx (XFmode);
15465
15466   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15467 })
15468
15469 (define_expand "acossf2"
15470   [(set (match_dup 2)
15471         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15472    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15473    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15474    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15475    (parallel [(set (match_dup 7)
15476                    (unspec:XF [(match_dup 2) (match_dup 6)]
15477                               UNSPEC_FPATAN))
15478               (clobber (match_scratch:XF 8 ""))])
15479    (set (match_operand:SF 0 "register_operand" "")
15480         (float_truncate:SF (match_dup 7)))]
15481   "TARGET_USE_FANCY_MATH_387
15482    && flag_unsafe_math_optimizations"
15483 {
15484   int i;
15485
15486   for (i=2; i<8; i++)
15487     operands[i] = gen_reg_rtx (XFmode);
15488
15489   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15490 })
15491
15492 (define_expand "acosxf2"
15493   [(set (match_dup 2)
15494         (mult:XF (match_operand:XF 1 "register_operand" "")
15495                  (match_dup 1)))
15496    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15497    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15498    (parallel [(set (match_operand:XF 0 "register_operand" "")
15499                    (unspec:XF [(match_dup 1) (match_dup 5)]
15500                               UNSPEC_FPATAN))
15501               (clobber (match_scratch:XF 6 ""))])]
15502   "TARGET_USE_FANCY_MATH_387
15503    && flag_unsafe_math_optimizations"
15504 {
15505   int i;
15506
15507   for (i=2; i<6; i++)
15508     operands[i] = gen_reg_rtx (XFmode);
15509
15510   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15511 })
15512
15513 (define_insn "fyl2x_xf3"
15514   [(set (match_operand:XF 0 "register_operand" "=f")
15515         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15516                     (match_operand:XF 1 "register_operand" "u")]
15517                    UNSPEC_FYL2X))
15518    (clobber (match_scratch:XF 3 "=1"))]
15519   "TARGET_USE_FANCY_MATH_387
15520    && flag_unsafe_math_optimizations"
15521   "fyl2x"
15522   [(set_attr "type" "fpspc")
15523    (set_attr "mode" "XF")])
15524
15525 (define_expand "logsf2"
15526   [(set (match_dup 2)
15527         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15528    (parallel [(set (match_dup 4)
15529                    (unspec:XF [(match_dup 2)
15530                                (match_dup 3)] UNSPEC_FYL2X))
15531               (clobber (match_scratch:XF 5 ""))])
15532    (set (match_operand:SF 0 "register_operand" "")
15533         (float_truncate:SF (match_dup 4)))]
15534   "TARGET_USE_FANCY_MATH_387
15535    && flag_unsafe_math_optimizations"
15536 {
15537   rtx temp;
15538
15539   operands[2] = gen_reg_rtx (XFmode);
15540   operands[3] = gen_reg_rtx (XFmode);
15541   operands[4] = gen_reg_rtx (XFmode);
15542
15543   temp = standard_80387_constant_rtx (4); /* fldln2 */
15544   emit_move_insn (operands[3], temp);
15545 })
15546
15547 (define_expand "logdf2"
15548   [(set (match_dup 2)
15549         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15550    (parallel [(set (match_dup 4)
15551                    (unspec:XF [(match_dup 2)
15552                                (match_dup 3)] UNSPEC_FYL2X))
15553               (clobber (match_scratch:XF 5 ""))])
15554    (set (match_operand:DF 0 "register_operand" "")
15555         (float_truncate:DF (match_dup 4)))]
15556   "TARGET_USE_FANCY_MATH_387
15557    && flag_unsafe_math_optimizations"
15558 {
15559   rtx temp;
15560
15561   operands[2] = gen_reg_rtx (XFmode);
15562   operands[3] = gen_reg_rtx (XFmode);
15563   operands[4] = gen_reg_rtx (XFmode);
15564
15565   temp = standard_80387_constant_rtx (4); /* fldln2 */
15566   emit_move_insn (operands[3], temp);
15567 })
15568
15569 (define_expand "logxf2"
15570   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15571                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15572                                (match_dup 2)] UNSPEC_FYL2X))
15573               (clobber (match_scratch:XF 3 ""))])]
15574   "TARGET_USE_FANCY_MATH_387
15575    && flag_unsafe_math_optimizations"
15576 {
15577   rtx temp;
15578
15579   operands[2] = gen_reg_rtx (XFmode);
15580   temp = standard_80387_constant_rtx (4); /* fldln2 */
15581   emit_move_insn (operands[2], temp);
15582 })
15583
15584 (define_expand "log10sf2"
15585   [(set (match_dup 2)
15586         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15587    (parallel [(set (match_dup 4)
15588                    (unspec:XF [(match_dup 2)
15589                                (match_dup 3)] UNSPEC_FYL2X))
15590               (clobber (match_scratch:XF 5 ""))])
15591    (set (match_operand:SF 0 "register_operand" "")
15592         (float_truncate:SF (match_dup 4)))]
15593   "TARGET_USE_FANCY_MATH_387
15594    && flag_unsafe_math_optimizations"
15595 {
15596   rtx temp;
15597
15598   operands[2] = gen_reg_rtx (XFmode);
15599   operands[3] = gen_reg_rtx (XFmode);
15600   operands[4] = gen_reg_rtx (XFmode);
15601
15602   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15603   emit_move_insn (operands[3], temp);
15604 })
15605
15606 (define_expand "log10df2"
15607   [(set (match_dup 2)
15608         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15609    (parallel [(set (match_dup 4)
15610                    (unspec:XF [(match_dup 2)
15611                                (match_dup 3)] UNSPEC_FYL2X))
15612               (clobber (match_scratch:XF 5 ""))])
15613    (set (match_operand:DF 0 "register_operand" "")
15614         (float_truncate:DF (match_dup 4)))]
15615   "TARGET_USE_FANCY_MATH_387
15616    && flag_unsafe_math_optimizations"
15617 {
15618   rtx temp;
15619
15620   operands[2] = gen_reg_rtx (XFmode);
15621   operands[3] = gen_reg_rtx (XFmode);
15622   operands[4] = gen_reg_rtx (XFmode);
15623
15624   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15625   emit_move_insn (operands[3], temp);
15626 })
15627
15628 (define_expand "log10xf2"
15629   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15630                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15631                                (match_dup 2)] UNSPEC_FYL2X))
15632               (clobber (match_scratch:XF 3 ""))])]
15633   "TARGET_USE_FANCY_MATH_387
15634    && flag_unsafe_math_optimizations"
15635 {
15636   rtx temp;
15637
15638   operands[2] = gen_reg_rtx (XFmode);
15639   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15640   emit_move_insn (operands[2], temp);
15641 })
15642
15643 (define_expand "log2sf2"
15644   [(set (match_dup 2)
15645         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15646    (parallel [(set (match_dup 4)
15647                    (unspec:XF [(match_dup 2)
15648                                (match_dup 3)] UNSPEC_FYL2X))
15649               (clobber (match_scratch:XF 5 ""))])
15650    (set (match_operand:SF 0 "register_operand" "")
15651         (float_truncate:SF (match_dup 4)))]
15652   "TARGET_USE_FANCY_MATH_387
15653    && flag_unsafe_math_optimizations"
15654 {
15655   operands[2] = gen_reg_rtx (XFmode);
15656   operands[3] = gen_reg_rtx (XFmode);
15657   operands[4] = gen_reg_rtx (XFmode);
15658
15659   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15660 })
15661
15662 (define_expand "log2df2"
15663   [(set (match_dup 2)
15664         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15665    (parallel [(set (match_dup 4)
15666                    (unspec:XF [(match_dup 2)
15667                                (match_dup 3)] UNSPEC_FYL2X))
15668               (clobber (match_scratch:XF 5 ""))])
15669    (set (match_operand:DF 0 "register_operand" "")
15670         (float_truncate:DF (match_dup 4)))]
15671   "TARGET_USE_FANCY_MATH_387
15672    && flag_unsafe_math_optimizations"
15673 {
15674   operands[2] = gen_reg_rtx (XFmode);
15675   operands[3] = gen_reg_rtx (XFmode);
15676   operands[4] = gen_reg_rtx (XFmode);
15677
15678   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15679 })
15680
15681 (define_expand "log2xf2"
15682   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15683                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15684                                (match_dup 2)] UNSPEC_FYL2X))
15685               (clobber (match_scratch:XF 3 ""))])]
15686   "TARGET_USE_FANCY_MATH_387
15687    && flag_unsafe_math_optimizations"
15688 {
15689   operands[2] = gen_reg_rtx (XFmode);
15690   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15691 })
15692
15693 (define_insn "fyl2xp1_xf3"
15694   [(set (match_operand:XF 0 "register_operand" "=f")
15695         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15696                     (match_operand:XF 1 "register_operand" "u")]
15697                    UNSPEC_FYL2XP1))
15698    (clobber (match_scratch:XF 3 "=1"))]
15699   "TARGET_USE_FANCY_MATH_387
15700    && flag_unsafe_math_optimizations"
15701   "fyl2xp1"
15702   [(set_attr "type" "fpspc")
15703    (set_attr "mode" "XF")])
15704
15705 (define_expand "log1psf2"
15706   [(use (match_operand:XF 0 "register_operand" ""))
15707    (use (match_operand:XF 1 "register_operand" ""))]
15708   "TARGET_USE_FANCY_MATH_387
15709    && flag_unsafe_math_optimizations"
15710 {
15711   rtx op0 = gen_reg_rtx (XFmode);
15712   rtx op1 = gen_reg_rtx (XFmode);
15713
15714   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15715   ix86_emit_i387_log1p (op0, op1);
15716   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
15717   DONE;
15718 })
15719
15720 (define_expand "log1pdf2"
15721   [(use (match_operand:XF 0 "register_operand" ""))
15722    (use (match_operand:XF 1 "register_operand" ""))]
15723   "TARGET_USE_FANCY_MATH_387
15724    && flag_unsafe_math_optimizations"
15725 {
15726   rtx op0 = gen_reg_rtx (XFmode);
15727   rtx op1 = gen_reg_rtx (XFmode);
15728
15729   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15730   ix86_emit_i387_log1p (op0, op1);
15731   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
15732   DONE;
15733 })
15734
15735 (define_expand "log1pxf2"
15736   [(use (match_operand:XF 0 "register_operand" ""))
15737    (use (match_operand:XF 1 "register_operand" ""))]
15738   "TARGET_USE_FANCY_MATH_387
15739    && flag_unsafe_math_optimizations"
15740 {
15741   ix86_emit_i387_log1p (operands[0], operands[1]);
15742   DONE;
15743 })
15744
15745 (define_insn "*fxtractxf3"
15746   [(set (match_operand:XF 0 "register_operand" "=f")
15747         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15748                    UNSPEC_XTRACT_FRACT))
15749    (set (match_operand:XF 1 "register_operand" "=u")
15750         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15751   "TARGET_USE_FANCY_MATH_387
15752    && flag_unsafe_math_optimizations"
15753   "fxtract"
15754   [(set_attr "type" "fpspc")
15755    (set_attr "mode" "XF")])
15756
15757 (define_expand "logbsf2"
15758   [(set (match_dup 2)
15759         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15760    (parallel [(set (match_dup 3)
15761                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15762               (set (match_dup 4)
15763                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15764    (set (match_operand:SF 0 "register_operand" "")
15765         (float_truncate:SF (match_dup 4)))]
15766   "TARGET_USE_FANCY_MATH_387
15767    && flag_unsafe_math_optimizations"
15768 {
15769   operands[2] = gen_reg_rtx (XFmode);
15770   operands[3] = gen_reg_rtx (XFmode);
15771   operands[4] = gen_reg_rtx (XFmode);
15772 })
15773
15774 (define_expand "logbdf2"
15775   [(set (match_dup 2)
15776         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15777    (parallel [(set (match_dup 3)
15778                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15779               (set (match_dup 4)
15780                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15781    (set (match_operand:DF 0 "register_operand" "")
15782         (float_truncate:DF (match_dup 4)))]
15783   "TARGET_USE_FANCY_MATH_387
15784    && flag_unsafe_math_optimizations"
15785 {
15786   operands[2] = gen_reg_rtx (XFmode);
15787   operands[3] = gen_reg_rtx (XFmode);
15788   operands[4] = gen_reg_rtx (XFmode);
15789 })
15790
15791 (define_expand "logbxf2"
15792   [(parallel [(set (match_dup 2)
15793                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15794                               UNSPEC_XTRACT_FRACT))
15795               (set (match_operand:XF 0 "register_operand" "")
15796                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15797   "TARGET_USE_FANCY_MATH_387
15798    && flag_unsafe_math_optimizations"
15799 {
15800   operands[2] = gen_reg_rtx (XFmode);
15801 })
15802
15803 (define_expand "ilogbsi2"
15804   [(parallel [(set (match_dup 2)
15805                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15806                               UNSPEC_XTRACT_FRACT))
15807               (set (match_operand:XF 3 "register_operand" "")
15808                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15809    (parallel [(set (match_operand:SI 0 "register_operand" "")
15810                    (fix:SI (match_dup 3)))
15811               (clobber (reg:CC FLAGS_REG))])]
15812   "TARGET_USE_FANCY_MATH_387
15813    && flag_unsafe_math_optimizations"
15814 {
15815   operands[2] = gen_reg_rtx (XFmode);
15816   operands[3] = gen_reg_rtx (XFmode);
15817 })
15818
15819 (define_insn "*f2xm1xf2"
15820   [(set (match_operand:XF 0 "register_operand" "=f")
15821         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15822          UNSPEC_F2XM1))]
15823   "TARGET_USE_FANCY_MATH_387
15824    && flag_unsafe_math_optimizations"
15825   "f2xm1"
15826   [(set_attr "type" "fpspc")
15827    (set_attr "mode" "XF")])
15828
15829 (define_insn "*fscalexf4"
15830   [(set (match_operand:XF 0 "register_operand" "=f")
15831         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15832                     (match_operand:XF 3 "register_operand" "1")]
15833                    UNSPEC_FSCALE_FRACT))
15834    (set (match_operand:XF 1 "register_operand" "=u")
15835         (unspec:XF [(match_dup 2) (match_dup 3)]
15836                    UNSPEC_FSCALE_EXP))]
15837   "TARGET_USE_FANCY_MATH_387
15838    && flag_unsafe_math_optimizations"
15839   "fscale"
15840   [(set_attr "type" "fpspc")
15841    (set_attr "mode" "XF")])
15842
15843 (define_expand "expsf2"
15844   [(set (match_dup 2)
15845         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15846    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15847    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15848    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15849    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15850    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15851    (parallel [(set (match_dup 10)
15852                    (unspec:XF [(match_dup 9) (match_dup 5)]
15853                               UNSPEC_FSCALE_FRACT))
15854               (set (match_dup 11)
15855                    (unspec:XF [(match_dup 9) (match_dup 5)]
15856                               UNSPEC_FSCALE_EXP))])
15857    (set (match_operand:SF 0 "register_operand" "")
15858         (float_truncate:SF (match_dup 10)))]
15859   "TARGET_USE_FANCY_MATH_387
15860    && flag_unsafe_math_optimizations"
15861 {
15862   rtx temp;
15863   int i;
15864
15865   for (i=2; i<12; i++)
15866     operands[i] = gen_reg_rtx (XFmode);
15867   temp = standard_80387_constant_rtx (5); /* fldl2e */
15868   emit_move_insn (operands[3], temp);
15869   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15870 })
15871
15872 (define_expand "expdf2"
15873   [(set (match_dup 2)
15874         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15875    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15876    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15877    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15878    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15879    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15880    (parallel [(set (match_dup 10)
15881                    (unspec:XF [(match_dup 9) (match_dup 5)]
15882                               UNSPEC_FSCALE_FRACT))
15883               (set (match_dup 11)
15884                    (unspec:XF [(match_dup 9) (match_dup 5)]
15885                               UNSPEC_FSCALE_EXP))])
15886    (set (match_operand:DF 0 "register_operand" "")
15887         (float_truncate:DF (match_dup 10)))]
15888   "TARGET_USE_FANCY_MATH_387
15889    && flag_unsafe_math_optimizations"
15890 {
15891   rtx temp;
15892   int i;
15893
15894   for (i=2; i<12; i++)
15895     operands[i] = gen_reg_rtx (XFmode);
15896   temp = standard_80387_constant_rtx (5); /* fldl2e */
15897   emit_move_insn (operands[3], temp);
15898   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15899 })
15900
15901 (define_expand "expxf2"
15902   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15903                                (match_dup 2)))
15904    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15905    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15906    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15907    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15908    (parallel [(set (match_operand:XF 0 "register_operand" "")
15909                    (unspec:XF [(match_dup 8) (match_dup 4)]
15910                               UNSPEC_FSCALE_FRACT))
15911               (set (match_dup 9)
15912                    (unspec:XF [(match_dup 8) (match_dup 4)]
15913                               UNSPEC_FSCALE_EXP))])]
15914   "TARGET_USE_FANCY_MATH_387
15915    && flag_unsafe_math_optimizations"
15916 {
15917   rtx temp;
15918   int i;
15919
15920   for (i=2; i<10; i++)
15921     operands[i] = gen_reg_rtx (XFmode);
15922   temp = standard_80387_constant_rtx (5); /* fldl2e */
15923   emit_move_insn (operands[2], temp);
15924   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15925 })
15926
15927 (define_expand "exp10sf2"
15928   [(set (match_dup 2)
15929         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15930    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15931    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15932    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15933    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15934    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15935    (parallel [(set (match_dup 10)
15936                    (unspec:XF [(match_dup 9) (match_dup 5)]
15937                               UNSPEC_FSCALE_FRACT))
15938               (set (match_dup 11)
15939                    (unspec:XF [(match_dup 9) (match_dup 5)]
15940                               UNSPEC_FSCALE_EXP))])
15941    (set (match_operand:SF 0 "register_operand" "")
15942         (float_truncate:SF (match_dup 10)))]
15943   "TARGET_USE_FANCY_MATH_387
15944    && flag_unsafe_math_optimizations"
15945 {
15946   rtx temp;
15947   int i;
15948
15949   for (i=2; i<12; i++)
15950     operands[i] = gen_reg_rtx (XFmode);
15951   temp = standard_80387_constant_rtx (6); /* fldl2t */
15952   emit_move_insn (operands[3], temp);
15953   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15954 })
15955
15956 (define_expand "exp10df2"
15957   [(set (match_dup 2)
15958         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15959    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15960    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15961    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15962    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15963    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15964    (parallel [(set (match_dup 10)
15965                    (unspec:XF [(match_dup 9) (match_dup 5)]
15966                               UNSPEC_FSCALE_FRACT))
15967               (set (match_dup 11)
15968                    (unspec:XF [(match_dup 9) (match_dup 5)]
15969                               UNSPEC_FSCALE_EXP))])
15970    (set (match_operand:DF 0 "register_operand" "")
15971         (float_truncate:DF (match_dup 10)))]
15972   "TARGET_USE_FANCY_MATH_387
15973    && flag_unsafe_math_optimizations"
15974 {
15975   rtx temp;
15976   int i;
15977
15978   for (i=2; i<12; i++)
15979     operands[i] = gen_reg_rtx (XFmode);
15980   temp = standard_80387_constant_rtx (6); /* fldl2t */
15981   emit_move_insn (operands[3], temp);
15982   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15983 })
15984
15985 (define_expand "exp10xf2"
15986   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15987                                (match_dup 2)))
15988    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15989    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15990    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15991    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15992    (parallel [(set (match_operand:XF 0 "register_operand" "")
15993                    (unspec:XF [(match_dup 8) (match_dup 4)]
15994                               UNSPEC_FSCALE_FRACT))
15995               (set (match_dup 9)
15996                    (unspec:XF [(match_dup 8) (match_dup 4)]
15997                               UNSPEC_FSCALE_EXP))])]
15998   "TARGET_USE_FANCY_MATH_387
15999    && flag_unsafe_math_optimizations"
16000 {
16001   rtx temp;
16002   int i;
16003
16004   for (i=2; i<10; i++)
16005     operands[i] = gen_reg_rtx (XFmode);
16006   temp = standard_80387_constant_rtx (6); /* fldl2t */
16007   emit_move_insn (operands[2], temp);
16008   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16009 })
16010
16011 (define_expand "exp2sf2"
16012   [(set (match_dup 2)
16013         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16014    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16015    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16016    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16017    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16018    (parallel [(set (match_dup 8)
16019                    (unspec:XF [(match_dup 7) (match_dup 3)]
16020                               UNSPEC_FSCALE_FRACT))
16021               (set (match_dup 9)
16022                    (unspec:XF [(match_dup 7) (match_dup 3)]
16023                               UNSPEC_FSCALE_EXP))])
16024    (set (match_operand:SF 0 "register_operand" "")
16025         (float_truncate:SF (match_dup 8)))]
16026   "TARGET_USE_FANCY_MATH_387
16027    && flag_unsafe_math_optimizations"
16028 {
16029   int i;
16030
16031   for (i=2; i<10; i++)
16032     operands[i] = gen_reg_rtx (XFmode);
16033   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16034 })
16035
16036 (define_expand "exp2df2"
16037   [(set (match_dup 2)
16038         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16039    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16040    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16041    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16042    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16043    (parallel [(set (match_dup 8)
16044                    (unspec:XF [(match_dup 7) (match_dup 3)]
16045                               UNSPEC_FSCALE_FRACT))
16046               (set (match_dup 9)
16047                    (unspec:XF [(match_dup 7) (match_dup 3)]
16048                               UNSPEC_FSCALE_EXP))])
16049    (set (match_operand:DF 0 "register_operand" "")
16050         (float_truncate:DF (match_dup 8)))]
16051   "TARGET_USE_FANCY_MATH_387
16052    && flag_unsafe_math_optimizations"
16053 {
16054   int i;
16055
16056   for (i=2; i<10; i++)
16057     operands[i] = gen_reg_rtx (XFmode);
16058   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16059 })
16060
16061 (define_expand "exp2xf2"
16062   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16063    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16064    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16065    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16066    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16067    (parallel [(set (match_operand:XF 0 "register_operand" "")
16068                    (unspec:XF [(match_dup 7) (match_dup 3)]
16069                               UNSPEC_FSCALE_FRACT))
16070               (set (match_dup 8)
16071                    (unspec:XF [(match_dup 7) (match_dup 3)]
16072                               UNSPEC_FSCALE_EXP))])]
16073   "TARGET_USE_FANCY_MATH_387
16074    && flag_unsafe_math_optimizations"
16075 {
16076   int i;
16077
16078   for (i=2; i<9; i++)
16079     operands[i] = gen_reg_rtx (XFmode);
16080   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16081 })
16082
16083 (define_expand "expm1df2"
16084   [(set (match_dup 2)
16085         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16086    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16087    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16088    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16089    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16090    (parallel [(set (match_dup 8)
16091                    (unspec:XF [(match_dup 7) (match_dup 5)]
16092                               UNSPEC_FSCALE_FRACT))
16093                    (set (match_dup 9)
16094                    (unspec:XF [(match_dup 7) (match_dup 5)]
16095                               UNSPEC_FSCALE_EXP))])
16096    (parallel [(set (match_dup 11)
16097                    (unspec:XF [(match_dup 10) (match_dup 9)]
16098                               UNSPEC_FSCALE_FRACT))
16099               (set (match_dup 12)
16100                    (unspec:XF [(match_dup 10) (match_dup 9)]
16101                               UNSPEC_FSCALE_EXP))])
16102    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16103    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16104    (set (match_operand:DF 0 "register_operand" "")
16105         (float_truncate:DF (match_dup 14)))]
16106   "TARGET_USE_FANCY_MATH_387
16107    && flag_unsafe_math_optimizations"
16108 {
16109   rtx temp;
16110   int i;
16111
16112   for (i=2; i<15; i++)
16113     operands[i] = gen_reg_rtx (XFmode);
16114   temp = standard_80387_constant_rtx (5); /* fldl2e */
16115   emit_move_insn (operands[3], temp);
16116   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16117 })
16118
16119 (define_expand "expm1sf2"
16120   [(set (match_dup 2)
16121         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16122    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16123    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16124    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16125    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16126    (parallel [(set (match_dup 8)
16127                    (unspec:XF [(match_dup 7) (match_dup 5)]
16128                               UNSPEC_FSCALE_FRACT))
16129                    (set (match_dup 9)
16130                    (unspec:XF [(match_dup 7) (match_dup 5)]
16131                               UNSPEC_FSCALE_EXP))])
16132    (parallel [(set (match_dup 11)
16133                    (unspec:XF [(match_dup 10) (match_dup 9)]
16134                               UNSPEC_FSCALE_FRACT))
16135               (set (match_dup 12)
16136                    (unspec:XF [(match_dup 10) (match_dup 9)]
16137                               UNSPEC_FSCALE_EXP))])
16138    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16139    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16140    (set (match_operand:SF 0 "register_operand" "")
16141         (float_truncate:SF (match_dup 14)))]
16142   "TARGET_USE_FANCY_MATH_387
16143    && flag_unsafe_math_optimizations"
16144 {
16145   rtx temp;
16146   int i;
16147
16148   for (i=2; i<15; i++)
16149     operands[i] = gen_reg_rtx (XFmode);
16150   temp = standard_80387_constant_rtx (5); /* fldl2e */
16151   emit_move_insn (operands[3], temp);
16152   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16153 })
16154
16155 (define_expand "expm1xf2"
16156   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16157                                (match_dup 2)))
16158    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16159    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16160    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16161    (parallel [(set (match_dup 7)
16162                    (unspec:XF [(match_dup 6) (match_dup 4)]
16163                               UNSPEC_FSCALE_FRACT))
16164                    (set (match_dup 8)
16165                    (unspec:XF [(match_dup 6) (match_dup 4)]
16166                               UNSPEC_FSCALE_EXP))])
16167    (parallel [(set (match_dup 10)
16168                    (unspec:XF [(match_dup 9) (match_dup 8)]
16169                               UNSPEC_FSCALE_FRACT))
16170               (set (match_dup 11)
16171                    (unspec:XF [(match_dup 9) (match_dup 8)]
16172                               UNSPEC_FSCALE_EXP))])
16173    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16174    (set (match_operand:XF 0 "register_operand" "")
16175         (plus:XF (match_dup 12) (match_dup 7)))]
16176   "TARGET_USE_FANCY_MATH_387
16177    && flag_unsafe_math_optimizations"
16178 {
16179   rtx temp;
16180   int i;
16181
16182   for (i=2; i<13; i++)
16183     operands[i] = gen_reg_rtx (XFmode);
16184   temp = standard_80387_constant_rtx (5); /* fldl2e */
16185   emit_move_insn (operands[2], temp);
16186   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16187 })
16188 \f
16189
16190 (define_insn "frndintxf2"
16191   [(set (match_operand:XF 0 "register_operand" "=f")
16192         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16193          UNSPEC_FRNDINT))]
16194   "TARGET_USE_FANCY_MATH_387
16195    && flag_unsafe_math_optimizations"
16196   "frndint"
16197   [(set_attr "type" "fpspc")
16198    (set_attr "mode" "XF")])
16199
16200 (define_expand "rintdf2"
16201   [(use (match_operand:DF 0 "register_operand" ""))
16202    (use (match_operand:DF 1 "register_operand" ""))]
16203   "TARGET_USE_FANCY_MATH_387
16204    && flag_unsafe_math_optimizations"
16205 {
16206   rtx op0 = gen_reg_rtx (XFmode);
16207   rtx op1 = gen_reg_rtx (XFmode);
16208
16209   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16210   emit_insn (gen_frndintxf2 (op0, op1));
16211
16212   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16213   DONE;
16214 })
16215
16216 (define_expand "rintsf2"
16217   [(use (match_operand:SF 0 "register_operand" ""))
16218    (use (match_operand:SF 1 "register_operand" ""))]
16219   "TARGET_USE_FANCY_MATH_387
16220    && flag_unsafe_math_optimizations"
16221 {
16222   rtx op0 = gen_reg_rtx (XFmode);
16223   rtx op1 = gen_reg_rtx (XFmode);
16224
16225   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16226   emit_insn (gen_frndintxf2 (op0, op1));
16227
16228   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16229   DONE;
16230 })
16231
16232 (define_expand "rintxf2"
16233   [(use (match_operand:XF 0 "register_operand" ""))
16234    (use (match_operand:XF 1 "register_operand" ""))]
16235   "TARGET_USE_FANCY_MATH_387
16236    && flag_unsafe_math_optimizations"
16237 {
16238   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16239   DONE;
16240 })
16241
16242 (define_insn "frndintxf2_floor"
16243   [(set (match_operand:XF 0 "register_operand" "=f")
16244         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16245          UNSPEC_FRNDINT_FLOOR))
16246    (use (match_operand:HI 2 "memory_operand" "m"))
16247    (use (match_operand:HI 3 "memory_operand" "m"))]
16248   "TARGET_USE_FANCY_MATH_387
16249    && flag_unsafe_math_optimizations"
16250   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16251   [(set_attr "type" "frndint")
16252    (set_attr "i387_cw" "floor")
16253    (set_attr "mode" "XF")])
16254
16255 (define_expand "floordf2"
16256   [(use (match_operand:DF 0 "register_operand" ""))
16257    (use (match_operand:DF 1 "register_operand" ""))]
16258   "TARGET_USE_FANCY_MATH_387
16259    && flag_unsafe_math_optimizations"
16260 {
16261   rtx op0 = gen_reg_rtx (XFmode);
16262   rtx op1 = gen_reg_rtx (XFmode);
16263   rtx op2 = assign_386_stack_local (HImode, 1);
16264   rtx op3 = assign_386_stack_local (HImode, 2);
16265         
16266   ix86_optimize_mode_switching = 1;
16267
16268   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16269   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16270
16271   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16272   DONE;
16273 })
16274
16275 (define_expand "floorsf2"
16276   [(use (match_operand:SF 0 "register_operand" ""))
16277    (use (match_operand:SF 1 "register_operand" ""))]
16278   "TARGET_USE_FANCY_MATH_387
16279    && flag_unsafe_math_optimizations"
16280 {
16281   rtx op0 = gen_reg_rtx (XFmode);
16282   rtx op1 = gen_reg_rtx (XFmode);
16283   rtx op2 = assign_386_stack_local (HImode, 1);
16284   rtx op3 = assign_386_stack_local (HImode, 2);
16285         
16286   ix86_optimize_mode_switching = 1;
16287
16288   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16289   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16290
16291   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16292   DONE;
16293 })
16294
16295 (define_expand "floorxf2"
16296   [(use (match_operand:XF 0 "register_operand" ""))
16297    (use (match_operand:XF 1 "register_operand" ""))]
16298   "TARGET_USE_FANCY_MATH_387
16299    && flag_unsafe_math_optimizations"
16300 {
16301   rtx op2 = assign_386_stack_local (HImode, 1);
16302   rtx op3 = assign_386_stack_local (HImode, 2);
16303         
16304   ix86_optimize_mode_switching = 1;
16305
16306   emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16307   DONE;
16308 })
16309
16310 (define_insn "frndintxf2_ceil"
16311   [(set (match_operand:XF 0 "register_operand" "=f")
16312         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16313          UNSPEC_FRNDINT_CEIL))
16314    (use (match_operand:HI 2 "memory_operand" "m"))
16315    (use (match_operand:HI 3 "memory_operand" "m"))]
16316   "TARGET_USE_FANCY_MATH_387
16317    && flag_unsafe_math_optimizations"
16318   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16319   [(set_attr "type" "frndint")
16320    (set_attr "i387_cw" "ceil")
16321    (set_attr "mode" "XF")])
16322
16323 (define_expand "ceildf2"
16324   [(use (match_operand:DF 0 "register_operand" ""))
16325    (use (match_operand:DF 1 "register_operand" ""))]
16326   "TARGET_USE_FANCY_MATH_387
16327    && flag_unsafe_math_optimizations"
16328 {
16329   rtx op0 = gen_reg_rtx (XFmode);
16330   rtx op1 = gen_reg_rtx (XFmode);
16331   rtx op2 = assign_386_stack_local (HImode, 1);
16332   rtx op3 = assign_386_stack_local (HImode, 2);
16333         
16334   ix86_optimize_mode_switching = 1;
16335
16336   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16337   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16338
16339   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16340   DONE;
16341 })
16342
16343 (define_expand "ceilsf2"
16344   [(use (match_operand:SF 0 "register_operand" ""))
16345    (use (match_operand:SF 1 "register_operand" ""))]
16346   "TARGET_USE_FANCY_MATH_387
16347    && flag_unsafe_math_optimizations"
16348 {
16349   rtx op0 = gen_reg_rtx (XFmode);
16350   rtx op1 = gen_reg_rtx (XFmode);
16351   rtx op2 = assign_386_stack_local (HImode, 1);
16352   rtx op3 = assign_386_stack_local (HImode, 2);
16353         
16354   ix86_optimize_mode_switching = 1;
16355
16356   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16357   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16358
16359   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16360   DONE;
16361 })
16362
16363 (define_expand "ceilxf2"
16364   [(use (match_operand:XF 0 "register_operand" ""))
16365    (use (match_operand:XF 1 "register_operand" ""))]
16366   "TARGET_USE_FANCY_MATH_387
16367    && flag_unsafe_math_optimizations"
16368 {
16369   rtx op2 = assign_386_stack_local (HImode, 1);
16370   rtx op3 = assign_386_stack_local (HImode, 2);
16371         
16372   ix86_optimize_mode_switching = 1;
16373
16374   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16375   DONE;
16376 })
16377
16378 (define_insn "frndintxf2_trunc"
16379   [(set (match_operand:XF 0 "register_operand" "=f")
16380         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16381          UNSPEC_FRNDINT_TRUNC))
16382    (use (match_operand:HI 2 "memory_operand" "m"))
16383    (use (match_operand:HI 3 "memory_operand" "m"))]
16384   "TARGET_USE_FANCY_MATH_387
16385    && flag_unsafe_math_optimizations"
16386   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16387   [(set_attr "type" "frndint")
16388    (set_attr "i387_cw" "trunc")
16389    (set_attr "mode" "XF")])
16390
16391 (define_expand "btruncdf2"
16392   [(use (match_operand:DF 0 "register_operand" ""))
16393    (use (match_operand:DF 1 "register_operand" ""))]
16394   "TARGET_USE_FANCY_MATH_387
16395    && flag_unsafe_math_optimizations"
16396 {
16397   rtx op0 = gen_reg_rtx (XFmode);
16398   rtx op1 = gen_reg_rtx (XFmode);
16399   rtx op2 = assign_386_stack_local (HImode, 1);
16400   rtx op3 = assign_386_stack_local (HImode, 2);
16401         
16402   ix86_optimize_mode_switching = 1;
16403
16404   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16405   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16406
16407   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16408   DONE;
16409 })
16410
16411 (define_expand "btruncsf2"
16412   [(use (match_operand:SF 0 "register_operand" ""))
16413    (use (match_operand:SF 1 "register_operand" ""))]
16414   "TARGET_USE_FANCY_MATH_387
16415    && flag_unsafe_math_optimizations"
16416 {
16417   rtx op0 = gen_reg_rtx (XFmode);
16418   rtx op1 = gen_reg_rtx (XFmode);
16419   rtx op2 = assign_386_stack_local (HImode, 1);
16420   rtx op3 = assign_386_stack_local (HImode, 2);
16421         
16422   ix86_optimize_mode_switching = 1;
16423
16424   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16425   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16426
16427   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16428   DONE;
16429 })
16430
16431 (define_expand "btruncxf2"
16432   [(use (match_operand:XF 0 "register_operand" ""))
16433    (use (match_operand:XF 1 "register_operand" ""))]
16434   "TARGET_USE_FANCY_MATH_387
16435    && flag_unsafe_math_optimizations"
16436 {
16437   rtx op2 = assign_386_stack_local (HImode, 1);
16438   rtx op3 = assign_386_stack_local (HImode, 2);
16439         
16440   ix86_optimize_mode_switching = 1;
16441
16442   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16443   DONE;
16444 })
16445
16446 (define_insn "frndintxf2_mask_pm"
16447   [(set (match_operand:XF 0 "register_operand" "=f")
16448         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16449          UNSPEC_FRNDINT_MASK_PM))
16450    (use (match_operand:HI 2 "memory_operand" "m"))
16451    (use (match_operand:HI 3 "memory_operand" "m"))]
16452   "TARGET_USE_FANCY_MATH_387
16453    && flag_unsafe_math_optimizations"
16454   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16455   [(set_attr "type" "frndint")
16456    (set_attr "i387_cw" "mask_pm")
16457    (set_attr "mode" "XF")])
16458
16459 (define_expand "nearbyintdf2"
16460   [(use (match_operand:DF 0 "register_operand" ""))
16461    (use (match_operand:DF 1 "register_operand" ""))]
16462   "TARGET_USE_FANCY_MATH_387
16463    && flag_unsafe_math_optimizations"
16464 {
16465   rtx op0 = gen_reg_rtx (XFmode);
16466   rtx op1 = gen_reg_rtx (XFmode);
16467   rtx op2 = assign_386_stack_local (HImode, 1);
16468   rtx op3 = assign_386_stack_local (HImode, 2);
16469         
16470   ix86_optimize_mode_switching = 1;
16471
16472   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16473   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16474
16475   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16476   DONE;
16477 })
16478
16479 (define_expand "nearbyintsf2"
16480   [(use (match_operand:SF 0 "register_operand" ""))
16481    (use (match_operand:SF 1 "register_operand" ""))]
16482   "TARGET_USE_FANCY_MATH_387
16483    && flag_unsafe_math_optimizations"
16484 {
16485   rtx op0 = gen_reg_rtx (XFmode);
16486   rtx op1 = gen_reg_rtx (XFmode);
16487   rtx op2 = assign_386_stack_local (HImode, 1);
16488   rtx op3 = assign_386_stack_local (HImode, 2);
16489         
16490   ix86_optimize_mode_switching = 1;
16491
16492   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16493   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16494
16495   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16496   DONE;
16497 })
16498
16499 (define_expand "nearbyintxf2"
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   rtx op2 = assign_386_stack_local (HImode, 1);
16506   rtx op3 = assign_386_stack_local (HImode, 2);
16507         
16508   ix86_optimize_mode_switching = 1;
16509
16510   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16511                                      op2, op3));
16512   DONE;
16513 })
16514
16515 \f
16516 ;; Block operation instructions
16517
16518 (define_insn "cld"
16519  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16520  ""
16521  "cld"
16522   [(set_attr "type" "cld")])
16523
16524 (define_expand "movmemsi"
16525   [(use (match_operand:BLK 0 "memory_operand" ""))
16526    (use (match_operand:BLK 1 "memory_operand" ""))
16527    (use (match_operand:SI 2 "nonmemory_operand" ""))
16528    (use (match_operand:SI 3 "const_int_operand" ""))]
16529   "! optimize_size"
16530 {
16531  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16532    DONE;
16533  else
16534    FAIL;
16535 })
16536
16537 (define_expand "movmemdi"
16538   [(use (match_operand:BLK 0 "memory_operand" ""))
16539    (use (match_operand:BLK 1 "memory_operand" ""))
16540    (use (match_operand:DI 2 "nonmemory_operand" ""))
16541    (use (match_operand:DI 3 "const_int_operand" ""))]
16542   "TARGET_64BIT"
16543 {
16544  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16545    DONE;
16546  else
16547    FAIL;
16548 })
16549
16550 ;; Most CPUs don't like single string operations
16551 ;; Handle this case here to simplify previous expander.
16552
16553 (define_expand "strmov"
16554   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16555    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16556    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16557               (clobber (reg:CC FLAGS_REG))])
16558    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16559               (clobber (reg:CC FLAGS_REG))])]
16560   ""
16561 {
16562   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16563
16564   /* If .md ever supports :P for Pmode, these can be directly
16565      in the pattern above.  */
16566   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16567   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16568
16569   if (TARGET_SINGLE_STRINGOP || optimize_size)
16570     {
16571       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16572                                       operands[2], operands[3],
16573                                       operands[5], operands[6]));
16574       DONE;
16575     }
16576
16577   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16578 })
16579
16580 (define_expand "strmov_singleop"
16581   [(parallel [(set (match_operand 1 "memory_operand" "")
16582                    (match_operand 3 "memory_operand" ""))
16583               (set (match_operand 0 "register_operand" "")
16584                    (match_operand 4 "" ""))
16585               (set (match_operand 2 "register_operand" "")
16586                    (match_operand 5 "" ""))
16587               (use (reg:SI DIRFLAG_REG))])]
16588   "TARGET_SINGLE_STRINGOP || optimize_size"
16589   "")
16590
16591 (define_insn "*strmovdi_rex_1"
16592   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16593         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16594    (set (match_operand:DI 0 "register_operand" "=D")
16595         (plus:DI (match_dup 2)
16596                  (const_int 8)))
16597    (set (match_operand:DI 1 "register_operand" "=S")
16598         (plus:DI (match_dup 3)
16599                  (const_int 8)))
16600    (use (reg:SI DIRFLAG_REG))]
16601   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16602   "movsq"
16603   [(set_attr "type" "str")
16604    (set_attr "mode" "DI")
16605    (set_attr "memory" "both")])
16606
16607 (define_insn "*strmovsi_1"
16608   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16609         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16610    (set (match_operand:SI 0 "register_operand" "=D")
16611         (plus:SI (match_dup 2)
16612                  (const_int 4)))
16613    (set (match_operand:SI 1 "register_operand" "=S")
16614         (plus:SI (match_dup 3)
16615                  (const_int 4)))
16616    (use (reg:SI DIRFLAG_REG))]
16617   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16618   "{movsl|movsd}"
16619   [(set_attr "type" "str")
16620    (set_attr "mode" "SI")
16621    (set_attr "memory" "both")])
16622
16623 (define_insn "*strmovsi_rex_1"
16624   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16625         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16626    (set (match_operand:DI 0 "register_operand" "=D")
16627         (plus:DI (match_dup 2)
16628                  (const_int 4)))
16629    (set (match_operand:DI 1 "register_operand" "=S")
16630         (plus:DI (match_dup 3)
16631                  (const_int 4)))
16632    (use (reg:SI DIRFLAG_REG))]
16633   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16634   "{movsl|movsd}"
16635   [(set_attr "type" "str")
16636    (set_attr "mode" "SI")
16637    (set_attr "memory" "both")])
16638
16639 (define_insn "*strmovhi_1"
16640   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16641         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16642    (set (match_operand:SI 0 "register_operand" "=D")
16643         (plus:SI (match_dup 2)
16644                  (const_int 2)))
16645    (set (match_operand:SI 1 "register_operand" "=S")
16646         (plus:SI (match_dup 3)
16647                  (const_int 2)))
16648    (use (reg:SI DIRFLAG_REG))]
16649   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16650   "movsw"
16651   [(set_attr "type" "str")
16652    (set_attr "memory" "both")
16653    (set_attr "mode" "HI")])
16654
16655 (define_insn "*strmovhi_rex_1"
16656   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16657         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16658    (set (match_operand:DI 0 "register_operand" "=D")
16659         (plus:DI (match_dup 2)
16660                  (const_int 2)))
16661    (set (match_operand:DI 1 "register_operand" "=S")
16662         (plus:DI (match_dup 3)
16663                  (const_int 2)))
16664    (use (reg:SI DIRFLAG_REG))]
16665   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16666   "movsw"
16667   [(set_attr "type" "str")
16668    (set_attr "memory" "both")
16669    (set_attr "mode" "HI")])
16670
16671 (define_insn "*strmovqi_1"
16672   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16673         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16674    (set (match_operand:SI 0 "register_operand" "=D")
16675         (plus:SI (match_dup 2)
16676                  (const_int 1)))
16677    (set (match_operand:SI 1 "register_operand" "=S")
16678         (plus:SI (match_dup 3)
16679                  (const_int 1)))
16680    (use (reg:SI DIRFLAG_REG))]
16681   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16682   "movsb"
16683   [(set_attr "type" "str")
16684    (set_attr "memory" "both")
16685    (set_attr "mode" "QI")])
16686
16687 (define_insn "*strmovqi_rex_1"
16688   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16689         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16690    (set (match_operand:DI 0 "register_operand" "=D")
16691         (plus:DI (match_dup 2)
16692                  (const_int 1)))
16693    (set (match_operand:DI 1 "register_operand" "=S")
16694         (plus:DI (match_dup 3)
16695                  (const_int 1)))
16696    (use (reg:SI DIRFLAG_REG))]
16697   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16698   "movsb"
16699   [(set_attr "type" "str")
16700    (set_attr "memory" "both")
16701    (set_attr "mode" "QI")])
16702
16703 (define_expand "rep_mov"
16704   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16705               (set (match_operand 0 "register_operand" "")
16706                    (match_operand 5 "" ""))
16707               (set (match_operand 2 "register_operand" "")
16708                    (match_operand 6 "" ""))
16709               (set (match_operand 1 "memory_operand" "")
16710                    (match_operand 3 "memory_operand" ""))
16711               (use (match_dup 4))
16712               (use (reg:SI DIRFLAG_REG))])]
16713   ""
16714   "")
16715
16716 (define_insn "*rep_movdi_rex64"
16717   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16718    (set (match_operand:DI 0 "register_operand" "=D") 
16719         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16720                             (const_int 3))
16721                  (match_operand:DI 3 "register_operand" "0")))
16722    (set (match_operand:DI 1 "register_operand" "=S") 
16723         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16724                  (match_operand:DI 4 "register_operand" "1")))
16725    (set (mem:BLK (match_dup 3))
16726         (mem:BLK (match_dup 4)))
16727    (use (match_dup 5))
16728    (use (reg:SI DIRFLAG_REG))]
16729   "TARGET_64BIT"
16730   "{rep\;movsq|rep movsq}"
16731   [(set_attr "type" "str")
16732    (set_attr "prefix_rep" "1")
16733    (set_attr "memory" "both")
16734    (set_attr "mode" "DI")])
16735
16736 (define_insn "*rep_movsi"
16737   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16738    (set (match_operand:SI 0 "register_operand" "=D") 
16739         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16740                             (const_int 2))
16741                  (match_operand:SI 3 "register_operand" "0")))
16742    (set (match_operand:SI 1 "register_operand" "=S") 
16743         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16744                  (match_operand:SI 4 "register_operand" "1")))
16745    (set (mem:BLK (match_dup 3))
16746         (mem:BLK (match_dup 4)))
16747    (use (match_dup 5))
16748    (use (reg:SI DIRFLAG_REG))]
16749   "!TARGET_64BIT"
16750   "{rep\;movsl|rep movsd}"
16751   [(set_attr "type" "str")
16752    (set_attr "prefix_rep" "1")
16753    (set_attr "memory" "both")
16754    (set_attr "mode" "SI")])
16755
16756 (define_insn "*rep_movsi_rex64"
16757   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16758    (set (match_operand:DI 0 "register_operand" "=D") 
16759         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16760                             (const_int 2))
16761                  (match_operand:DI 3 "register_operand" "0")))
16762    (set (match_operand:DI 1 "register_operand" "=S") 
16763         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16764                  (match_operand:DI 4 "register_operand" "1")))
16765    (set (mem:BLK (match_dup 3))
16766         (mem:BLK (match_dup 4)))
16767    (use (match_dup 5))
16768    (use (reg:SI DIRFLAG_REG))]
16769   "TARGET_64BIT"
16770   "{rep\;movsl|rep movsd}"
16771   [(set_attr "type" "str")
16772    (set_attr "prefix_rep" "1")
16773    (set_attr "memory" "both")
16774    (set_attr "mode" "SI")])
16775
16776 (define_insn "*rep_movqi"
16777   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16778    (set (match_operand:SI 0 "register_operand" "=D") 
16779         (plus:SI (match_operand:SI 3 "register_operand" "0")
16780                  (match_operand:SI 5 "register_operand" "2")))
16781    (set (match_operand:SI 1 "register_operand" "=S") 
16782         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16783    (set (mem:BLK (match_dup 3))
16784         (mem:BLK (match_dup 4)))
16785    (use (match_dup 5))
16786    (use (reg:SI DIRFLAG_REG))]
16787   "!TARGET_64BIT"
16788   "{rep\;movsb|rep movsb}"
16789   [(set_attr "type" "str")
16790    (set_attr "prefix_rep" "1")
16791    (set_attr "memory" "both")
16792    (set_attr "mode" "SI")])
16793
16794 (define_insn "*rep_movqi_rex64"
16795   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16796    (set (match_operand:DI 0 "register_operand" "=D") 
16797         (plus:DI (match_operand:DI 3 "register_operand" "0")
16798                  (match_operand:DI 5 "register_operand" "2")))
16799    (set (match_operand:DI 1 "register_operand" "=S") 
16800         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16801    (set (mem:BLK (match_dup 3))
16802         (mem:BLK (match_dup 4)))
16803    (use (match_dup 5))
16804    (use (reg:SI DIRFLAG_REG))]
16805   "TARGET_64BIT"
16806   "{rep\;movsb|rep movsb}"
16807   [(set_attr "type" "str")
16808    (set_attr "prefix_rep" "1")
16809    (set_attr "memory" "both")
16810    (set_attr "mode" "SI")])
16811
16812 (define_expand "clrmemsi"
16813    [(use (match_operand:BLK 0 "memory_operand" ""))
16814     (use (match_operand:SI 1 "nonmemory_operand" ""))
16815     (use (match_operand 2 "const_int_operand" ""))]
16816   ""
16817 {
16818  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16819    DONE;
16820  else
16821    FAIL;
16822 })
16823
16824 (define_expand "clrmemdi"
16825    [(use (match_operand:BLK 0 "memory_operand" ""))
16826     (use (match_operand:DI 1 "nonmemory_operand" ""))
16827     (use (match_operand 2 "const_int_operand" ""))]
16828   "TARGET_64BIT"
16829 {
16830  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16831    DONE;
16832  else
16833    FAIL;
16834 })
16835
16836 ;; Most CPUs don't like single string operations
16837 ;; Handle this case here to simplify previous expander.
16838
16839 (define_expand "strset"
16840   [(set (match_operand 1 "memory_operand" "")
16841         (match_operand 2 "register_operand" ""))
16842    (parallel [(set (match_operand 0 "register_operand" "")
16843                    (match_dup 3))
16844               (clobber (reg:CC FLAGS_REG))])]
16845   ""
16846 {
16847   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16848     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16849
16850   /* If .md ever supports :P for Pmode, this can be directly
16851      in the pattern above.  */
16852   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16853                               GEN_INT (GET_MODE_SIZE (GET_MODE
16854                                                       (operands[2]))));
16855   if (TARGET_SINGLE_STRINGOP || optimize_size)
16856     {
16857       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16858                                       operands[3]));
16859       DONE;
16860     }
16861 })
16862
16863 (define_expand "strset_singleop"
16864   [(parallel [(set (match_operand 1 "memory_operand" "")
16865                    (match_operand 2 "register_operand" ""))
16866               (set (match_operand 0 "register_operand" "")
16867                    (match_operand 3 "" ""))
16868               (use (reg:SI DIRFLAG_REG))])]
16869   "TARGET_SINGLE_STRINGOP || optimize_size"
16870   "")
16871
16872 (define_insn "*strsetdi_rex_1"
16873   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16874         (match_operand:DI 2 "register_operand" "a"))
16875    (set (match_operand:DI 0 "register_operand" "=D")
16876         (plus:DI (match_dup 1)
16877                  (const_int 8)))
16878    (use (reg:SI DIRFLAG_REG))]
16879   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16880   "stosq"
16881   [(set_attr "type" "str")
16882    (set_attr "memory" "store")
16883    (set_attr "mode" "DI")])
16884
16885 (define_insn "*strsetsi_1"
16886   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16887         (match_operand:SI 2 "register_operand" "a"))
16888    (set (match_operand:SI 0 "register_operand" "=D")
16889         (plus:SI (match_dup 1)
16890                  (const_int 4)))
16891    (use (reg:SI DIRFLAG_REG))]
16892   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16893   "{stosl|stosd}"
16894   [(set_attr "type" "str")
16895    (set_attr "memory" "store")
16896    (set_attr "mode" "SI")])
16897
16898 (define_insn "*strsetsi_rex_1"
16899   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16900         (match_operand:SI 2 "register_operand" "a"))
16901    (set (match_operand:DI 0 "register_operand" "=D")
16902         (plus:DI (match_dup 1)
16903                  (const_int 4)))
16904    (use (reg:SI DIRFLAG_REG))]
16905   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16906   "{stosl|stosd}"
16907   [(set_attr "type" "str")
16908    (set_attr "memory" "store")
16909    (set_attr "mode" "SI")])
16910
16911 (define_insn "*strsethi_1"
16912   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16913         (match_operand:HI 2 "register_operand" "a"))
16914    (set (match_operand:SI 0 "register_operand" "=D")
16915         (plus:SI (match_dup 1)
16916                  (const_int 2)))
16917    (use (reg:SI DIRFLAG_REG))]
16918   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16919   "stosw"
16920   [(set_attr "type" "str")
16921    (set_attr "memory" "store")
16922    (set_attr "mode" "HI")])
16923
16924 (define_insn "*strsethi_rex_1"
16925   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16926         (match_operand:HI 2 "register_operand" "a"))
16927    (set (match_operand:DI 0 "register_operand" "=D")
16928         (plus:DI (match_dup 1)
16929                  (const_int 2)))
16930    (use (reg:SI DIRFLAG_REG))]
16931   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16932   "stosw"
16933   [(set_attr "type" "str")
16934    (set_attr "memory" "store")
16935    (set_attr "mode" "HI")])
16936
16937 (define_insn "*strsetqi_1"
16938   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16939         (match_operand:QI 2 "register_operand" "a"))
16940    (set (match_operand:SI 0 "register_operand" "=D")
16941         (plus:SI (match_dup 1)
16942                  (const_int 1)))
16943    (use (reg:SI DIRFLAG_REG))]
16944   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16945   "stosb"
16946   [(set_attr "type" "str")
16947    (set_attr "memory" "store")
16948    (set_attr "mode" "QI")])
16949
16950 (define_insn "*strsetqi_rex_1"
16951   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16952         (match_operand:QI 2 "register_operand" "a"))
16953    (set (match_operand:DI 0 "register_operand" "=D")
16954         (plus:DI (match_dup 1)
16955                  (const_int 1)))
16956    (use (reg:SI DIRFLAG_REG))]
16957   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16958   "stosb"
16959   [(set_attr "type" "str")
16960    (set_attr "memory" "store")
16961    (set_attr "mode" "QI")])
16962
16963 (define_expand "rep_stos"
16964   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16965               (set (match_operand 0 "register_operand" "")
16966                    (match_operand 4 "" ""))
16967               (set (match_operand 2 "memory_operand" "") (const_int 0))
16968               (use (match_operand 3 "register_operand" ""))
16969               (use (match_dup 1))
16970               (use (reg:SI DIRFLAG_REG))])]
16971   ""
16972   "")
16973
16974 (define_insn "*rep_stosdi_rex64"
16975   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16976    (set (match_operand:DI 0 "register_operand" "=D") 
16977         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16978                             (const_int 3))
16979                  (match_operand:DI 3 "register_operand" "0")))
16980    (set (mem:BLK (match_dup 3))
16981         (const_int 0))
16982    (use (match_operand:DI 2 "register_operand" "a"))
16983    (use (match_dup 4))
16984    (use (reg:SI DIRFLAG_REG))]
16985   "TARGET_64BIT"
16986   "{rep\;stosq|rep stosq}"
16987   [(set_attr "type" "str")
16988    (set_attr "prefix_rep" "1")
16989    (set_attr "memory" "store")
16990    (set_attr "mode" "DI")])
16991
16992 (define_insn "*rep_stossi"
16993   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16994    (set (match_operand:SI 0 "register_operand" "=D") 
16995         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16996                             (const_int 2))
16997                  (match_operand:SI 3 "register_operand" "0")))
16998    (set (mem:BLK (match_dup 3))
16999         (const_int 0))
17000    (use (match_operand:SI 2 "register_operand" "a"))
17001    (use (match_dup 4))
17002    (use (reg:SI DIRFLAG_REG))]
17003   "!TARGET_64BIT"
17004   "{rep\;stosl|rep stosd}"
17005   [(set_attr "type" "str")
17006    (set_attr "prefix_rep" "1")
17007    (set_attr "memory" "store")
17008    (set_attr "mode" "SI")])
17009
17010 (define_insn "*rep_stossi_rex64"
17011   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17012    (set (match_operand:DI 0 "register_operand" "=D") 
17013         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17014                             (const_int 2))
17015                  (match_operand:DI 3 "register_operand" "0")))
17016    (set (mem:BLK (match_dup 3))
17017         (const_int 0))
17018    (use (match_operand:SI 2 "register_operand" "a"))
17019    (use (match_dup 4))
17020    (use (reg:SI DIRFLAG_REG))]
17021   "TARGET_64BIT"
17022   "{rep\;stosl|rep stosd}"
17023   [(set_attr "type" "str")
17024    (set_attr "prefix_rep" "1")
17025    (set_attr "memory" "store")
17026    (set_attr "mode" "SI")])
17027
17028 (define_insn "*rep_stosqi"
17029   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17030    (set (match_operand:SI 0 "register_operand" "=D") 
17031         (plus:SI (match_operand:SI 3 "register_operand" "0")
17032                  (match_operand:SI 4 "register_operand" "1")))
17033    (set (mem:BLK (match_dup 3))
17034         (const_int 0))
17035    (use (match_operand:QI 2 "register_operand" "a"))
17036    (use (match_dup 4))
17037    (use (reg:SI DIRFLAG_REG))]
17038   "!TARGET_64BIT"
17039   "{rep\;stosb|rep stosb}"
17040   [(set_attr "type" "str")
17041    (set_attr "prefix_rep" "1")
17042    (set_attr "memory" "store")
17043    (set_attr "mode" "QI")])
17044
17045 (define_insn "*rep_stosqi_rex64"
17046   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17047    (set (match_operand:DI 0 "register_operand" "=D") 
17048         (plus:DI (match_operand:DI 3 "register_operand" "0")
17049                  (match_operand:DI 4 "register_operand" "1")))
17050    (set (mem:BLK (match_dup 3))
17051         (const_int 0))
17052    (use (match_operand:QI 2 "register_operand" "a"))
17053    (use (match_dup 4))
17054    (use (reg:SI DIRFLAG_REG))]
17055   "TARGET_64BIT"
17056   "{rep\;stosb|rep stosb}"
17057   [(set_attr "type" "str")
17058    (set_attr "prefix_rep" "1")
17059    (set_attr "memory" "store")
17060    (set_attr "mode" "QI")])
17061
17062 (define_expand "cmpstrsi"
17063   [(set (match_operand:SI 0 "register_operand" "")
17064         (compare:SI (match_operand:BLK 1 "general_operand" "")
17065                     (match_operand:BLK 2 "general_operand" "")))
17066    (use (match_operand 3 "general_operand" ""))
17067    (use (match_operand 4 "immediate_operand" ""))]
17068   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17069 {
17070   rtx addr1, addr2, out, outlow, count, countreg, align;
17071
17072   /* Can't use this if the user has appropriated esi or edi.  */
17073   if (global_regs[4] || global_regs[5])
17074     FAIL;
17075
17076   out = operands[0];
17077   if (GET_CODE (out) != REG)
17078     out = gen_reg_rtx (SImode);
17079
17080   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17081   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17082   if (addr1 != XEXP (operands[1], 0))
17083     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17084   if (addr2 != XEXP (operands[2], 0))
17085     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17086
17087   count = operands[3];
17088   countreg = ix86_zero_extend_to_Pmode (count);
17089
17090   /* %%% Iff we are testing strict equality, we can use known alignment
17091      to good advantage.  This may be possible with combine, particularly
17092      once cc0 is dead.  */
17093   align = operands[4];
17094
17095   emit_insn (gen_cld ());
17096   if (GET_CODE (count) == CONST_INT)
17097     {
17098       if (INTVAL (count) == 0)
17099         {
17100           emit_move_insn (operands[0], const0_rtx);
17101           DONE;
17102         }
17103       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17104                                     operands[1], operands[2]));
17105     }
17106   else
17107     {
17108       if (TARGET_64BIT)
17109         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17110       else
17111         emit_insn (gen_cmpsi_1 (countreg, countreg));
17112       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17113                                  operands[1], operands[2]));
17114     }
17115
17116   outlow = gen_lowpart (QImode, out);
17117   emit_insn (gen_cmpintqi (outlow));
17118   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17119
17120   if (operands[0] != out)
17121     emit_move_insn (operands[0], out);
17122
17123   DONE;
17124 })
17125
17126 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17127
17128 (define_expand "cmpintqi"
17129   [(set (match_dup 1)
17130         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17131    (set (match_dup 2)
17132         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17133    (parallel [(set (match_operand:QI 0 "register_operand" "")
17134                    (minus:QI (match_dup 1)
17135                              (match_dup 2)))
17136               (clobber (reg:CC FLAGS_REG))])]
17137   ""
17138   "operands[1] = gen_reg_rtx (QImode);
17139    operands[2] = gen_reg_rtx (QImode);")
17140
17141 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17142 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17143
17144 (define_expand "cmpstrqi_nz_1"
17145   [(parallel [(set (reg:CC FLAGS_REG)
17146                    (compare:CC (match_operand 4 "memory_operand" "")
17147                                (match_operand 5 "memory_operand" "")))
17148               (use (match_operand 2 "register_operand" ""))
17149               (use (match_operand:SI 3 "immediate_operand" ""))
17150               (use (reg:SI DIRFLAG_REG))
17151               (clobber (match_operand 0 "register_operand" ""))
17152               (clobber (match_operand 1 "register_operand" ""))
17153               (clobber (match_dup 2))])]
17154   ""
17155   "")
17156
17157 (define_insn "*cmpstrqi_nz_1"
17158   [(set (reg:CC FLAGS_REG)
17159         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17160                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17161    (use (match_operand:SI 6 "register_operand" "2"))
17162    (use (match_operand:SI 3 "immediate_operand" "i"))
17163    (use (reg:SI DIRFLAG_REG))
17164    (clobber (match_operand:SI 0 "register_operand" "=S"))
17165    (clobber (match_operand:SI 1 "register_operand" "=D"))
17166    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17167   "!TARGET_64BIT"
17168   "repz{\;| }cmpsb"
17169   [(set_attr "type" "str")
17170    (set_attr "mode" "QI")
17171    (set_attr "prefix_rep" "1")])
17172
17173 (define_insn "*cmpstrqi_nz_rex_1"
17174   [(set (reg:CC FLAGS_REG)
17175         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17176                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17177    (use (match_operand:DI 6 "register_operand" "2"))
17178    (use (match_operand:SI 3 "immediate_operand" "i"))
17179    (use (reg:SI DIRFLAG_REG))
17180    (clobber (match_operand:DI 0 "register_operand" "=S"))
17181    (clobber (match_operand:DI 1 "register_operand" "=D"))
17182    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17183   "TARGET_64BIT"
17184   "repz{\;| }cmpsb"
17185   [(set_attr "type" "str")
17186    (set_attr "mode" "QI")
17187    (set_attr "prefix_rep" "1")])
17188
17189 ;; The same, but the count is not known to not be zero.
17190
17191 (define_expand "cmpstrqi_1"
17192   [(parallel [(set (reg:CC FLAGS_REG)
17193                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17194                                      (const_int 0))
17195                   (compare:CC (match_operand 4 "memory_operand" "")
17196                               (match_operand 5 "memory_operand" ""))
17197                   (const_int 0)))
17198               (use (match_operand:SI 3 "immediate_operand" ""))
17199               (use (reg:CC FLAGS_REG))
17200               (use (reg:SI DIRFLAG_REG))
17201               (clobber (match_operand 0 "register_operand" ""))
17202               (clobber (match_operand 1 "register_operand" ""))
17203               (clobber (match_dup 2))])]
17204   ""
17205   "")
17206
17207 (define_insn "*cmpstrqi_1"
17208   [(set (reg:CC FLAGS_REG)
17209         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17210                              (const_int 0))
17211           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17212                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17213           (const_int 0)))
17214    (use (match_operand:SI 3 "immediate_operand" "i"))
17215    (use (reg:CC FLAGS_REG))
17216    (use (reg:SI DIRFLAG_REG))
17217    (clobber (match_operand:SI 0 "register_operand" "=S"))
17218    (clobber (match_operand:SI 1 "register_operand" "=D"))
17219    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17220   "!TARGET_64BIT"
17221   "repz{\;| }cmpsb"
17222   [(set_attr "type" "str")
17223    (set_attr "mode" "QI")
17224    (set_attr "prefix_rep" "1")])
17225
17226 (define_insn "*cmpstrqi_rex_1"
17227   [(set (reg:CC FLAGS_REG)
17228         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17229                              (const_int 0))
17230           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17231                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17232           (const_int 0)))
17233    (use (match_operand:SI 3 "immediate_operand" "i"))
17234    (use (reg:CC FLAGS_REG))
17235    (use (reg:SI DIRFLAG_REG))
17236    (clobber (match_operand:DI 0 "register_operand" "=S"))
17237    (clobber (match_operand:DI 1 "register_operand" "=D"))
17238    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17239   "TARGET_64BIT"
17240   "repz{\;| }cmpsb"
17241   [(set_attr "type" "str")
17242    (set_attr "mode" "QI")
17243    (set_attr "prefix_rep" "1")])
17244
17245 (define_expand "strlensi"
17246   [(set (match_operand:SI 0 "register_operand" "")
17247         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17248                     (match_operand:QI 2 "immediate_operand" "")
17249                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17250   ""
17251 {
17252  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17253    DONE;
17254  else
17255    FAIL;
17256 })
17257
17258 (define_expand "strlendi"
17259   [(set (match_operand:DI 0 "register_operand" "")
17260         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17261                     (match_operand:QI 2 "immediate_operand" "")
17262                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17263   ""
17264 {
17265  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17266    DONE;
17267  else
17268    FAIL;
17269 })
17270
17271 (define_expand "strlenqi_1"
17272   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17273               (use (reg:SI DIRFLAG_REG))
17274               (clobber (match_operand 1 "register_operand" ""))
17275               (clobber (reg:CC FLAGS_REG))])]
17276   ""
17277   "")
17278
17279 (define_insn "*strlenqi_1"
17280   [(set (match_operand:SI 0 "register_operand" "=&c")
17281         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17282                     (match_operand:QI 2 "register_operand" "a")
17283                     (match_operand:SI 3 "immediate_operand" "i")
17284                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17285    (use (reg:SI DIRFLAG_REG))
17286    (clobber (match_operand:SI 1 "register_operand" "=D"))
17287    (clobber (reg:CC FLAGS_REG))]
17288   "!TARGET_64BIT"
17289   "repnz{\;| }scasb"
17290   [(set_attr "type" "str")
17291    (set_attr "mode" "QI")
17292    (set_attr "prefix_rep" "1")])
17293
17294 (define_insn "*strlenqi_rex_1"
17295   [(set (match_operand:DI 0 "register_operand" "=&c")
17296         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17297                     (match_operand:QI 2 "register_operand" "a")
17298                     (match_operand:DI 3 "immediate_operand" "i")
17299                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17300    (use (reg:SI DIRFLAG_REG))
17301    (clobber (match_operand:DI 1 "register_operand" "=D"))
17302    (clobber (reg:CC FLAGS_REG))]
17303   "TARGET_64BIT"
17304   "repnz{\;| }scasb"
17305   [(set_attr "type" "str")
17306    (set_attr "mode" "QI")
17307    (set_attr "prefix_rep" "1")])
17308
17309 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17310 ;; handled in combine, but it is not currently up to the task.
17311 ;; When used for their truth value, the cmpstr* expanders generate
17312 ;; code like this:
17313 ;;
17314 ;;   repz cmpsb
17315 ;;   seta       %al
17316 ;;   setb       %dl
17317 ;;   cmpb       %al, %dl
17318 ;;   jcc        label
17319 ;;
17320 ;; The intermediate three instructions are unnecessary.
17321
17322 ;; This one handles cmpstr*_nz_1...
17323 (define_peephole2
17324   [(parallel[
17325      (set (reg:CC FLAGS_REG)
17326           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17327                       (mem:BLK (match_operand 5 "register_operand" ""))))
17328      (use (match_operand 6 "register_operand" ""))
17329      (use (match_operand:SI 3 "immediate_operand" ""))
17330      (use (reg:SI DIRFLAG_REG))
17331      (clobber (match_operand 0 "register_operand" ""))
17332      (clobber (match_operand 1 "register_operand" ""))
17333      (clobber (match_operand 2 "register_operand" ""))])
17334    (set (match_operand:QI 7 "register_operand" "")
17335         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17336    (set (match_operand:QI 8 "register_operand" "")
17337         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17338    (set (reg FLAGS_REG)
17339         (compare (match_dup 7) (match_dup 8)))
17340   ]
17341   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17342   [(parallel[
17343      (set (reg:CC FLAGS_REG)
17344           (compare:CC (mem:BLK (match_dup 4))
17345                       (mem:BLK (match_dup 5))))
17346      (use (match_dup 6))
17347      (use (match_dup 3))
17348      (use (reg:SI DIRFLAG_REG))
17349      (clobber (match_dup 0))
17350      (clobber (match_dup 1))
17351      (clobber (match_dup 2))])]
17352   "")
17353
17354 ;; ...and this one handles cmpstr*_1.
17355 (define_peephole2
17356   [(parallel[
17357      (set (reg:CC FLAGS_REG)
17358           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17359                                (const_int 0))
17360             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17361                         (mem:BLK (match_operand 5 "register_operand" "")))
17362             (const_int 0)))
17363      (use (match_operand:SI 3 "immediate_operand" ""))
17364      (use (reg:CC FLAGS_REG))
17365      (use (reg:SI DIRFLAG_REG))
17366      (clobber (match_operand 0 "register_operand" ""))
17367      (clobber (match_operand 1 "register_operand" ""))
17368      (clobber (match_operand 2 "register_operand" ""))])
17369    (set (match_operand:QI 7 "register_operand" "")
17370         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17371    (set (match_operand:QI 8 "register_operand" "")
17372         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17373    (set (reg FLAGS_REG)
17374         (compare (match_dup 7) (match_dup 8)))
17375   ]
17376   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17377   [(parallel[
17378      (set (reg:CC FLAGS_REG)
17379           (if_then_else:CC (ne (match_dup 6)
17380                                (const_int 0))
17381             (compare:CC (mem:BLK (match_dup 4))
17382                         (mem:BLK (match_dup 5)))
17383             (const_int 0)))
17384      (use (match_dup 3))
17385      (use (reg:CC FLAGS_REG))
17386      (use (reg:SI DIRFLAG_REG))
17387      (clobber (match_dup 0))
17388      (clobber (match_dup 1))
17389      (clobber (match_dup 2))])]
17390   "")
17391
17392
17393 \f
17394 ;; Conditional move instructions.
17395
17396 (define_expand "movdicc"
17397   [(set (match_operand:DI 0 "register_operand" "")
17398         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17399                          (match_operand:DI 2 "general_operand" "")
17400                          (match_operand:DI 3 "general_operand" "")))]
17401   "TARGET_64BIT"
17402   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17403
17404 (define_insn "x86_movdicc_0_m1_rex64"
17405   [(set (match_operand:DI 0 "register_operand" "=r")
17406         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17407           (const_int -1)
17408           (const_int 0)))
17409    (clobber (reg:CC FLAGS_REG))]
17410   "TARGET_64BIT"
17411   "sbb{q}\t%0, %0"
17412   ; Since we don't have the proper number of operands for an alu insn,
17413   ; fill in all the blanks.
17414   [(set_attr "type" "alu")
17415    (set_attr "pent_pair" "pu")
17416    (set_attr "memory" "none")
17417    (set_attr "imm_disp" "false")
17418    (set_attr "mode" "DI")
17419    (set_attr "length_immediate" "0")])
17420
17421 (define_insn "movdicc_c_rex64"
17422   [(set (match_operand:DI 0 "register_operand" "=r,r")
17423         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17424                                 [(reg FLAGS_REG) (const_int 0)])
17425                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17426                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17427   "TARGET_64BIT && TARGET_CMOVE
17428    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17429   "@
17430    cmov%O2%C1\t{%2, %0|%0, %2}
17431    cmov%O2%c1\t{%3, %0|%0, %3}"
17432   [(set_attr "type" "icmov")
17433    (set_attr "mode" "DI")])
17434
17435 (define_expand "movsicc"
17436   [(set (match_operand:SI 0 "register_operand" "")
17437         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17438                          (match_operand:SI 2 "general_operand" "")
17439                          (match_operand:SI 3 "general_operand" "")))]
17440   ""
17441   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17442
17443 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17444 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17445 ;; So just document what we're doing explicitly.
17446
17447 (define_insn "x86_movsicc_0_m1"
17448   [(set (match_operand:SI 0 "register_operand" "=r")
17449         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17450           (const_int -1)
17451           (const_int 0)))
17452    (clobber (reg:CC FLAGS_REG))]
17453   ""
17454   "sbb{l}\t%0, %0"
17455   ; Since we don't have the proper number of operands for an alu insn,
17456   ; fill in all the blanks.
17457   [(set_attr "type" "alu")
17458    (set_attr "pent_pair" "pu")
17459    (set_attr "memory" "none")
17460    (set_attr "imm_disp" "false")
17461    (set_attr "mode" "SI")
17462    (set_attr "length_immediate" "0")])
17463
17464 (define_insn "*movsicc_noc"
17465   [(set (match_operand:SI 0 "register_operand" "=r,r")
17466         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17467                                 [(reg FLAGS_REG) (const_int 0)])
17468                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17469                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17470   "TARGET_CMOVE
17471    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17472   "@
17473    cmov%O2%C1\t{%2, %0|%0, %2}
17474    cmov%O2%c1\t{%3, %0|%0, %3}"
17475   [(set_attr "type" "icmov")
17476    (set_attr "mode" "SI")])
17477
17478 (define_expand "movhicc"
17479   [(set (match_operand:HI 0 "register_operand" "")
17480         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17481                          (match_operand:HI 2 "general_operand" "")
17482                          (match_operand:HI 3 "general_operand" "")))]
17483   "TARGET_HIMODE_MATH"
17484   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17485
17486 (define_insn "*movhicc_noc"
17487   [(set (match_operand:HI 0 "register_operand" "=r,r")
17488         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17489                                 [(reg FLAGS_REG) (const_int 0)])
17490                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17491                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17492   "TARGET_CMOVE
17493    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17494   "@
17495    cmov%O2%C1\t{%2, %0|%0, %2}
17496    cmov%O2%c1\t{%3, %0|%0, %3}"
17497   [(set_attr "type" "icmov")
17498    (set_attr "mode" "HI")])
17499
17500 (define_expand "movqicc"
17501   [(set (match_operand:QI 0 "register_operand" "")
17502         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17503                          (match_operand:QI 2 "general_operand" "")
17504                          (match_operand:QI 3 "general_operand" "")))]
17505   "TARGET_QIMODE_MATH"
17506   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17507
17508 (define_insn_and_split "*movqicc_noc"
17509   [(set (match_operand:QI 0 "register_operand" "=r,r")
17510         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17511                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17512                       (match_operand:QI 2 "register_operand" "r,0")
17513                       (match_operand:QI 3 "register_operand" "0,r")))]
17514   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17515   "#"
17516   "&& reload_completed"
17517   [(set (match_dup 0)
17518         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17519                       (match_dup 2)
17520                       (match_dup 3)))]
17521   "operands[0] = gen_lowpart (SImode, operands[0]);
17522    operands[2] = gen_lowpart (SImode, operands[2]);
17523    operands[3] = gen_lowpart (SImode, operands[3]);"
17524   [(set_attr "type" "icmov")
17525    (set_attr "mode" "SI")])
17526
17527 (define_expand "movsfcc"
17528   [(set (match_operand:SF 0 "register_operand" "")
17529         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17530                          (match_operand:SF 2 "register_operand" "")
17531                          (match_operand:SF 3 "register_operand" "")))]
17532   "TARGET_CMOVE"
17533   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17534
17535 (define_insn "*movsfcc_1"
17536   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17537         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17538                                 [(reg FLAGS_REG) (const_int 0)])
17539                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17540                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17541   "TARGET_CMOVE
17542    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17543   "@
17544    fcmov%F1\t{%2, %0|%0, %2}
17545    fcmov%f1\t{%3, %0|%0, %3}
17546    cmov%O2%C1\t{%2, %0|%0, %2}
17547    cmov%O2%c1\t{%3, %0|%0, %3}"
17548   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17549    (set_attr "mode" "SF,SF,SI,SI")])
17550
17551 (define_expand "movdfcc"
17552   [(set (match_operand:DF 0 "register_operand" "")
17553         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17554                          (match_operand:DF 2 "register_operand" "")
17555                          (match_operand:DF 3 "register_operand" "")))]
17556   "TARGET_CMOVE"
17557   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17558
17559 (define_insn "*movdfcc_1"
17560   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17561         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17562                                 [(reg FLAGS_REG) (const_int 0)])
17563                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17564                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17565   "!TARGET_64BIT && TARGET_CMOVE
17566    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17567   "@
17568    fcmov%F1\t{%2, %0|%0, %2}
17569    fcmov%f1\t{%3, %0|%0, %3}
17570    #
17571    #"
17572   [(set_attr "type" "fcmov,fcmov,multi,multi")
17573    (set_attr "mode" "DF")])
17574
17575 (define_insn "*movdfcc_1_rex64"
17576   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17577         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17578                                 [(reg FLAGS_REG) (const_int 0)])
17579                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17580                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17581   "TARGET_64BIT && TARGET_CMOVE
17582    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17583   "@
17584    fcmov%F1\t{%2, %0|%0, %2}
17585    fcmov%f1\t{%3, %0|%0, %3}
17586    cmov%O2%C1\t{%2, %0|%0, %2}
17587    cmov%O2%c1\t{%3, %0|%0, %3}"
17588   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17589    (set_attr "mode" "DF")])
17590
17591 (define_split
17592   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17593         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17594                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17595                       (match_operand:DF 2 "nonimmediate_operand" "")
17596                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17597   "!TARGET_64BIT && reload_completed"
17598   [(set (match_dup 2)
17599         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17600                       (match_dup 5)
17601                       (match_dup 7)))
17602    (set (match_dup 3)
17603         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17604                       (match_dup 6)
17605                       (match_dup 8)))]
17606   "split_di (operands+2, 1, operands+5, operands+6);
17607    split_di (operands+3, 1, operands+7, operands+8);
17608    split_di (operands, 1, operands+2, operands+3);")
17609
17610 (define_expand "movxfcc"
17611   [(set (match_operand:XF 0 "register_operand" "")
17612         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17613                          (match_operand:XF 2 "register_operand" "")
17614                          (match_operand:XF 3 "register_operand" "")))]
17615   "TARGET_CMOVE"
17616   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17617
17618 (define_insn "*movxfcc_1"
17619   [(set (match_operand:XF 0 "register_operand" "=f,f")
17620         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17621                                 [(reg FLAGS_REG) (const_int 0)])
17622                       (match_operand:XF 2 "register_operand" "f,0")
17623                       (match_operand:XF 3 "register_operand" "0,f")))]
17624   "TARGET_CMOVE"
17625   "@
17626    fcmov%F1\t{%2, %0|%0, %2}
17627    fcmov%f1\t{%3, %0|%0, %3}"
17628   [(set_attr "type" "fcmov")
17629    (set_attr "mode" "XF")])
17630
17631 (define_expand "minsf3"
17632   [(parallel [
17633      (set (match_operand:SF 0 "register_operand" "")
17634           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17635                                (match_operand:SF 2 "nonimmediate_operand" ""))
17636                            (match_dup 1)
17637                            (match_dup 2)))
17638      (clobber (reg:CC FLAGS_REG))])]
17639   "TARGET_SSE"
17640   "")
17641
17642 (define_insn "*minsf"
17643   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17644         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17645                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17646                          (match_dup 1)
17647                          (match_dup 2)))
17648    (clobber (reg:CC FLAGS_REG))]
17649   "TARGET_SSE && TARGET_IEEE_FP"
17650   "#")
17651
17652 (define_insn "*minsf_nonieee"
17653   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17654         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17655                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17656                          (match_dup 1)
17657                          (match_dup 2)))
17658    (clobber (reg:CC FLAGS_REG))]
17659   "TARGET_SSE && !TARGET_IEEE_FP
17660    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17661   "#")
17662
17663 (define_split
17664   [(set (match_operand:SF 0 "register_operand" "")
17665         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17666                              (match_operand:SF 2 "nonimmediate_operand" ""))
17667                          (match_operand:SF 3 "register_operand" "")
17668                          (match_operand:SF 4 "nonimmediate_operand" "")))
17669    (clobber (reg:CC FLAGS_REG))]
17670   "SSE_REG_P (operands[0]) && reload_completed
17671    && ((operands_match_p (operands[1], operands[3])
17672         && operands_match_p (operands[2], operands[4]))
17673        || (operands_match_p (operands[1], operands[4])
17674            && operands_match_p (operands[2], operands[3])))"
17675   [(set (match_dup 0)
17676         (if_then_else:SF (lt (match_dup 1)
17677                              (match_dup 2))
17678                          (match_dup 1)
17679                          (match_dup 2)))])
17680
17681 ;; Conditional addition patterns
17682 (define_expand "addqicc"
17683   [(match_operand:QI 0 "register_operand" "")
17684    (match_operand 1 "comparison_operator" "")
17685    (match_operand:QI 2 "register_operand" "")
17686    (match_operand:QI 3 "const_int_operand" "")]
17687   ""
17688   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17689
17690 (define_expand "addhicc"
17691   [(match_operand:HI 0 "register_operand" "")
17692    (match_operand 1 "comparison_operator" "")
17693    (match_operand:HI 2 "register_operand" "")
17694    (match_operand:HI 3 "const_int_operand" "")]
17695   ""
17696   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17697
17698 (define_expand "addsicc"
17699   [(match_operand:SI 0 "register_operand" "")
17700    (match_operand 1 "comparison_operator" "")
17701    (match_operand:SI 2 "register_operand" "")
17702    (match_operand:SI 3 "const_int_operand" "")]
17703   ""
17704   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17705
17706 (define_expand "adddicc"
17707   [(match_operand:DI 0 "register_operand" "")
17708    (match_operand 1 "comparison_operator" "")
17709    (match_operand:DI 2 "register_operand" "")
17710    (match_operand:DI 3 "const_int_operand" "")]
17711   "TARGET_64BIT"
17712   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17713
17714 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17715
17716 (define_split
17717   [(set (match_operand:SF 0 "fp_register_operand" "")
17718         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17719                              (match_operand:SF 2 "register_operand" ""))
17720                          (match_operand:SF 3 "register_operand" "")
17721                          (match_operand:SF 4 "register_operand" "")))
17722    (clobber (reg:CC FLAGS_REG))]
17723   "reload_completed
17724    && ((operands_match_p (operands[1], operands[3])
17725         && operands_match_p (operands[2], operands[4]))
17726        || (operands_match_p (operands[1], operands[4])
17727            && operands_match_p (operands[2], operands[3])))"
17728   [(set (reg:CCFP FLAGS_REG)
17729         (compare:CCFP (match_dup 2)
17730                       (match_dup 1)))
17731    (set (match_dup 0)
17732         (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17733                          (match_dup 1)
17734                          (match_dup 2)))])
17735
17736 (define_insn "*minsf_sse"
17737   [(set (match_operand:SF 0 "register_operand" "=x")
17738         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17739                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17740                          (match_dup 1)
17741                          (match_dup 2)))]
17742   "TARGET_SSE && reload_completed"
17743   "minss\t{%2, %0|%0, %2}"
17744   [(set_attr "type" "sse")
17745    (set_attr "mode" "SF")])
17746
17747 (define_expand "mindf3"
17748   [(parallel [
17749      (set (match_operand:DF 0 "register_operand" "")
17750           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17751                                (match_operand:DF 2 "nonimmediate_operand" ""))
17752                            (match_dup 1)
17753                            (match_dup 2)))
17754      (clobber (reg:CC FLAGS_REG))])]
17755   "TARGET_SSE2 && TARGET_SSE_MATH"
17756   "#")
17757
17758 (define_insn "*mindf"
17759   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17760         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17761                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17762                          (match_dup 1)
17763                          (match_dup 2)))
17764    (clobber (reg:CC FLAGS_REG))]
17765   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17766   "#")
17767
17768 (define_insn "*mindf_nonieee"
17769   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17770         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17771                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17772                          (match_dup 1)
17773                          (match_dup 2)))
17774    (clobber (reg:CC FLAGS_REG))]
17775   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17776    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17777   "#")
17778
17779 (define_split
17780   [(set (match_operand:DF 0 "register_operand" "")
17781         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17782                              (match_operand:DF 2 "nonimmediate_operand" ""))
17783                          (match_operand:DF 3 "register_operand" "")
17784                          (match_operand:DF 4 "nonimmediate_operand" "")))
17785    (clobber (reg:CC FLAGS_REG))]
17786   "SSE_REG_P (operands[0]) && reload_completed
17787    && ((operands_match_p (operands[1], operands[3])
17788         && operands_match_p (operands[2], operands[4]))
17789        || (operands_match_p (operands[1], operands[4])
17790            && operands_match_p (operands[2], operands[3])))"
17791   [(set (match_dup 0)
17792         (if_then_else:DF (lt (match_dup 1)
17793                              (match_dup 2))
17794                          (match_dup 1)
17795                          (match_dup 2)))])
17796
17797 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17798 (define_split
17799   [(set (match_operand:DF 0 "fp_register_operand" "")
17800         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17801                              (match_operand:DF 2 "register_operand" ""))
17802                          (match_operand:DF 3 "register_operand" "")
17803                          (match_operand:DF 4 "register_operand" "")))
17804    (clobber (reg:CC FLAGS_REG))]
17805   "reload_completed
17806    && ((operands_match_p (operands[1], operands[3])
17807         && operands_match_p (operands[2], operands[4]))
17808        || (operands_match_p (operands[1], operands[4])
17809            && operands_match_p (operands[2], operands[3])))"
17810   [(set (reg:CCFP FLAGS_REG)
17811         (compare:CCFP (match_dup 2)
17812                       (match_dup 1)))
17813    (set (match_dup 0)
17814         (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17815                          (match_dup 1)
17816                          (match_dup 2)))])
17817
17818 (define_insn "*mindf_sse"
17819   [(set (match_operand:DF 0 "register_operand" "=Y")
17820         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17821                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17822                          (match_dup 1)
17823                          (match_dup 2)))]
17824   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17825   "minsd\t{%2, %0|%0, %2}"
17826   [(set_attr "type" "sse")
17827    (set_attr "mode" "DF")])
17828
17829 (define_expand "maxsf3"
17830   [(parallel [
17831      (set (match_operand:SF 0 "register_operand" "")
17832           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17833                                (match_operand:SF 2 "nonimmediate_operand" ""))
17834                            (match_dup 1)
17835                            (match_dup 2)))
17836      (clobber (reg:CC FLAGS_REG))])]
17837   "TARGET_SSE"
17838   "#")
17839
17840 (define_insn "*maxsf"
17841   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17842         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17843                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17844                          (match_dup 1)
17845                          (match_dup 2)))
17846    (clobber (reg:CC FLAGS_REG))]
17847   "TARGET_SSE && TARGET_IEEE_FP"
17848   "#")
17849
17850 (define_insn "*maxsf_nonieee"
17851   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17852         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17853                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17854                          (match_dup 1)
17855                          (match_dup 2)))
17856    (clobber (reg:CC FLAGS_REG))]
17857   "TARGET_SSE && !TARGET_IEEE_FP
17858    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17859   "#")
17860
17861 (define_split
17862   [(set (match_operand:SF 0 "register_operand" "")
17863         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17864                              (match_operand:SF 2 "nonimmediate_operand" ""))
17865                          (match_operand:SF 3 "register_operand" "")
17866                          (match_operand:SF 4 "nonimmediate_operand" "")))
17867    (clobber (reg:CC FLAGS_REG))]
17868   "SSE_REG_P (operands[0]) && reload_completed
17869    && ((operands_match_p (operands[1], operands[3])
17870         && operands_match_p (operands[2], operands[4]))
17871        || (operands_match_p (operands[1], operands[4])
17872            && operands_match_p (operands[2], operands[3])))"
17873   [(set (match_dup 0)
17874         (if_then_else:SF (gt (match_dup 1)
17875                              (match_dup 2))
17876                          (match_dup 1)
17877                          (match_dup 2)))])
17878
17879 (define_split
17880   [(set (match_operand:SF 0 "fp_register_operand" "")
17881         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17882                              (match_operand:SF 2 "register_operand" ""))
17883                          (match_operand:SF 3 "register_operand" "")
17884                          (match_operand:SF 4 "register_operand" "")))
17885    (clobber (reg:CC FLAGS_REG))]
17886   "reload_completed
17887    && ((operands_match_p (operands[1], operands[3])
17888         && operands_match_p (operands[2], operands[4]))
17889        || (operands_match_p (operands[1], operands[4])
17890            && operands_match_p (operands[2], operands[3])))"
17891   [(set (reg:CCFP FLAGS_REG)
17892         (compare:CCFP (match_dup 1)
17893                       (match_dup 2)))
17894    (set (match_dup 0)
17895         (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17896                          (match_dup 1)
17897                          (match_dup 2)))])
17898
17899 (define_insn "*maxsf_sse"
17900   [(set (match_operand:SF 0 "register_operand" "=x")
17901         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17902                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17903                          (match_dup 1)
17904                          (match_dup 2)))]
17905   "TARGET_SSE && reload_completed"
17906   "maxss\t{%2, %0|%0, %2}"
17907   [(set_attr "type" "sse")
17908    (set_attr "mode" "SF")])
17909
17910 (define_expand "maxdf3"
17911   [(parallel [
17912      (set (match_operand:DF 0 "register_operand" "")
17913           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17914                                (match_operand:DF 2 "nonimmediate_operand" ""))
17915                            (match_dup 1)
17916                            (match_dup 2)))
17917      (clobber (reg:CC FLAGS_REG))])]
17918   "TARGET_SSE2 && TARGET_SSE_MATH"
17919   "#")
17920
17921 (define_insn "*maxdf"
17922   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17923         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17924                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17925                          (match_dup 1)
17926                          (match_dup 2)))
17927    (clobber (reg:CC FLAGS_REG))]
17928   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17929   "#")
17930
17931 (define_insn "*maxdf_nonieee"
17932   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17933         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17934                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17935                          (match_dup 1)
17936                          (match_dup 2)))
17937    (clobber (reg:CC FLAGS_REG))]
17938   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17939    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17940   "#")
17941
17942 (define_split
17943   [(set (match_operand:DF 0 "register_operand" "")
17944         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17945                              (match_operand:DF 2 "nonimmediate_operand" ""))
17946                          (match_operand:DF 3 "register_operand" "")
17947                          (match_operand:DF 4 "nonimmediate_operand" "")))
17948    (clobber (reg:CC FLAGS_REG))]
17949   "SSE_REG_P (operands[0]) && reload_completed
17950    && ((operands_match_p (operands[1], operands[3])
17951         && operands_match_p (operands[2], operands[4]))
17952        || (operands_match_p (operands[1], operands[4])
17953            && operands_match_p (operands[2], operands[3])))"
17954   [(set (match_dup 0)
17955         (if_then_else:DF (gt (match_dup 1)
17956                              (match_dup 2))
17957                          (match_dup 1)
17958                          (match_dup 2)))])
17959
17960 (define_split
17961   [(set (match_operand:DF 0 "fp_register_operand" "")
17962         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17963                              (match_operand:DF 2 "register_operand" ""))
17964                          (match_operand:DF 3 "register_operand" "")
17965                          (match_operand:DF 4 "register_operand" "")))
17966    (clobber (reg:CC FLAGS_REG))]
17967   "reload_completed
17968    && ((operands_match_p (operands[1], operands[3])
17969         && operands_match_p (operands[2], operands[4]))
17970        || (operands_match_p (operands[1], operands[4])
17971            && operands_match_p (operands[2], operands[3])))"
17972   [(set (reg:CCFP FLAGS_REG)
17973         (compare:CCFP (match_dup 1)
17974                       (match_dup 2)))
17975    (set (match_dup 0)
17976         (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17977                          (match_dup 1)
17978                          (match_dup 2)))])
17979
17980 (define_insn "*maxdf_sse"
17981   [(set (match_operand:DF 0 "register_operand" "=Y")
17982         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17983                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17984                          (match_dup 1)
17985                          (match_dup 2)))]
17986   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17987   "maxsd\t{%2, %0|%0, %2}"
17988   [(set_attr "type" "sse")
17989    (set_attr "mode" "DF")])
17990 \f
17991 ;; Misc patterns (?)
17992
17993 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17994 ;; Otherwise there will be nothing to keep
17995 ;; 
17996 ;; [(set (reg ebp) (reg esp))]
17997 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17998 ;;  (clobber (eflags)]
17999 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18000 ;;
18001 ;; in proper program order.
18002 (define_insn "pro_epilogue_adjust_stack_1"
18003   [(set (match_operand:SI 0 "register_operand" "=r,r")
18004         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18005                  (match_operand:SI 2 "immediate_operand" "i,i")))
18006    (clobber (reg:CC FLAGS_REG))
18007    (clobber (mem:BLK (scratch)))]
18008   "!TARGET_64BIT"
18009 {
18010   switch (get_attr_type (insn))
18011     {
18012     case TYPE_IMOV:
18013       return "mov{l}\t{%1, %0|%0, %1}";
18014
18015     case TYPE_ALU:
18016       if (GET_CODE (operands[2]) == CONST_INT
18017           && (INTVAL (operands[2]) == 128
18018               || (INTVAL (operands[2]) < 0
18019                   && INTVAL (operands[2]) != -128)))
18020         {
18021           operands[2] = GEN_INT (-INTVAL (operands[2]));
18022           return "sub{l}\t{%2, %0|%0, %2}";
18023         }
18024       return "add{l}\t{%2, %0|%0, %2}";
18025
18026     case TYPE_LEA:
18027       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18028       return "lea{l}\t{%a2, %0|%0, %a2}";
18029
18030     default:
18031       abort ();
18032     }
18033 }
18034   [(set (attr "type")
18035         (cond [(eq_attr "alternative" "0")
18036                  (const_string "alu")
18037                (match_operand:SI 2 "const0_operand" "")
18038                  (const_string "imov")
18039               ]
18040               (const_string "lea")))
18041    (set_attr "mode" "SI")])
18042
18043 (define_insn "pro_epilogue_adjust_stack_rex64"
18044   [(set (match_operand:DI 0 "register_operand" "=r,r")
18045         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18046                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18047    (clobber (reg:CC FLAGS_REG))
18048    (clobber (mem:BLK (scratch)))]
18049   "TARGET_64BIT"
18050 {
18051   switch (get_attr_type (insn))
18052     {
18053     case TYPE_IMOV:
18054       return "mov{q}\t{%1, %0|%0, %1}";
18055
18056     case TYPE_ALU:
18057       if (GET_CODE (operands[2]) == CONST_INT
18058           /* Avoid overflows.  */
18059           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18060           && (INTVAL (operands[2]) == 128
18061               || (INTVAL (operands[2]) < 0
18062                   && INTVAL (operands[2]) != -128)))
18063         {
18064           operands[2] = GEN_INT (-INTVAL (operands[2]));
18065           return "sub{q}\t{%2, %0|%0, %2}";
18066         }
18067       return "add{q}\t{%2, %0|%0, %2}";
18068
18069     case TYPE_LEA:
18070       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18071       return "lea{q}\t{%a2, %0|%0, %a2}";
18072
18073     default:
18074       abort ();
18075     }
18076 }
18077   [(set (attr "type")
18078         (cond [(eq_attr "alternative" "0")
18079                  (const_string "alu")
18080                (match_operand:DI 2 "const0_operand" "")
18081                  (const_string "imov")
18082               ]
18083               (const_string "lea")))
18084    (set_attr "mode" "DI")])
18085
18086 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18087   [(set (match_operand:DI 0 "register_operand" "=r,r")
18088         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18089                  (match_operand:DI 3 "immediate_operand" "i,i")))
18090    (use (match_operand:DI 2 "register_operand" "r,r"))
18091    (clobber (reg:CC FLAGS_REG))
18092    (clobber (mem:BLK (scratch)))]
18093   "TARGET_64BIT"
18094 {
18095   switch (get_attr_type (insn))
18096     {
18097     case TYPE_ALU:
18098       return "add{q}\t{%2, %0|%0, %2}";
18099
18100     case TYPE_LEA:
18101       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18102       return "lea{q}\t{%a2, %0|%0, %a2}";
18103
18104     default:
18105       abort ();
18106     }
18107 }
18108   [(set_attr "type" "alu,lea")
18109    (set_attr "mode" "DI")])
18110
18111 ;; Placeholder for the conditional moves.  This one is split either to SSE
18112 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
18113 ;; fact is that compares supported by the cmp??ss instructions are exactly
18114 ;; swapped of those supported by cmove sequence.
18115 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18116 ;; supported by i387 comparisons and we do need to emit two conditional moves
18117 ;; in tandem.
18118
18119 (define_insn "sse_movsfcc"
18120   [(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")
18121         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18122                         [(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")
18123                          (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")])
18124                       (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")
18125                       (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")))
18126    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18127    (clobber (reg:CC FLAGS_REG))]
18128   "TARGET_SSE
18129    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18130    /* Avoid combine from being smart and converting min/max
18131       instruction patterns into conditional moves.  */
18132    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18133         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18134        || !rtx_equal_p (operands[4], operands[2])
18135        || !rtx_equal_p (operands[5], operands[3]))
18136    && (!TARGET_IEEE_FP
18137        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18138   "#")
18139
18140 (define_insn "sse_movsfcc_eq"
18141   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18142         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18143                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18144                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18145                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18146    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18147    (clobber (reg:CC FLAGS_REG))]
18148   "TARGET_SSE
18149    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18150   "#")
18151
18152 (define_insn "sse_movdfcc"
18153   [(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")
18154         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18155                         [(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")
18156                          (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")])
18157                       (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")
18158                       (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")))
18159    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18160    (clobber (reg:CC FLAGS_REG))]
18161   "TARGET_SSE2
18162    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18163    /* Avoid combine from being smart and converting min/max
18164       instruction patterns into conditional moves.  */
18165    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18166         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18167        || !rtx_equal_p (operands[4], operands[2])
18168        || !rtx_equal_p (operands[5], operands[3]))
18169    && (!TARGET_IEEE_FP
18170        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18171   "#")
18172
18173 (define_insn "sse_movdfcc_eq"
18174   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18175         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18176                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18177                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18178                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18179    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18180    (clobber (reg:CC FLAGS_REG))]
18181   "TARGET_SSE
18182    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18183   "#")
18184
18185 ;; For non-sse moves just expand the usual cmove sequence.
18186 (define_split
18187   [(set (match_operand 0 "register_operand" "")
18188         (if_then_else (match_operator 1 "comparison_operator"
18189                         [(match_operand 4 "nonimmediate_operand" "")
18190                          (match_operand 5 "register_operand" "")])
18191                       (match_operand 2 "nonimmediate_operand" "")
18192                       (match_operand 3 "nonimmediate_operand" "")))
18193    (clobber (match_operand 6 "" ""))
18194    (clobber (reg:CC FLAGS_REG))]
18195   "!SSE_REG_P (operands[0]) && reload_completed
18196    && (GET_MODE (operands[0]) == SFmode
18197        || (TARGET_SSE2 && GET_MODE (operands[0]) == DFmode))"
18198   [(const_int 0)]
18199 {
18200    ix86_compare_op0 = operands[5];
18201    ix86_compare_op1 = operands[4];
18202    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18203                                  VOIDmode, operands[5], operands[4]);
18204    ix86_expand_fp_movcc (operands);
18205    DONE;
18206 })
18207
18208 ;; Split SSE based conditional move into sequence:
18209 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
18210 ;; and   op2, op0   -  zero op2 if comparison was false
18211 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
18212 ;; or    op2, op0   -  get the nonzero one into the result.
18213 (define_split
18214   [(set (match_operand:SF 0 "register_operand" "")
18215         (if_then_else:SF (match_operator:SF 1 "sse_comparison_operator"
18216                            [(match_operand:SF 4 "register_operand" "")
18217                             (match_operand:SF 5 "nonimmediate_operand" "")])
18218                          (match_operand:SF 2 "register_operand" "")
18219                          (match_operand:SF 3 "register_operand" "")))
18220    (clobber (match_operand 6 "" ""))
18221    (clobber (reg:CC FLAGS_REG))]
18222   "SSE_REG_P (operands[0]) && reload_completed"
18223   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18224    (set (match_dup 2) (and:V4SF (match_dup 2)
18225                                 (match_dup 8)))
18226    (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18227                                           (match_dup 3)))
18228    (set (match_dup 0) (ior:V4SF (match_dup 6)
18229                                 (match_dup 7)))]
18230 {
18231   /* If op2 == op3, op3 would be clobbered before it is used.  */
18232   if (operands_match_p (operands[2], operands[3]))
18233     {
18234       emit_move_insn (operands[0], operands[2]);
18235       DONE;
18236     }
18237
18238   PUT_MODE (operands[1], GET_MODE (operands[0]));
18239   if (operands_match_p (operands[0], operands[4]))
18240     operands[6] = operands[4], operands[7] = operands[2];
18241   else
18242     operands[6] = operands[2], operands[7] = operands[4];
18243   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18244   operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18245   operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18246   operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18247   operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18248   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18249 })
18250
18251 (define_split
18252   [(set (match_operand:DF 0 "register_operand" "")
18253         (if_then_else:DF (match_operator:DF 1 "sse_comparison_operator"
18254                            [(match_operand:DF 4 "register_operand" "")
18255                             (match_operand:DF 5 "nonimmediate_operand" "")])
18256                          (match_operand:DF 2 "register_operand" "")
18257                          (match_operand:DF 3 "register_operand" "")))
18258    (clobber (match_operand 6 "" ""))
18259    (clobber (reg:CC FLAGS_REG))]
18260   "SSE_REG_P (operands[0]) && reload_completed"
18261   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18262    (set (match_dup 2) (and:V2DF (match_dup 2)
18263                                 (match_dup 8)))
18264    (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18265                                           (match_dup 3)))
18266    (set (match_dup 0) (ior:V2DF (match_dup 6)
18267                                 (match_dup 7)))]
18268 {
18269   if (GET_MODE (operands[2]) == DFmode
18270       && TARGET_SSE_PARTIAL_REGS && !optimize_size)
18271     {
18272       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18273       emit_insn (gen_sse2_unpcklpd (op, op, op));
18274       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18275       emit_insn (gen_sse2_unpcklpd (op, op, op));
18276     }
18277
18278   /* If op2 == op3, op3 would be clobbered before it is used.  */
18279   if (operands_match_p (operands[2], operands[3]))
18280     {
18281       emit_move_insn (operands[0], operands[2]);
18282       DONE;
18283     }
18284
18285   PUT_MODE (operands[1], GET_MODE (operands[0]));
18286   if (operands_match_p (operands[0], operands[4]))
18287     operands[6] = operands[4], operands[7] = operands[2];
18288   else
18289     operands[6] = operands[2], operands[7] = operands[4];
18290   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18291   operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18292   operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18293   operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18294   operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18295   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18296 })
18297
18298 ;; Special case of conditional move we can handle effectively.
18299 ;; Do not brother with the integer/floating point case, since these are
18300 ;; bot considerably slower, unlike in the generic case.
18301 (define_insn "*sse_movsfcc_const0_1"
18302   [(set (match_operand:SF 0 "register_operand" "=&x")
18303         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18304                         [(match_operand:SF 4 "register_operand" "0")
18305                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18306                       (match_operand:SF 2 "register_operand" "x")
18307                       (match_operand:SF 3 "const0_operand" "X")))]
18308   "TARGET_SSE"
18309   "#")
18310
18311 (define_insn "*sse_movsfcc_const0_2"
18312   [(set (match_operand:SF 0 "register_operand" "=&x")
18313         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18314                         [(match_operand:SF 4 "register_operand" "0")
18315                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18316                       (match_operand:SF 2 "const0_operand" "X")
18317                       (match_operand:SF 3 "register_operand" "x")))]
18318   "TARGET_SSE"
18319   "#")
18320
18321 (define_insn "*sse_movsfcc_const0_3"
18322   [(set (match_operand:SF 0 "register_operand" "=&x")
18323         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18324                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18325                          (match_operand:SF 5 "register_operand" "0")])
18326                       (match_operand:SF 2 "register_operand" "x")
18327                       (match_operand:SF 3 "const0_operand" "X")))]
18328   "TARGET_SSE"
18329   "#")
18330
18331 (define_insn "*sse_movsfcc_const0_4"
18332   [(set (match_operand:SF 0 "register_operand" "=&x")
18333         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18334                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18335                          (match_operand:SF 5 "register_operand" "0")])
18336                       (match_operand:SF 2 "const0_operand" "X")
18337                       (match_operand:SF 3 "register_operand" "x")))]
18338   "TARGET_SSE"
18339   "#")
18340
18341 (define_insn "*sse_movdfcc_const0_1"
18342   [(set (match_operand:DF 0 "register_operand" "=&Y")
18343         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18344                         [(match_operand:DF 4 "register_operand" "0")
18345                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18346                       (match_operand:DF 2 "register_operand" "Y")
18347                       (match_operand:DF 3 "const0_operand" "X")))]
18348   "TARGET_SSE2"
18349   "#")
18350
18351 (define_insn "*sse_movdfcc_const0_2"
18352   [(set (match_operand:DF 0 "register_operand" "=&Y")
18353         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18354                         [(match_operand:DF 4 "register_operand" "0")
18355                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18356                       (match_operand:DF 2 "const0_operand" "X")
18357                       (match_operand:DF 3 "register_operand" "Y")))]
18358   "TARGET_SSE2"
18359   "#")
18360
18361 (define_insn "*sse_movdfcc_const0_3"
18362   [(set (match_operand:DF 0 "register_operand" "=&Y")
18363         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18364                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18365                          (match_operand:DF 5 "register_operand" "0")])
18366                       (match_operand:DF 2 "register_operand" "Y")
18367                       (match_operand:DF 3 "const0_operand" "X")))]
18368   "TARGET_SSE2"
18369   "#")
18370
18371 (define_insn "*sse_movdfcc_const0_4"
18372   [(set (match_operand:DF 0 "register_operand" "=&Y")
18373         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18374                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18375                          (match_operand:DF 5 "register_operand" "0")])
18376                       (match_operand:DF 2 "const0_operand" "X")
18377                       (match_operand:DF 3 "register_operand" "Y")))]
18378   "TARGET_SSE2"
18379   "#")
18380
18381 (define_split
18382   [(set (match_operand:SF 0 "register_operand" "")
18383         (if_then_else:SF (match_operator 1 "comparison_operator"
18384                            [(match_operand:SF 4 "nonimmediate_operand" "")
18385                             (match_operand:SF 5 "nonimmediate_operand" "")])
18386                          (match_operand:SF 2 "nonmemory_operand" "")
18387                          (match_operand:SF 3 "nonmemory_operand" "")))]
18388   "SSE_REG_P (operands[0]) && reload_completed
18389    && (const0_operand (operands[2], GET_MODE (operands[0]))
18390        || const0_operand (operands[3], GET_MODE (operands[0])))"
18391   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18392    (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18393 {
18394   PUT_MODE (operands[1], GET_MODE (operands[0]));
18395   if (!sse_comparison_operator (operands[1], VOIDmode)
18396       || !rtx_equal_p (operands[0], operands[4]))
18397     {
18398       rtx tmp = operands[5];
18399       operands[5] = operands[4];
18400       operands[4] = tmp;
18401       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18402     }
18403   if (!rtx_equal_p (operands[0], operands[4]))
18404     abort ();
18405   operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18406   if (const0_operand (operands[2], GET_MODE (operands[2])))
18407     {
18408       operands[7] = operands[3];
18409       operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18410     }
18411   else
18412     {
18413       operands[7] = operands[2];
18414       operands[6] = operands[8];
18415     }
18416   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18417 })
18418
18419 (define_split
18420   [(set (match_operand:DF 0 "register_operand" "")
18421         (if_then_else:DF (match_operator 1 "comparison_operator"
18422                            [(match_operand:DF 4 "nonimmediate_operand" "")
18423                             (match_operand:DF 5 "nonimmediate_operand" "")])
18424                          (match_operand:DF 2 "nonmemory_operand" "")
18425                          (match_operand:DF 3 "nonmemory_operand" "")))]
18426   "SSE_REG_P (operands[0]) && reload_completed
18427    && (const0_operand (operands[2], GET_MODE (operands[0]))
18428        || const0_operand (operands[3], GET_MODE (operands[0])))"
18429   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18430    (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18431 {
18432   if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18433       && GET_MODE (operands[2]) == DFmode)
18434     {
18435       if (REG_P (operands[2]))
18436         {
18437           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18438           emit_insn (gen_sse2_unpcklpd (op, op, op));
18439         }
18440       if (REG_P (operands[3]))
18441         {
18442           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18443           emit_insn (gen_sse2_unpcklpd (op, op, op));
18444         }
18445     }
18446   PUT_MODE (operands[1], GET_MODE (operands[0]));
18447   if (!sse_comparison_operator (operands[1], VOIDmode)
18448       || !rtx_equal_p (operands[0], operands[4]))
18449     {
18450       rtx tmp = operands[5];
18451       operands[5] = operands[4];
18452       operands[4] = tmp;
18453       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18454     }
18455   if (!rtx_equal_p (operands[0], operands[4]))
18456     abort ();
18457   operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18458   if (const0_operand (operands[2], GET_MODE (operands[2])))
18459     {
18460       operands[7] = operands[3];
18461       operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18462     }
18463   else
18464     {
18465       operands[7] = operands[2];
18466       operands[6] = operands[8];
18467     }
18468   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18469 })
18470
18471 (define_expand "allocate_stack_worker"
18472   [(match_operand:SI 0 "register_operand" "")]
18473   "TARGET_STACK_PROBE"
18474 {
18475   if (reload_completed)
18476     {
18477       if (TARGET_64BIT)
18478         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18479       else
18480         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18481     }
18482   else
18483     {
18484       if (TARGET_64BIT)
18485         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18486       else
18487         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18488     }
18489   DONE;
18490 })
18491
18492 (define_insn "allocate_stack_worker_1"
18493   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18494     UNSPECV_STACK_PROBE)
18495    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18496    (clobber (match_scratch:SI 1 "=0"))
18497    (clobber (reg:CC FLAGS_REG))]
18498   "!TARGET_64BIT && TARGET_STACK_PROBE"
18499   "call\t__alloca"
18500   [(set_attr "type" "multi")
18501    (set_attr "length" "5")])
18502
18503 (define_expand "allocate_stack_worker_postreload"
18504   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18505                                     UNSPECV_STACK_PROBE)
18506               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18507               (clobber (match_dup 0))
18508               (clobber (reg:CC FLAGS_REG))])]
18509   ""
18510   "")
18511
18512 (define_insn "allocate_stack_worker_rex64"
18513   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18514     UNSPECV_STACK_PROBE)
18515    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18516    (clobber (match_scratch:DI 1 "=0"))
18517    (clobber (reg:CC FLAGS_REG))]
18518   "TARGET_64BIT && TARGET_STACK_PROBE"
18519   "call\t__alloca"
18520   [(set_attr "type" "multi")
18521    (set_attr "length" "5")])
18522
18523 (define_expand "allocate_stack_worker_rex64_postreload"
18524   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18525                                     UNSPECV_STACK_PROBE)
18526               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18527               (clobber (match_dup 0))
18528               (clobber (reg:CC FLAGS_REG))])]
18529   ""
18530   "")
18531
18532 (define_expand "allocate_stack"
18533   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18534                    (minus:SI (reg:SI SP_REG)
18535                              (match_operand:SI 1 "general_operand" "")))
18536               (clobber (reg:CC FLAGS_REG))])
18537    (parallel [(set (reg:SI SP_REG)
18538                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18539               (clobber (reg:CC FLAGS_REG))])]
18540   "TARGET_STACK_PROBE"
18541 {
18542 #ifdef CHECK_STACK_LIMIT
18543   if (GET_CODE (operands[1]) == CONST_INT
18544       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18545     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18546                            operands[1]));
18547   else 
18548 #endif
18549     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18550                                                             operands[1])));
18551
18552   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18553   DONE;
18554 })
18555
18556 (define_expand "builtin_setjmp_receiver"
18557   [(label_ref (match_operand 0 "" ""))]
18558   "!TARGET_64BIT && flag_pic"
18559 {
18560   emit_insn (gen_set_got (pic_offset_table_rtx));
18561   DONE;
18562 })
18563 \f
18564 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18565
18566 (define_split
18567   [(set (match_operand 0 "register_operand" "")
18568         (match_operator 3 "promotable_binary_operator"
18569            [(match_operand 1 "register_operand" "")
18570             (match_operand 2 "aligned_operand" "")]))
18571    (clobber (reg:CC FLAGS_REG))]
18572   "! TARGET_PARTIAL_REG_STALL && reload_completed
18573    && ((GET_MODE (operands[0]) == HImode 
18574         && ((!optimize_size && !TARGET_FAST_PREFIX)
18575             || GET_CODE (operands[2]) != CONST_INT
18576             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18577        || (GET_MODE (operands[0]) == QImode 
18578            && (TARGET_PROMOTE_QImode || optimize_size)))"
18579   [(parallel [(set (match_dup 0)
18580                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18581               (clobber (reg:CC FLAGS_REG))])]
18582   "operands[0] = gen_lowpart (SImode, operands[0]);
18583    operands[1] = gen_lowpart (SImode, operands[1]);
18584    if (GET_CODE (operands[3]) != ASHIFT)
18585      operands[2] = gen_lowpart (SImode, operands[2]);
18586    PUT_MODE (operands[3], SImode);")
18587
18588 ; Promote the QImode tests, as i386 has encoding of the AND
18589 ; instruction with 32-bit sign-extended immediate and thus the
18590 ; instruction size is unchanged, except in the %eax case for
18591 ; which it is increased by one byte, hence the ! optimize_size.
18592 (define_split
18593   [(set (match_operand 0 "flags_reg_operand" "")
18594         (match_operator 2 "compare_operator"
18595           [(and (match_operand 3 "aligned_operand" "")
18596                 (match_operand 4 "const_int_operand" ""))
18597            (const_int 0)]))
18598    (set (match_operand 1 "register_operand" "")
18599         (and (match_dup 3) (match_dup 4)))]
18600   "! TARGET_PARTIAL_REG_STALL && reload_completed
18601    /* Ensure that the operand will remain sign-extended immediate.  */
18602    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18603    && ! optimize_size
18604    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18605        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18606   [(parallel [(set (match_dup 0)
18607                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18608                                     (const_int 0)]))
18609               (set (match_dup 1)
18610                    (and:SI (match_dup 3) (match_dup 4)))])]
18611 {
18612   operands[4]
18613     = gen_int_mode (INTVAL (operands[4])
18614                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18615   operands[1] = gen_lowpart (SImode, operands[1]);
18616   operands[3] = gen_lowpart (SImode, operands[3]);
18617 })
18618
18619 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18620 ; the TEST instruction with 32-bit sign-extended immediate and thus
18621 ; the instruction size would at least double, which is not what we
18622 ; want even with ! optimize_size.
18623 (define_split
18624   [(set (match_operand 0 "flags_reg_operand" "")
18625         (match_operator 1 "compare_operator"
18626           [(and (match_operand:HI 2 "aligned_operand" "")
18627                 (match_operand:HI 3 "const_int_operand" ""))
18628            (const_int 0)]))]
18629   "! TARGET_PARTIAL_REG_STALL && reload_completed
18630    /* Ensure that the operand will remain sign-extended immediate.  */
18631    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18632    && ! TARGET_FAST_PREFIX
18633    && ! optimize_size"
18634   [(set (match_dup 0)
18635         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18636                          (const_int 0)]))]
18637 {
18638   operands[3]
18639     = gen_int_mode (INTVAL (operands[3])
18640                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18641   operands[2] = gen_lowpart (SImode, operands[2]);
18642 })
18643
18644 (define_split
18645   [(set (match_operand 0 "register_operand" "")
18646         (neg (match_operand 1 "register_operand" "")))
18647    (clobber (reg:CC FLAGS_REG))]
18648   "! TARGET_PARTIAL_REG_STALL && reload_completed
18649    && (GET_MODE (operands[0]) == HImode
18650        || (GET_MODE (operands[0]) == QImode 
18651            && (TARGET_PROMOTE_QImode || optimize_size)))"
18652   [(parallel [(set (match_dup 0)
18653                    (neg:SI (match_dup 1)))
18654               (clobber (reg:CC FLAGS_REG))])]
18655   "operands[0] = gen_lowpart (SImode, operands[0]);
18656    operands[1] = gen_lowpart (SImode, operands[1]);")
18657
18658 (define_split
18659   [(set (match_operand 0 "register_operand" "")
18660         (not (match_operand 1 "register_operand" "")))]
18661   "! TARGET_PARTIAL_REG_STALL && reload_completed
18662    && (GET_MODE (operands[0]) == HImode
18663        || (GET_MODE (operands[0]) == QImode 
18664            && (TARGET_PROMOTE_QImode || optimize_size)))"
18665   [(set (match_dup 0)
18666         (not:SI (match_dup 1)))]
18667   "operands[0] = gen_lowpart (SImode, operands[0]);
18668    operands[1] = gen_lowpart (SImode, operands[1]);")
18669
18670 (define_split 
18671   [(set (match_operand 0 "register_operand" "")
18672         (if_then_else (match_operator 1 "comparison_operator" 
18673                                 [(reg FLAGS_REG) (const_int 0)])
18674                       (match_operand 2 "register_operand" "")
18675                       (match_operand 3 "register_operand" "")))]
18676   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18677    && (GET_MODE (operands[0]) == HImode
18678        || (GET_MODE (operands[0]) == QImode 
18679            && (TARGET_PROMOTE_QImode || optimize_size)))"
18680   [(set (match_dup 0)
18681         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18682   "operands[0] = gen_lowpart (SImode, operands[0]);
18683    operands[2] = gen_lowpart (SImode, operands[2]);
18684    operands[3] = gen_lowpart (SImode, operands[3]);")
18685                         
18686 \f
18687 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18688 ;; transform a complex memory operation into two memory to register operations.
18689
18690 ;; Don't push memory operands
18691 (define_peephole2
18692   [(set (match_operand:SI 0 "push_operand" "")
18693         (match_operand:SI 1 "memory_operand" ""))
18694    (match_scratch:SI 2 "r")]
18695   "! optimize_size && ! TARGET_PUSH_MEMORY"
18696   [(set (match_dup 2) (match_dup 1))
18697    (set (match_dup 0) (match_dup 2))]
18698   "")
18699
18700 (define_peephole2
18701   [(set (match_operand:DI 0 "push_operand" "")
18702         (match_operand:DI 1 "memory_operand" ""))
18703    (match_scratch:DI 2 "r")]
18704   "! optimize_size && ! TARGET_PUSH_MEMORY"
18705   [(set (match_dup 2) (match_dup 1))
18706    (set (match_dup 0) (match_dup 2))]
18707   "")
18708
18709 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18710 ;; SImode pushes.
18711 (define_peephole2
18712   [(set (match_operand:SF 0 "push_operand" "")
18713         (match_operand:SF 1 "memory_operand" ""))
18714    (match_scratch:SF 2 "r")]
18715   "! optimize_size && ! TARGET_PUSH_MEMORY"
18716   [(set (match_dup 2) (match_dup 1))
18717    (set (match_dup 0) (match_dup 2))]
18718   "")
18719
18720 (define_peephole2
18721   [(set (match_operand:HI 0 "push_operand" "")
18722         (match_operand:HI 1 "memory_operand" ""))
18723    (match_scratch:HI 2 "r")]
18724   "! optimize_size && ! TARGET_PUSH_MEMORY"
18725   [(set (match_dup 2) (match_dup 1))
18726    (set (match_dup 0) (match_dup 2))]
18727   "")
18728
18729 (define_peephole2
18730   [(set (match_operand:QI 0 "push_operand" "")
18731         (match_operand:QI 1 "memory_operand" ""))
18732    (match_scratch:QI 2 "q")]
18733   "! optimize_size && ! TARGET_PUSH_MEMORY"
18734   [(set (match_dup 2) (match_dup 1))
18735    (set (match_dup 0) (match_dup 2))]
18736   "")
18737
18738 ;; Don't move an immediate directly to memory when the instruction
18739 ;; gets too big.
18740 (define_peephole2
18741   [(match_scratch:SI 1 "r")
18742    (set (match_operand:SI 0 "memory_operand" "")
18743         (const_int 0))]
18744   "! optimize_size
18745    && ! TARGET_USE_MOV0
18746    && TARGET_SPLIT_LONG_MOVES
18747    && get_attr_length (insn) >= ix86_cost->large_insn
18748    && peep2_regno_dead_p (0, FLAGS_REG)"
18749   [(parallel [(set (match_dup 1) (const_int 0))
18750               (clobber (reg:CC FLAGS_REG))])
18751    (set (match_dup 0) (match_dup 1))]
18752   "")
18753
18754 (define_peephole2
18755   [(match_scratch:HI 1 "r")
18756    (set (match_operand:HI 0 "memory_operand" "")
18757         (const_int 0))]
18758   "! optimize_size
18759    && ! TARGET_USE_MOV0
18760    && TARGET_SPLIT_LONG_MOVES
18761    && get_attr_length (insn) >= ix86_cost->large_insn
18762    && peep2_regno_dead_p (0, FLAGS_REG)"
18763   [(parallel [(set (match_dup 2) (const_int 0))
18764               (clobber (reg:CC FLAGS_REG))])
18765    (set (match_dup 0) (match_dup 1))]
18766   "operands[2] = gen_lowpart (SImode, operands[1]);")
18767
18768 (define_peephole2
18769   [(match_scratch:QI 1 "q")
18770    (set (match_operand:QI 0 "memory_operand" "")
18771         (const_int 0))]
18772   "! optimize_size
18773    && ! TARGET_USE_MOV0
18774    && TARGET_SPLIT_LONG_MOVES
18775    && get_attr_length (insn) >= ix86_cost->large_insn
18776    && peep2_regno_dead_p (0, FLAGS_REG)"
18777   [(parallel [(set (match_dup 2) (const_int 0))
18778               (clobber (reg:CC FLAGS_REG))])
18779    (set (match_dup 0) (match_dup 1))]
18780   "operands[2] = gen_lowpart (SImode, operands[1]);")
18781
18782 (define_peephole2
18783   [(match_scratch:SI 2 "r")
18784    (set (match_operand:SI 0 "memory_operand" "")
18785         (match_operand:SI 1 "immediate_operand" ""))]
18786   "! optimize_size
18787    && get_attr_length (insn) >= ix86_cost->large_insn
18788    && TARGET_SPLIT_LONG_MOVES"
18789   [(set (match_dup 2) (match_dup 1))
18790    (set (match_dup 0) (match_dup 2))]
18791   "")
18792
18793 (define_peephole2
18794   [(match_scratch:HI 2 "r")
18795    (set (match_operand:HI 0 "memory_operand" "")
18796         (match_operand:HI 1 "immediate_operand" ""))]
18797   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18798   && TARGET_SPLIT_LONG_MOVES"
18799   [(set (match_dup 2) (match_dup 1))
18800    (set (match_dup 0) (match_dup 2))]
18801   "")
18802
18803 (define_peephole2
18804   [(match_scratch:QI 2 "q")
18805    (set (match_operand:QI 0 "memory_operand" "")
18806         (match_operand:QI 1 "immediate_operand" ""))]
18807   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18808   && TARGET_SPLIT_LONG_MOVES"
18809   [(set (match_dup 2) (match_dup 1))
18810    (set (match_dup 0) (match_dup 2))]
18811   "")
18812
18813 ;; Don't compare memory with zero, load and use a test instead.
18814 (define_peephole2
18815   [(set (match_operand 0 "flags_reg_operand" "")
18816         (match_operator 1 "compare_operator"
18817           [(match_operand:SI 2 "memory_operand" "")
18818            (const_int 0)]))
18819    (match_scratch:SI 3 "r")]
18820   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18821   [(set (match_dup 3) (match_dup 2))
18822    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18823   "")
18824
18825 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18826 ;; Don't split NOTs with a displacement operand, because resulting XOR
18827 ;; will not be pairable anyway.
18828 ;;
18829 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18830 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18831 ;; so this split helps here as well.
18832 ;;
18833 ;; Note: Can't do this as a regular split because we can't get proper
18834 ;; lifetime information then.
18835
18836 (define_peephole2
18837   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18838         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18839   "!optimize_size
18840    && peep2_regno_dead_p (0, FLAGS_REG)
18841    && ((TARGET_PENTIUM 
18842         && (GET_CODE (operands[0]) != MEM
18843             || !memory_displacement_operand (operands[0], SImode)))
18844        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18845   [(parallel [(set (match_dup 0)
18846                    (xor:SI (match_dup 1) (const_int -1)))
18847               (clobber (reg:CC FLAGS_REG))])]
18848   "")
18849
18850 (define_peephole2
18851   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18852         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18853   "!optimize_size
18854    && peep2_regno_dead_p (0, FLAGS_REG)
18855    && ((TARGET_PENTIUM 
18856         && (GET_CODE (operands[0]) != MEM
18857             || !memory_displacement_operand (operands[0], HImode)))
18858        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18859   [(parallel [(set (match_dup 0)
18860                    (xor:HI (match_dup 1) (const_int -1)))
18861               (clobber (reg:CC FLAGS_REG))])]
18862   "")
18863
18864 (define_peephole2
18865   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18866         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18867   "!optimize_size
18868    && peep2_regno_dead_p (0, FLAGS_REG)
18869    && ((TARGET_PENTIUM 
18870         && (GET_CODE (operands[0]) != MEM
18871             || !memory_displacement_operand (operands[0], QImode)))
18872        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18873   [(parallel [(set (match_dup 0)
18874                    (xor:QI (match_dup 1) (const_int -1)))
18875               (clobber (reg:CC FLAGS_REG))])]
18876   "")
18877
18878 ;; Non pairable "test imm, reg" instructions can be translated to
18879 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18880 ;; byte opcode instead of two, have a short form for byte operands),
18881 ;; so do it for other CPUs as well.  Given that the value was dead,
18882 ;; this should not create any new dependencies.  Pass on the sub-word
18883 ;; versions if we're concerned about partial register stalls.
18884
18885 (define_peephole2
18886   [(set (match_operand 0 "flags_reg_operand" "")
18887         (match_operator 1 "compare_operator"
18888           [(and:SI (match_operand:SI 2 "register_operand" "")
18889                    (match_operand:SI 3 "immediate_operand" ""))
18890            (const_int 0)]))]
18891   "ix86_match_ccmode (insn, CCNOmode)
18892    && (true_regnum (operands[2]) != 0
18893        || (GET_CODE (operands[3]) == CONST_INT
18894            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18895    && peep2_reg_dead_p (1, operands[2])"
18896   [(parallel
18897      [(set (match_dup 0)
18898            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18899                             (const_int 0)]))
18900       (set (match_dup 2)
18901            (and:SI (match_dup 2) (match_dup 3)))])]
18902   "")
18903
18904 ;; We don't need to handle HImode case, because it will be promoted to SImode
18905 ;; on ! TARGET_PARTIAL_REG_STALL
18906
18907 (define_peephole2
18908   [(set (match_operand 0 "flags_reg_operand" "")
18909         (match_operator 1 "compare_operator"
18910           [(and:QI (match_operand:QI 2 "register_operand" "")
18911                    (match_operand:QI 3 "immediate_operand" ""))
18912            (const_int 0)]))]
18913   "! TARGET_PARTIAL_REG_STALL
18914    && ix86_match_ccmode (insn, CCNOmode)
18915    && true_regnum (operands[2]) != 0
18916    && peep2_reg_dead_p (1, operands[2])"
18917   [(parallel
18918      [(set (match_dup 0)
18919            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18920                             (const_int 0)]))
18921       (set (match_dup 2)
18922            (and:QI (match_dup 2) (match_dup 3)))])]
18923   "")
18924
18925 (define_peephole2
18926   [(set (match_operand 0 "flags_reg_operand" "")
18927         (match_operator 1 "compare_operator"
18928           [(and:SI
18929              (zero_extract:SI
18930                (match_operand 2 "ext_register_operand" "")
18931                (const_int 8)
18932                (const_int 8))
18933              (match_operand 3 "const_int_operand" ""))
18934            (const_int 0)]))]
18935   "! TARGET_PARTIAL_REG_STALL
18936    && ix86_match_ccmode (insn, CCNOmode)
18937    && true_regnum (operands[2]) != 0
18938    && peep2_reg_dead_p (1, operands[2])"
18939   [(parallel [(set (match_dup 0)
18940                    (match_op_dup 1
18941                      [(and:SI
18942                         (zero_extract:SI
18943                           (match_dup 2)
18944                           (const_int 8)
18945                           (const_int 8))
18946                         (match_dup 3))
18947                       (const_int 0)]))
18948               (set (zero_extract:SI (match_dup 2)
18949                                     (const_int 8)
18950                                     (const_int 8))
18951                    (and:SI 
18952                      (zero_extract:SI
18953                        (match_dup 2)
18954                        (const_int 8)
18955                        (const_int 8))
18956                      (match_dup 3)))])]
18957   "")
18958
18959 ;; Don't do logical operations with memory inputs.
18960 (define_peephole2
18961   [(match_scratch:SI 2 "r")
18962    (parallel [(set (match_operand:SI 0 "register_operand" "")
18963                    (match_operator:SI 3 "arith_or_logical_operator"
18964                      [(match_dup 0)
18965                       (match_operand:SI 1 "memory_operand" "")]))
18966               (clobber (reg:CC FLAGS_REG))])]
18967   "! optimize_size && ! TARGET_READ_MODIFY"
18968   [(set (match_dup 2) (match_dup 1))
18969    (parallel [(set (match_dup 0)
18970                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18971               (clobber (reg:CC FLAGS_REG))])]
18972   "")
18973
18974 (define_peephole2
18975   [(match_scratch:SI 2 "r")
18976    (parallel [(set (match_operand:SI 0 "register_operand" "")
18977                    (match_operator:SI 3 "arith_or_logical_operator"
18978                      [(match_operand:SI 1 "memory_operand" "")
18979                       (match_dup 0)]))
18980               (clobber (reg:CC FLAGS_REG))])]
18981   "! optimize_size && ! TARGET_READ_MODIFY"
18982   [(set (match_dup 2) (match_dup 1))
18983    (parallel [(set (match_dup 0)
18984                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18985               (clobber (reg:CC FLAGS_REG))])]
18986   "")
18987
18988 ; Don't do logical operations with memory outputs
18989 ;
18990 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18991 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18992 ; the same decoder scheduling characteristics as the original.
18993
18994 (define_peephole2
18995   [(match_scratch:SI 2 "r")
18996    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18997                    (match_operator:SI 3 "arith_or_logical_operator"
18998                      [(match_dup 0)
18999                       (match_operand:SI 1 "nonmemory_operand" "")]))
19000               (clobber (reg:CC FLAGS_REG))])]
19001   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19002   [(set (match_dup 2) (match_dup 0))
19003    (parallel [(set (match_dup 2)
19004                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19005               (clobber (reg:CC FLAGS_REG))])
19006    (set (match_dup 0) (match_dup 2))]
19007   "")
19008
19009 (define_peephole2
19010   [(match_scratch:SI 2 "r")
19011    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19012                    (match_operator:SI 3 "arith_or_logical_operator"
19013                      [(match_operand:SI 1 "nonmemory_operand" "")
19014                       (match_dup 0)]))
19015               (clobber (reg:CC FLAGS_REG))])]
19016   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19017   [(set (match_dup 2) (match_dup 0))
19018    (parallel [(set (match_dup 2)
19019                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19020               (clobber (reg:CC FLAGS_REG))])
19021    (set (match_dup 0) (match_dup 2))]
19022   "")
19023
19024 ;; Attempt to always use XOR for zeroing registers.
19025 (define_peephole2
19026   [(set (match_operand 0 "register_operand" "")
19027         (const_int 0))]
19028   "(GET_MODE (operands[0]) == QImode
19029     || GET_MODE (operands[0]) == HImode
19030     || GET_MODE (operands[0]) == SImode
19031     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19032    && (! TARGET_USE_MOV0 || optimize_size)
19033    && peep2_regno_dead_p (0, FLAGS_REG)"
19034   [(parallel [(set (match_dup 0) (const_int 0))
19035               (clobber (reg:CC FLAGS_REG))])]
19036   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19037                               operands[0]);")
19038
19039 (define_peephole2
19040   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19041         (const_int 0))]
19042   "(GET_MODE (operands[0]) == QImode
19043     || GET_MODE (operands[0]) == HImode)
19044    && (! TARGET_USE_MOV0 || optimize_size)
19045    && peep2_regno_dead_p (0, FLAGS_REG)"
19046   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19047               (clobber (reg:CC FLAGS_REG))])])
19048
19049 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19050 (define_peephole2
19051   [(set (match_operand 0 "register_operand" "")
19052         (const_int -1))]
19053   "(GET_MODE (operands[0]) == HImode
19054     || GET_MODE (operands[0]) == SImode 
19055     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19056    && (optimize_size || TARGET_PENTIUM)
19057    && peep2_regno_dead_p (0, FLAGS_REG)"
19058   [(parallel [(set (match_dup 0) (const_int -1))
19059               (clobber (reg:CC FLAGS_REG))])]
19060   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19061                               operands[0]);")
19062
19063 ;; Attempt to convert simple leas to adds. These can be created by
19064 ;; move expanders.
19065 (define_peephole2
19066   [(set (match_operand:SI 0 "register_operand" "")
19067         (plus:SI (match_dup 0)
19068                  (match_operand:SI 1 "nonmemory_operand" "")))]
19069   "peep2_regno_dead_p (0, FLAGS_REG)"
19070   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19071               (clobber (reg:CC FLAGS_REG))])]
19072   "")
19073
19074 (define_peephole2
19075   [(set (match_operand:SI 0 "register_operand" "")
19076         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19077                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19078   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19079   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19080               (clobber (reg:CC FLAGS_REG))])]
19081   "operands[2] = gen_lowpart (SImode, operands[2]);")
19082
19083 (define_peephole2
19084   [(set (match_operand:DI 0 "register_operand" "")
19085         (plus:DI (match_dup 0)
19086                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19087   "peep2_regno_dead_p (0, FLAGS_REG)"
19088   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19089               (clobber (reg:CC FLAGS_REG))])]
19090   "")
19091
19092 (define_peephole2
19093   [(set (match_operand:SI 0 "register_operand" "")
19094         (mult:SI (match_dup 0)
19095                  (match_operand:SI 1 "const_int_operand" "")))]
19096   "exact_log2 (INTVAL (operands[1])) >= 0
19097    && peep2_regno_dead_p (0, FLAGS_REG)"
19098   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19099               (clobber (reg:CC FLAGS_REG))])]
19100   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19101
19102 (define_peephole2
19103   [(set (match_operand:DI 0 "register_operand" "")
19104         (mult:DI (match_dup 0)
19105                  (match_operand:DI 1 "const_int_operand" "")))]
19106   "exact_log2 (INTVAL (operands[1])) >= 0
19107    && peep2_regno_dead_p (0, FLAGS_REG)"
19108   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19109               (clobber (reg:CC FLAGS_REG))])]
19110   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19111
19112 (define_peephole2
19113   [(set (match_operand:SI 0 "register_operand" "")
19114         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19115                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19116   "exact_log2 (INTVAL (operands[2])) >= 0
19117    && REGNO (operands[0]) == REGNO (operands[1])
19118    && peep2_regno_dead_p (0, FLAGS_REG)"
19119   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19120               (clobber (reg:CC FLAGS_REG))])]
19121   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19122
19123 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19124 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19125 ;; many CPUs it is also faster, since special hardware to avoid esp
19126 ;; dependencies is present.
19127
19128 ;; While some of these conversions may be done using splitters, we use peepholes
19129 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19130
19131 ;; Convert prologue esp subtractions to push.
19132 ;; We need register to push.  In order to keep verify_flow_info happy we have
19133 ;; two choices
19134 ;; - use scratch and clobber it in order to avoid dependencies
19135 ;; - use already live register
19136 ;; We can't use the second way right now, since there is no reliable way how to
19137 ;; verify that given register is live.  First choice will also most likely in
19138 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19139 ;; call clobbered registers are dead.  We may want to use base pointer as an
19140 ;; alternative when no register is available later.
19141
19142 (define_peephole2
19143   [(match_scratch:SI 0 "r")
19144    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19145               (clobber (reg:CC FLAGS_REG))
19146               (clobber (mem:BLK (scratch)))])]
19147   "optimize_size || !TARGET_SUB_ESP_4"
19148   [(clobber (match_dup 0))
19149    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19150               (clobber (mem:BLK (scratch)))])])
19151
19152 (define_peephole2
19153   [(match_scratch:SI 0 "r")
19154    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19155               (clobber (reg:CC FLAGS_REG))
19156               (clobber (mem:BLK (scratch)))])]
19157   "optimize_size || !TARGET_SUB_ESP_8"
19158   [(clobber (match_dup 0))
19159    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19160    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19161               (clobber (mem:BLK (scratch)))])])
19162
19163 ;; Convert esp subtractions to push.
19164 (define_peephole2
19165   [(match_scratch:SI 0 "r")
19166    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19167               (clobber (reg:CC FLAGS_REG))])]
19168   "optimize_size || !TARGET_SUB_ESP_4"
19169   [(clobber (match_dup 0))
19170    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19171
19172 (define_peephole2
19173   [(match_scratch:SI 0 "r")
19174    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19175               (clobber (reg:CC FLAGS_REG))])]
19176   "optimize_size || !TARGET_SUB_ESP_8"
19177   [(clobber (match_dup 0))
19178    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19179    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19180
19181 ;; Convert epilogue deallocator to pop.
19182 (define_peephole2
19183   [(match_scratch:SI 0 "r")
19184    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19185               (clobber (reg:CC FLAGS_REG))
19186               (clobber (mem:BLK (scratch)))])]
19187   "optimize_size || !TARGET_ADD_ESP_4"
19188   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19189               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19190               (clobber (mem:BLK (scratch)))])]
19191   "")
19192
19193 ;; Two pops case is tricky, since pop causes dependency on destination register.
19194 ;; We use two registers if available.
19195 (define_peephole2
19196   [(match_scratch:SI 0 "r")
19197    (match_scratch:SI 1 "r")
19198    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19199               (clobber (reg:CC FLAGS_REG))
19200               (clobber (mem:BLK (scratch)))])]
19201   "optimize_size || !TARGET_ADD_ESP_8"
19202   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19203               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19204               (clobber (mem:BLK (scratch)))])
19205    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19206               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19207   "")
19208
19209 (define_peephole2
19210   [(match_scratch:SI 0 "r")
19211    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19212               (clobber (reg:CC FLAGS_REG))
19213               (clobber (mem:BLK (scratch)))])]
19214   "optimize_size"
19215   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19216               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19217               (clobber (mem:BLK (scratch)))])
19218    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19219               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19220   "")
19221
19222 ;; Convert esp additions to pop.
19223 (define_peephole2
19224   [(match_scratch:SI 0 "r")
19225    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19226               (clobber (reg:CC FLAGS_REG))])]
19227   ""
19228   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19229               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19230   "")
19231
19232 ;; Two pops case is tricky, since pop causes dependency on destination register.
19233 ;; We use two registers if available.
19234 (define_peephole2
19235   [(match_scratch:SI 0 "r")
19236    (match_scratch:SI 1 "r")
19237    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19238               (clobber (reg:CC FLAGS_REG))])]
19239   ""
19240   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19241               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19242    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19243               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19244   "")
19245
19246 (define_peephole2
19247   [(match_scratch:SI 0 "r")
19248    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19249               (clobber (reg:CC FLAGS_REG))])]
19250   "optimize_size"
19251   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19252               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19253    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19254               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19255   "")
19256 \f
19257 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19258 ;; required and register dies.  Similarly for 128 to plus -128.
19259 (define_peephole2
19260   [(set (match_operand 0 "flags_reg_operand" "")
19261         (match_operator 1 "compare_operator"
19262           [(match_operand 2 "register_operand" "")
19263            (match_operand 3 "const_int_operand" "")]))]
19264   "(INTVAL (operands[3]) == -1
19265     || INTVAL (operands[3]) == 1
19266     || INTVAL (operands[3]) == 128)
19267    && ix86_match_ccmode (insn, CCGCmode)
19268    && peep2_reg_dead_p (1, operands[2])"
19269   [(parallel [(set (match_dup 0)
19270                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19271               (clobber (match_dup 2))])]
19272   "")
19273 \f
19274 (define_peephole2
19275   [(match_scratch:DI 0 "r")
19276    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19277               (clobber (reg:CC FLAGS_REG))
19278               (clobber (mem:BLK (scratch)))])]
19279   "optimize_size || !TARGET_SUB_ESP_4"
19280   [(clobber (match_dup 0))
19281    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19282               (clobber (mem:BLK (scratch)))])])
19283
19284 (define_peephole2
19285   [(match_scratch:DI 0 "r")
19286    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19287               (clobber (reg:CC FLAGS_REG))
19288               (clobber (mem:BLK (scratch)))])]
19289   "optimize_size || !TARGET_SUB_ESP_8"
19290   [(clobber (match_dup 0))
19291    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19292    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19293               (clobber (mem:BLK (scratch)))])])
19294
19295 ;; Convert esp subtractions to push.
19296 (define_peephole2
19297   [(match_scratch:DI 0 "r")
19298    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19299               (clobber (reg:CC FLAGS_REG))])]
19300   "optimize_size || !TARGET_SUB_ESP_4"
19301   [(clobber (match_dup 0))
19302    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19303
19304 (define_peephole2
19305   [(match_scratch:DI 0 "r")
19306    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19307               (clobber (reg:CC FLAGS_REG))])]
19308   "optimize_size || !TARGET_SUB_ESP_8"
19309   [(clobber (match_dup 0))
19310    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19311    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19312
19313 ;; Convert epilogue deallocator to pop.
19314 (define_peephole2
19315   [(match_scratch:DI 0 "r")
19316    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19317               (clobber (reg:CC FLAGS_REG))
19318               (clobber (mem:BLK (scratch)))])]
19319   "optimize_size || !TARGET_ADD_ESP_4"
19320   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19321               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19322               (clobber (mem:BLK (scratch)))])]
19323   "")
19324
19325 ;; Two pops case is tricky, since pop causes dependency on destination register.
19326 ;; We use two registers if available.
19327 (define_peephole2
19328   [(match_scratch:DI 0 "r")
19329    (match_scratch:DI 1 "r")
19330    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19331               (clobber (reg:CC FLAGS_REG))
19332               (clobber (mem:BLK (scratch)))])]
19333   "optimize_size || !TARGET_ADD_ESP_8"
19334   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19335               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19336               (clobber (mem:BLK (scratch)))])
19337    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19338               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19339   "")
19340
19341 (define_peephole2
19342   [(match_scratch:DI 0 "r")
19343    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19344               (clobber (reg:CC FLAGS_REG))
19345               (clobber (mem:BLK (scratch)))])]
19346   "optimize_size"
19347   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19348               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19349               (clobber (mem:BLK (scratch)))])
19350    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19351               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19352   "")
19353
19354 ;; Convert esp additions to pop.
19355 (define_peephole2
19356   [(match_scratch:DI 0 "r")
19357    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19358               (clobber (reg:CC FLAGS_REG))])]
19359   ""
19360   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19361               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19362   "")
19363
19364 ;; Two pops case is tricky, since pop causes dependency on destination register.
19365 ;; We use two registers if available.
19366 (define_peephole2
19367   [(match_scratch:DI 0 "r")
19368    (match_scratch:DI 1 "r")
19369    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19370               (clobber (reg:CC FLAGS_REG))])]
19371   ""
19372   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19373               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19374    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19375               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19376   "")
19377
19378 (define_peephole2
19379   [(match_scratch:DI 0 "r")
19380    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19381               (clobber (reg:CC FLAGS_REG))])]
19382   "optimize_size"
19383   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19384               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19385    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19386               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19387   "")
19388 \f
19389 ;; Convert imul by three, five and nine into lea
19390 (define_peephole2
19391   [(parallel
19392     [(set (match_operand:SI 0 "register_operand" "")
19393           (mult:SI (match_operand:SI 1 "register_operand" "")
19394                    (match_operand:SI 2 "const_int_operand" "")))
19395      (clobber (reg:CC FLAGS_REG))])]
19396   "INTVAL (operands[2]) == 3
19397    || INTVAL (operands[2]) == 5
19398    || INTVAL (operands[2]) == 9"
19399   [(set (match_dup 0)
19400         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19401                  (match_dup 1)))]
19402   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19403
19404 (define_peephole2
19405   [(parallel
19406     [(set (match_operand:SI 0 "register_operand" "")
19407           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19408                    (match_operand:SI 2 "const_int_operand" "")))
19409      (clobber (reg:CC FLAGS_REG))])]
19410   "!optimize_size 
19411    && (INTVAL (operands[2]) == 3
19412        || INTVAL (operands[2]) == 5
19413        || INTVAL (operands[2]) == 9)"
19414   [(set (match_dup 0) (match_dup 1))
19415    (set (match_dup 0)
19416         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19417                  (match_dup 0)))]
19418   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19419
19420 (define_peephole2
19421   [(parallel
19422     [(set (match_operand:DI 0 "register_operand" "")
19423           (mult:DI (match_operand:DI 1 "register_operand" "")
19424                    (match_operand:DI 2 "const_int_operand" "")))
19425      (clobber (reg:CC FLAGS_REG))])]
19426   "TARGET_64BIT
19427    && (INTVAL (operands[2]) == 3
19428        || INTVAL (operands[2]) == 5
19429        || INTVAL (operands[2]) == 9)"
19430   [(set (match_dup 0)
19431         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19432                  (match_dup 1)))]
19433   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19434
19435 (define_peephole2
19436   [(parallel
19437     [(set (match_operand:DI 0 "register_operand" "")
19438           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19439                    (match_operand:DI 2 "const_int_operand" "")))
19440      (clobber (reg:CC FLAGS_REG))])]
19441   "TARGET_64BIT
19442    && !optimize_size 
19443    && (INTVAL (operands[2]) == 3
19444        || INTVAL (operands[2]) == 5
19445        || INTVAL (operands[2]) == 9)"
19446   [(set (match_dup 0) (match_dup 1))
19447    (set (match_dup 0)
19448         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19449                  (match_dup 0)))]
19450   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19451
19452 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19453 ;; imul $32bit_imm, reg, reg is direct decoded.
19454 (define_peephole2
19455   [(match_scratch:DI 3 "r")
19456    (parallel [(set (match_operand:DI 0 "register_operand" "")
19457                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19458                             (match_operand:DI 2 "immediate_operand" "")))
19459               (clobber (reg:CC FLAGS_REG))])]
19460   "TARGET_K8 && !optimize_size
19461    && (GET_CODE (operands[2]) != CONST_INT
19462        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19463   [(set (match_dup 3) (match_dup 1))
19464    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19465               (clobber (reg:CC FLAGS_REG))])]
19466 "")
19467
19468 (define_peephole2
19469   [(match_scratch:SI 3 "r")
19470    (parallel [(set (match_operand:SI 0 "register_operand" "")
19471                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19472                             (match_operand:SI 2 "immediate_operand" "")))
19473               (clobber (reg:CC FLAGS_REG))])]
19474   "TARGET_K8 && !optimize_size
19475    && (GET_CODE (operands[2]) != CONST_INT
19476        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19477   [(set (match_dup 3) (match_dup 1))
19478    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19479               (clobber (reg:CC FLAGS_REG))])]
19480 "")
19481
19482 (define_peephole2
19483   [(match_scratch:SI 3 "r")
19484    (parallel [(set (match_operand:DI 0 "register_operand" "")
19485                    (zero_extend:DI
19486                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19487                               (match_operand:SI 2 "immediate_operand" ""))))
19488               (clobber (reg:CC FLAGS_REG))])]
19489   "TARGET_K8 && !optimize_size
19490    && (GET_CODE (operands[2]) != CONST_INT
19491        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19492   [(set (match_dup 3) (match_dup 1))
19493    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19494               (clobber (reg:CC FLAGS_REG))])]
19495 "")
19496
19497 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19498 ;; Convert it into imul reg, reg
19499 ;; It would be better to force assembler to encode instruction using long
19500 ;; immediate, but there is apparently no way to do so.
19501 (define_peephole2
19502   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19503                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19504                             (match_operand:DI 2 "const_int_operand" "")))
19505               (clobber (reg:CC FLAGS_REG))])
19506    (match_scratch:DI 3 "r")]
19507   "TARGET_K8 && !optimize_size
19508    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19509   [(set (match_dup 3) (match_dup 2))
19510    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19511               (clobber (reg:CC FLAGS_REG))])]
19512 {
19513   if (!rtx_equal_p (operands[0], operands[1]))
19514     emit_move_insn (operands[0], operands[1]);
19515 })
19516
19517 (define_peephole2
19518   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19519                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19520                             (match_operand:SI 2 "const_int_operand" "")))
19521               (clobber (reg:CC FLAGS_REG))])
19522    (match_scratch:SI 3 "r")]
19523   "TARGET_K8 && !optimize_size
19524    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19525   [(set (match_dup 3) (match_dup 2))
19526    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19527               (clobber (reg:CC FLAGS_REG))])]
19528 {
19529   if (!rtx_equal_p (operands[0], operands[1]))
19530     emit_move_insn (operands[0], operands[1]);
19531 })
19532
19533 (define_peephole2
19534   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19535                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19536                             (match_operand:HI 2 "immediate_operand" "")))
19537               (clobber (reg:CC FLAGS_REG))])
19538    (match_scratch:HI 3 "r")]
19539   "TARGET_K8 && !optimize_size"
19540   [(set (match_dup 3) (match_dup 2))
19541    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19542               (clobber (reg:CC FLAGS_REG))])]
19543 {
19544   if (!rtx_equal_p (operands[0], operands[1]))
19545     emit_move_insn (operands[0], operands[1]);
19546 })
19547 \f
19548 ;; Call-value patterns last so that the wildcard operand does not
19549 ;; disrupt insn-recog's switch tables.
19550
19551 (define_insn "*call_value_pop_0"
19552   [(set (match_operand 0 "" "")
19553         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19554               (match_operand:SI 2 "" "")))
19555    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19556                             (match_operand:SI 3 "immediate_operand" "")))]
19557   "!TARGET_64BIT"
19558 {
19559   if (SIBLING_CALL_P (insn))
19560     return "jmp\t%P1";
19561   else
19562     return "call\t%P1";
19563 }
19564   [(set_attr "type" "callv")])
19565
19566 (define_insn "*call_value_pop_1"
19567   [(set (match_operand 0 "" "")
19568         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19569               (match_operand:SI 2 "" "")))
19570    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19571                             (match_operand:SI 3 "immediate_operand" "i")))]
19572   "!TARGET_64BIT"
19573 {
19574   if (constant_call_address_operand (operands[1], Pmode))
19575     {
19576       if (SIBLING_CALL_P (insn))
19577         return "jmp\t%P1";
19578       else
19579         return "call\t%P1";
19580     }
19581   if (SIBLING_CALL_P (insn))
19582     return "jmp\t%A1";
19583   else
19584     return "call\t%A1";
19585 }
19586   [(set_attr "type" "callv")])
19587
19588 (define_insn "*call_value_0"
19589   [(set (match_operand 0 "" "")
19590         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19591               (match_operand:SI 2 "" "")))]
19592   "!TARGET_64BIT"
19593 {
19594   if (SIBLING_CALL_P (insn))
19595     return "jmp\t%P1";
19596   else
19597     return "call\t%P1";
19598 }
19599   [(set_attr "type" "callv")])
19600
19601 (define_insn "*call_value_0_rex64"
19602   [(set (match_operand 0 "" "")
19603         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19604               (match_operand:DI 2 "const_int_operand" "")))]
19605   "TARGET_64BIT"
19606 {
19607   if (SIBLING_CALL_P (insn))
19608     return "jmp\t%P1";
19609   else
19610     return "call\t%P1";
19611 }
19612   [(set_attr "type" "callv")])
19613
19614 (define_insn "*call_value_1"
19615   [(set (match_operand 0 "" "")
19616         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19617               (match_operand:SI 2 "" "")))]
19618   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19619 {
19620   if (constant_call_address_operand (operands[1], Pmode))
19621     return "call\t%P1";
19622   return "call\t%A1";
19623 }
19624   [(set_attr "type" "callv")])
19625
19626 (define_insn "*sibcall_value_1"
19627   [(set (match_operand 0 "" "")
19628         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19629               (match_operand:SI 2 "" "")))]
19630   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19631 {
19632   if (constant_call_address_operand (operands[1], Pmode))
19633     return "jmp\t%P1";
19634   return "jmp\t%A1";
19635 }
19636   [(set_attr "type" "callv")])
19637
19638 (define_insn "*call_value_1_rex64"
19639   [(set (match_operand 0 "" "")
19640         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19641               (match_operand:DI 2 "" "")))]
19642   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19643 {
19644   if (constant_call_address_operand (operands[1], Pmode))
19645     return "call\t%P1";
19646   return "call\t%A1";
19647 }
19648   [(set_attr "type" "callv")])
19649
19650 (define_insn "*sibcall_value_1_rex64"
19651   [(set (match_operand 0 "" "")
19652         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19653               (match_operand:DI 2 "" "")))]
19654   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19655   "jmp\t%P1"
19656   [(set_attr "type" "callv")])
19657
19658 (define_insn "*sibcall_value_1_rex64_v"
19659   [(set (match_operand 0 "" "")
19660         (call (mem:QI (reg:DI 40))
19661               (match_operand:DI 1 "" "")))]
19662   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19663   "jmp\t*%%r11"
19664   [(set_attr "type" "callv")])
19665 \f
19666 (define_insn "trap"
19667   [(trap_if (const_int 1) (const_int 5))]
19668   ""
19669   "int\t$5")
19670
19671 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19672 ;;; for the sake of bounds checking.  By emitting bounds checks as
19673 ;;; conditional traps rather than as conditional jumps around
19674 ;;; unconditional traps we avoid introducing spurious basic-block
19675 ;;; boundaries and facilitate elimination of redundant checks.  In
19676 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19677 ;;; interrupt 5.
19678 ;;; 
19679 ;;; FIXME: Static branch prediction rules for ix86 are such that
19680 ;;; forward conditional branches predict as untaken.  As implemented
19681 ;;; below, pseudo conditional traps violate that rule.  We should use
19682 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19683 ;;; section loaded at the end of the text segment and branch forward
19684 ;;; there on bounds-failure, and then jump back immediately (in case
19685 ;;; the system chooses to ignore bounds violations, or to report
19686 ;;; violations and continue execution).
19687
19688 (define_expand "conditional_trap"
19689   [(trap_if (match_operator 0 "comparison_operator"
19690              [(match_dup 2) (const_int 0)])
19691             (match_operand 1 "const_int_operand" ""))]
19692   ""
19693 {
19694   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19695                               ix86_expand_compare (GET_CODE (operands[0]),
19696                                                    NULL, NULL),
19697                               operands[1]));
19698   DONE;
19699 })
19700
19701 (define_insn "*conditional_trap_1"
19702   [(trap_if (match_operator 0 "comparison_operator"
19703              [(reg FLAGS_REG) (const_int 0)])
19704             (match_operand 1 "const_int_operand" ""))]
19705   ""
19706 {
19707   operands[2] = gen_label_rtx ();
19708   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19709   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19710                              CODE_LABEL_NUMBER (operands[2]));
19711   RET;
19712 })
19713
19714         ;; Pentium III SIMD instructions.
19715
19716 ;; Moves for SSE/MMX regs.
19717
19718 (define_expand "movv4sf"
19719   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19720         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19721   "TARGET_SSE"
19722 {
19723   ix86_expand_vector_move (V4SFmode, operands);
19724   DONE;
19725 })
19726
19727 (define_insn "*movv4sf_internal"
19728   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19729         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19730   "TARGET_SSE"
19731   "@
19732     xorps\t%0, %0
19733     movaps\t{%1, %0|%0, %1}
19734     movaps\t{%1, %0|%0, %1}"
19735   [(set_attr "type" "ssemov")
19736    (set_attr "mode" "V4SF")])
19737
19738 (define_split
19739   [(set (match_operand:V4SF 0 "register_operand" "")
19740         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19741   "TARGET_SSE && reload_completed"
19742   [(set (match_dup 0)
19743         (vec_merge:V4SF
19744          (vec_duplicate:V4SF (match_dup 1))
19745          (match_dup 2)
19746          (const_int 1)))]
19747 {
19748   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19749   operands[2] = CONST0_RTX (V4SFmode);
19750 })
19751
19752 (define_expand "movv2df"
19753   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19754         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19755   "TARGET_SSE"
19756 {
19757   ix86_expand_vector_move (V2DFmode, operands);
19758   DONE;
19759 })
19760
19761 (define_insn "*movv2df_internal"
19762   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19763         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19764   "TARGET_SSE
19765    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19766 {
19767   switch (which_alternative)
19768     {
19769     case 0:
19770       if (get_attr_mode (insn) == MODE_V4SF)
19771         return "xorps\t%0, %0";
19772       else
19773         return "xorpd\t%0, %0";
19774     case 1:
19775     case 2:
19776       if (get_attr_mode (insn) == MODE_V4SF)
19777         return "movaps\t{%1, %0|%0, %1}";
19778       else
19779         return "movapd\t{%1, %0|%0, %1}";
19780     default:
19781       abort ();
19782     }
19783 }
19784   [(set_attr "type" "ssemov")
19785    (set (attr "mode")
19786         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
19787                  (const_string "V4SF")
19788                (eq_attr "alternative" "0,1")
19789                  (if_then_else
19790                    (ne (symbol_ref "optimize_size")
19791                        (const_int 0))
19792                    (const_string "V4SF")
19793                    (const_string "V2DF"))
19794                (eq_attr "alternative" "2")
19795                  (if_then_else
19796                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19797                             (const_int 0))
19798                         (ne (symbol_ref "optimize_size")
19799                             (const_int 0)))
19800                    (const_string "V4SF")
19801                    (const_string "V2DF"))]
19802                (const_string "V2DF")))])
19803
19804 (define_split
19805   [(set (match_operand:V2DF 0 "register_operand" "")
19806         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19807   "TARGET_SSE2 && reload_completed"
19808   [(set (match_dup 0)
19809         (vec_merge:V2DF
19810          (vec_duplicate:V2DF (match_dup 1))
19811          (match_dup 2)
19812          (const_int 1)))]
19813 {
19814   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19815   operands[2] = CONST0_RTX (V2DFmode);
19816 })
19817
19818 ;; 16 byte integral modes handled by SSE, minus TImode, which gets
19819 ;; special-cased for TARGET_64BIT.
19820 (define_mode_macro SSEINT16 [V16QI V8HI V4SI V2DI])
19821
19822 (define_expand "mov<mode>"
19823   [(set (match_operand:SSEINT16 0 "nonimmediate_operand" "")
19824         (match_operand:SSEINT16 1 "nonimmediate_operand" ""))]
19825   "TARGET_SSE"
19826 {
19827   ix86_expand_vector_move (<MODE>mode, operands);
19828   DONE;
19829 })
19830
19831 (define_insn "*mov<mode>_internal"
19832   [(set (match_operand:SSEINT16 0 "nonimmediate_operand" "=x,x ,m")
19833         (match_operand:SSEINT16 1 "vector_move_operand"  "C ,xm,x"))]
19834   "TARGET_SSE
19835    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19836 {
19837   switch (which_alternative)
19838     {
19839     case 0:
19840       if (get_attr_mode (insn) == MODE_V4SF)
19841         return "xorps\t%0, %0";
19842       else
19843         return "pxor\t%0, %0";
19844     case 1:
19845     case 2:
19846       if (get_attr_mode (insn) == MODE_V4SF)
19847         return "movaps\t{%1, %0|%0, %1}";
19848       else
19849         return "movdqa\t{%1, %0|%0, %1}";
19850     default:
19851       abort ();
19852     }
19853 }
19854   [(set_attr "type" "ssemov")
19855    (set (attr "mode")
19856         (cond [(eq_attr "alternative" "0,1")
19857                  (if_then_else
19858                    (ne (symbol_ref "optimize_size")
19859                        (const_int 0))
19860                    (const_string "V4SF")
19861                    (const_string "TI"))
19862                (eq_attr "alternative" "2")
19863                  (if_then_else
19864                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19865                             (const_int 0))
19866                         (ne (symbol_ref "optimize_size")
19867                             (const_int 0)))
19868                    (const_string "V4SF")
19869                    (const_string "TI"))]
19870                (const_string "TI")))])
19871
19872 ;; 8 byte integral modes handled by MMX (and by extension, SSE)
19873 (define_mode_macro MMXINT8 [V8QI V4HI V2SI])
19874
19875 (define_expand "mov<mode>"
19876   [(set (match_operand:MMXINT8 0 "nonimmediate_operand" "")
19877         (match_operand:MMXINT8 1 "nonimmediate_operand" ""))]
19878   "TARGET_MMX"
19879 {
19880   ix86_expand_vector_move (<MODE>mode, operands);
19881   DONE;
19882 })
19883
19884 (define_insn "*mov<mode>_internal"
19885   [(set (match_operand:MMXINT8 0 "nonimmediate_operand"
19886                                         "=y,y ,m,!y,!*Y,*x,?*x,?m")
19887         (match_operand:MMXINT8 1 "vector_move_operand"
19888                                         "C ,ym,y,*Y,y  ,C ,*xm,*x"))]
19889   "TARGET_MMX
19890    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19891   "@
19892     pxor\t%0, %0
19893     movq\t{%1, %0|%0, %1}
19894     movq\t{%1, %0|%0, %1}
19895     movdq2q\t{%1, %0|%0, %1}
19896     movq2dq\t{%1, %0|%0, %1}
19897     pxor\t%0, %0
19898     movq\t{%1, %0|%0, %1}
19899     movq\t{%1, %0|%0, %1}"
19900   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
19901    (set_attr "mode" "DI")])
19902
19903 (define_expand "movv2sf"
19904   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19905         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19906   "TARGET_MMX"
19907 {
19908   ix86_expand_vector_move (V2SFmode, operands);
19909   DONE;
19910 })
19911
19912 (define_insn "*movv2sf_internal"
19913   [(set (match_operand:V2SF 0 "nonimmediate_operand"
19914                                         "=y,y ,m,!y,!*Y,*x,?*x,?m")
19915         (match_operand:V2SF 1 "vector_move_operand"
19916                                         "C ,ym,y,*Y,y  ,C ,*xm,*x"))]
19917   "TARGET_MMX
19918    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19919   "@
19920     pxor\t%0, %0
19921     movq\t{%1, %0|%0, %1}
19922     movq\t{%1, %0|%0, %1}
19923     movdq2q\t{%1, %0|%0, %1}
19924     movq2dq\t{%1, %0|%0, %1}
19925     xorps\t%0, %0
19926     movlps\t{%1, %0|%0, %1}
19927     movlps\t{%1, %0|%0, %1}"
19928   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
19929    (set_attr "mode" "DI,DI,DI,DI,DI,V4SF,V2SF,V2SF")])
19930
19931 (define_expand "movti"
19932   [(set (match_operand:TI 0 "nonimmediate_operand" "")
19933         (match_operand:TI 1 "nonimmediate_operand" ""))]
19934   "TARGET_SSE || TARGET_64BIT"
19935 {
19936   if (TARGET_64BIT)
19937     ix86_expand_move (TImode, operands);
19938   else
19939     ix86_expand_vector_move (TImode, operands);
19940   DONE;
19941 })
19942
19943 (define_insn "*movti_internal"
19944   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19945         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19946   "TARGET_SSE && !TARGET_64BIT
19947    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19948 {
19949   switch (which_alternative)
19950     {
19951     case 0:
19952       if (get_attr_mode (insn) == MODE_V4SF)
19953         return "xorps\t%0, %0";
19954       else
19955         return "pxor\t%0, %0";
19956     case 1:
19957     case 2:
19958       if (get_attr_mode (insn) == MODE_V4SF)
19959         return "movaps\t{%1, %0|%0, %1}";
19960       else
19961         return "movdqa\t{%1, %0|%0, %1}";
19962     default:
19963       abort ();
19964     }
19965 }
19966   [(set_attr "type" "ssemov,ssemov,ssemov")
19967    (set (attr "mode")
19968         (cond [(eq_attr "alternative" "0,1")
19969                  (if_then_else
19970                    (ne (symbol_ref "optimize_size")
19971                        (const_int 0))
19972                    (const_string "V4SF")
19973                    (const_string "TI"))
19974                (eq_attr "alternative" "2")
19975                  (if_then_else
19976                    (ne (symbol_ref "optimize_size")
19977                        (const_int 0))
19978                    (const_string "V4SF")
19979                    (const_string "TI"))]
19980                (const_string "TI")))])
19981
19982 (define_insn "*movti_rex64"
19983   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19984         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19985   "TARGET_64BIT
19986    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19987 {
19988   switch (which_alternative)
19989     {
19990     case 0:
19991     case 1:
19992       return "#";
19993     case 2:
19994       if (get_attr_mode (insn) == MODE_V4SF)
19995         return "xorps\t%0, %0";
19996       else
19997         return "pxor\t%0, %0";
19998     case 3:
19999     case 4:
20000       if (get_attr_mode (insn) == MODE_V4SF)
20001         return "movaps\t{%1, %0|%0, %1}";
20002       else
20003         return "movdqa\t{%1, %0|%0, %1}";
20004     default:
20005       abort ();
20006     }
20007 }
20008   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20009    (set (attr "mode")
20010         (cond [(eq_attr "alternative" "2,3")
20011                  (if_then_else
20012                    (ne (symbol_ref "optimize_size")
20013                        (const_int 0))
20014                    (const_string "V4SF")
20015                    (const_string "TI"))
20016                (eq_attr "alternative" "4")
20017                  (if_then_else
20018                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20019                             (const_int 0))
20020                         (ne (symbol_ref "optimize_size")
20021                             (const_int 0)))
20022                    (const_string "V4SF")
20023                    (const_string "TI"))]
20024                (const_string "DI")))])
20025
20026 (define_expand "movtf"
20027   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20028         (match_operand:TF 1 "nonimmediate_operand" ""))]
20029   "TARGET_64BIT"
20030 {
20031   ix86_expand_move (TFmode, operands);
20032   DONE;
20033 })
20034
20035 (define_insn "*movtf_internal"
20036   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20037         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20038   "TARGET_64BIT
20039    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20040 {
20041   switch (which_alternative)
20042     {
20043     case 0:
20044     case 1:
20045       return "#";
20046     case 2:
20047       if (get_attr_mode (insn) == MODE_V4SF)
20048         return "xorps\t%0, %0";
20049       else
20050         return "pxor\t%0, %0";
20051     case 3:
20052     case 4:
20053       if (get_attr_mode (insn) == MODE_V4SF)
20054         return "movaps\t{%1, %0|%0, %1}";
20055       else
20056         return "movdqa\t{%1, %0|%0, %1}";
20057     default:
20058       abort ();
20059     }
20060 }
20061   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20062    (set (attr "mode")
20063         (cond [(eq_attr "alternative" "2,3")
20064                  (if_then_else
20065                    (ne (symbol_ref "optimize_size")
20066                        (const_int 0))
20067                    (const_string "V4SF")
20068                    (const_string "TI"))
20069                (eq_attr "alternative" "4")
20070                  (if_then_else
20071                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20072                             (const_int 0))
20073                         (ne (symbol_ref "optimize_size")
20074                             (const_int 0)))
20075                    (const_string "V4SF")
20076                    (const_string "TI"))]
20077                (const_string "DI")))])
20078
20079 (define_mode_macro SSEPUSH [V16QI V8HI V4SI V2DI TI V4SF V2DF])
20080
20081 (define_insn "*push<mode>"
20082   [(set (match_operand:SSEPUSH 0 "push_operand" "=<")
20083         (match_operand:SSEPUSH 1 "register_operand" "x"))]
20084   "TARGET_SSE"
20085   "#")
20086
20087 (define_mode_macro MMXPUSH [V8QI V4HI V2SI V2SF])
20088
20089 (define_insn "*push<mode>"
20090   [(set (match_operand:MMXPUSH 0 "push_operand" "=<")
20091         (match_operand:MMXPUSH 1 "register_operand" "xy"))]
20092   "TARGET_MMX"
20093   "#")
20094
20095 (define_split
20096   [(set (match_operand 0 "push_operand" "")
20097         (match_operand 1 "register_operand" ""))]
20098   "!TARGET_64BIT && reload_completed
20099    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20100   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20101    (set (match_dup 2) (match_dup 1))]
20102   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20103                                  stack_pointer_rtx);
20104    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20105
20106 (define_split
20107   [(set (match_operand 0 "push_operand" "")
20108         (match_operand 1 "register_operand" ""))]
20109   "TARGET_64BIT && reload_completed
20110    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20111   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20112    (set (match_dup 2) (match_dup 1))]
20113   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20114                                  stack_pointer_rtx);
20115    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20116
20117
20118 (define_split
20119   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20120         (match_operand:TI 1 "general_operand" ""))]
20121   "reload_completed && !SSE_REG_P (operands[0])
20122    && !SSE_REG_P (operands[1])"
20123   [(const_int 0)]
20124   "ix86_split_long_move (operands); DONE;")
20125
20126 (define_split
20127   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20128         (match_operand:TF 1 "general_operand" ""))]
20129   "reload_completed && !SSE_REG_P (operands[0])
20130    && !SSE_REG_P (operands[1])"
20131   [(const_int 0)]
20132   "ix86_split_long_move (operands); DONE;")
20133
20134 ;; These two patterns are useful for specifying exactly whether to use
20135 ;; movaps or movups
20136 (define_expand "sse_movaps"
20137   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20138         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20139                      UNSPEC_MOVA))]
20140   "TARGET_SSE"
20141 {
20142   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20143     {
20144       rtx tmp = gen_reg_rtx (V4SFmode);
20145       emit_insn (gen_sse_movaps (tmp, operands[1]));
20146       emit_move_insn (operands[0], tmp);
20147       DONE;
20148     }
20149 })
20150
20151 (define_insn "*sse_movaps_1"
20152   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20153         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20154                      UNSPEC_MOVA))]
20155   "TARGET_SSE
20156    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20157   "movaps\t{%1, %0|%0, %1}"
20158   [(set_attr "type" "ssemov,ssemov")
20159    (set_attr "mode" "V4SF")])
20160
20161 (define_expand "sse_movups"
20162   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20163         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20164                      UNSPEC_MOVU))]
20165   "TARGET_SSE"
20166 {
20167   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20168     {
20169       rtx tmp = gen_reg_rtx (V4SFmode);
20170       emit_insn (gen_sse_movups (tmp, operands[1]));
20171       emit_move_insn (operands[0], tmp);
20172       DONE;
20173     }
20174 })
20175
20176 (define_insn "*sse_movups_1"
20177   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20178         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20179                      UNSPEC_MOVU))]
20180   "TARGET_SSE
20181    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20182   "movups\t{%1, %0|%0, %1}"
20183   [(set_attr "type" "ssecvt,ssecvt")
20184    (set_attr "mode" "V4SF")])
20185
20186 ;; SSE Strange Moves.
20187
20188 (define_insn "sse_movmskps"
20189   [(set (match_operand:SI 0 "register_operand" "=r")
20190         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20191                    UNSPEC_MOVMSK))]
20192   "TARGET_SSE"
20193   "movmskps\t{%1, %0|%0, %1}"
20194   [(set_attr "type" "ssecvt")
20195    (set_attr "mode" "V4SF")])
20196
20197 (define_insn "mmx_pmovmskb"
20198   [(set (match_operand:SI 0 "register_operand" "=r")
20199         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20200                    UNSPEC_MOVMSK))]
20201   "TARGET_SSE || TARGET_3DNOW_A"
20202   "pmovmskb\t{%1, %0|%0, %1}"
20203   [(set_attr "type" "ssecvt")
20204    (set_attr "mode" "V4SF")])
20205
20206
20207 (define_insn "mmx_maskmovq"
20208   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20209         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20210                       (match_operand:V8QI 2 "register_operand" "y")]
20211                      UNSPEC_MASKMOV))]
20212   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20213   ;; @@@ check ordering of operands in intel/nonintel syntax
20214   "maskmovq\t{%2, %1|%1, %2}"
20215   [(set_attr "type" "mmxcvt")
20216    (set_attr "mode" "DI")])
20217
20218 (define_insn "mmx_maskmovq_rex"
20219   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20220         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20221                       (match_operand:V8QI 2 "register_operand" "y")]
20222                      UNSPEC_MASKMOV))]
20223   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20224   ;; @@@ check ordering of operands in intel/nonintel syntax
20225   "maskmovq\t{%2, %1|%1, %2}"
20226   [(set_attr "type" "mmxcvt")
20227    (set_attr "mode" "DI")])
20228
20229 (define_insn "sse_movntv4sf"
20230   [(set (match_operand:V4SF 0 "memory_operand" "=m")
20231         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20232                      UNSPEC_MOVNT))]
20233   "TARGET_SSE"
20234   "movntps\t{%1, %0|%0, %1}"
20235   [(set_attr "type" "ssemov")
20236    (set_attr "mode" "V4SF")])
20237
20238 (define_insn "sse_movntdi"
20239   [(set (match_operand:DI 0 "memory_operand" "=m")
20240         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20241                    UNSPEC_MOVNT))]
20242   "TARGET_SSE || TARGET_3DNOW_A"
20243   "movntq\t{%1, %0|%0, %1}"
20244   [(set_attr "type" "mmxmov")
20245    (set_attr "mode" "DI")])
20246
20247 (define_insn "sse_movhlps"
20248   [(set (match_operand:V4SF 0 "register_operand" "=x")
20249         (vec_merge:V4SF
20250          (match_operand:V4SF 1 "register_operand" "0")
20251          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20252                           (parallel [(const_int 2)
20253                                      (const_int 3)
20254                                      (const_int 0)
20255                                      (const_int 1)]))
20256          (const_int 3)))]
20257   "TARGET_SSE"
20258   "movhlps\t{%2, %0|%0, %2}"
20259   [(set_attr "type" "ssecvt")
20260    (set_attr "mode" "V4SF")])
20261
20262 (define_insn "sse_movlhps"
20263   [(set (match_operand:V4SF 0 "register_operand" "=x")
20264         (vec_merge:V4SF
20265          (match_operand:V4SF 1 "register_operand" "0")
20266          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20267                           (parallel [(const_int 2)
20268                                      (const_int 3)
20269                                      (const_int 0)
20270                                      (const_int 1)]))
20271          (const_int 12)))]
20272   "TARGET_SSE"
20273   "movlhps\t{%2, %0|%0, %2}"
20274   [(set_attr "type" "ssecvt")
20275    (set_attr "mode" "V4SF")])
20276
20277 (define_insn "sse_movhps"
20278   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20279         (vec_merge:V4SF
20280          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20281          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20282          (const_int 12)))]
20283   "TARGET_SSE
20284    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20285   "movhps\t{%2, %0|%0, %2}"
20286   [(set_attr "type" "ssecvt")
20287    (set_attr "mode" "V4SF")])
20288
20289 (define_insn "sse_movlps"
20290   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20291         (vec_merge:V4SF
20292          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20293          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20294          (const_int 3)))]
20295   "TARGET_SSE
20296    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20297   "movlps\t{%2, %0|%0, %2}"
20298   [(set_attr "type" "ssecvt")
20299    (set_attr "mode" "V4SF")])
20300
20301 (define_expand "sse_loadss"
20302   [(match_operand:V4SF 0 "register_operand" "")
20303    (match_operand:SF 1 "memory_operand" "")]
20304   "TARGET_SSE"
20305 {
20306   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20307                                CONST0_RTX (V4SFmode)));
20308   DONE;
20309 })
20310
20311 (define_insn "sse_loadss_1"
20312   [(set (match_operand:V4SF 0 "register_operand" "=x")
20313         (vec_merge:V4SF
20314          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20315          (match_operand:V4SF 2 "const0_operand" "X")
20316          (const_int 1)))]
20317   "TARGET_SSE"
20318   "movss\t{%1, %0|%0, %1}"
20319   [(set_attr "type" "ssemov")
20320    (set_attr "mode" "SF")])
20321
20322 (define_insn "sse_movss"
20323   [(set (match_operand:V4SF 0 "register_operand" "=x")
20324         (vec_merge:V4SF
20325          (match_operand:V4SF 1 "register_operand" "0")
20326          (match_operand:V4SF 2 "register_operand" "x")
20327          (const_int 14)))]
20328   "TARGET_SSE"
20329   "movss\t{%2, %0|%0, %2}"
20330   [(set_attr "type" "ssemov")
20331    (set_attr "mode" "SF")])
20332
20333 (define_insn "sse_storess"
20334   [(set (match_operand:SF 0 "memory_operand" "=m")
20335         (vec_select:SF
20336          (match_operand:V4SF 1 "register_operand" "x")
20337          (parallel [(const_int 0)])))]
20338   "TARGET_SSE"
20339   "movss\t{%1, %0|%0, %1}"
20340   [(set_attr "type" "ssemov")
20341    (set_attr "mode" "SF")])
20342
20343 (define_insn "sse_shufps"
20344   [(set (match_operand:V4SF 0 "register_operand" "=x")
20345         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20346                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20347                       (match_operand:SI 3 "immediate_operand" "i")]
20348                      UNSPEC_SHUFFLE))]
20349   "TARGET_SSE"
20350   ;; @@@ check operand order for intel/nonintel syntax
20351   "shufps\t{%3, %2, %0|%0, %2, %3}"
20352   [(set_attr "type" "ssecvt")
20353    (set_attr "mode" "V4SF")])
20354
20355
20356 ;; SSE arithmetic
20357
20358 (define_insn "addv4sf3"
20359   [(set (match_operand:V4SF 0 "register_operand" "=x")
20360         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20361                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20362   "TARGET_SSE"
20363   "addps\t{%2, %0|%0, %2}"
20364   [(set_attr "type" "sseadd")
20365    (set_attr "mode" "V4SF")])
20366
20367 (define_insn "vmaddv4sf3"
20368   [(set (match_operand:V4SF 0 "register_operand" "=x")
20369         (vec_merge:V4SF
20370          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20371                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20372          (match_dup 1)
20373          (const_int 1)))]
20374   "TARGET_SSE"
20375   "addss\t{%2, %0|%0, %2}"
20376   [(set_attr "type" "sseadd")
20377    (set_attr "mode" "SF")])
20378
20379 (define_insn "subv4sf3"
20380   [(set (match_operand:V4SF 0 "register_operand" "=x")
20381         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20382                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20383   "TARGET_SSE"
20384   "subps\t{%2, %0|%0, %2}"
20385   [(set_attr "type" "sseadd")
20386    (set_attr "mode" "V4SF")])
20387
20388 (define_insn "vmsubv4sf3"
20389   [(set (match_operand:V4SF 0 "register_operand" "=x")
20390         (vec_merge:V4SF
20391          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20392                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20393          (match_dup 1)
20394          (const_int 1)))]
20395   "TARGET_SSE"
20396   "subss\t{%2, %0|%0, %2}"
20397   [(set_attr "type" "sseadd")
20398    (set_attr "mode" "SF")])
20399
20400 ;; ??? Should probably be done by generic code instead.
20401 (define_expand "negv4sf2"
20402   [(set (match_operand:V4SF 0 "register_operand" "")
20403         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20404                   (match_dup 2)))]
20405   "TARGET_SSE"
20406 {
20407   rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20408   rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20409   operands[2] = force_reg (V4SFmode, vm0);
20410 })
20411
20412 (define_insn "mulv4sf3"
20413   [(set (match_operand:V4SF 0 "register_operand" "=x")
20414         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20415                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20416   "TARGET_SSE"
20417   "mulps\t{%2, %0|%0, %2}"
20418   [(set_attr "type" "ssemul")
20419    (set_attr "mode" "V4SF")])
20420
20421 (define_insn "vmmulv4sf3"
20422   [(set (match_operand:V4SF 0 "register_operand" "=x")
20423         (vec_merge:V4SF
20424          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20425                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20426          (match_dup 1)
20427          (const_int 1)))]
20428   "TARGET_SSE"
20429   "mulss\t{%2, %0|%0, %2}"
20430   [(set_attr "type" "ssemul")
20431    (set_attr "mode" "SF")])
20432
20433 (define_insn "divv4sf3"
20434   [(set (match_operand:V4SF 0 "register_operand" "=x")
20435         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20436                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20437   "TARGET_SSE"
20438   "divps\t{%2, %0|%0, %2}"
20439   [(set_attr "type" "ssediv")
20440    (set_attr "mode" "V4SF")])
20441
20442 (define_insn "vmdivv4sf3"
20443   [(set (match_operand:V4SF 0 "register_operand" "=x")
20444         (vec_merge:V4SF
20445          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20446                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20447          (match_dup 1)
20448          (const_int 1)))]
20449   "TARGET_SSE"
20450   "divss\t{%2, %0|%0, %2}"
20451   [(set_attr "type" "ssediv")
20452    (set_attr "mode" "SF")])
20453
20454
20455 ;; SSE square root/reciprocal
20456
20457 (define_insn "rcpv4sf2"
20458   [(set (match_operand:V4SF 0 "register_operand" "=x")
20459         (unspec:V4SF
20460          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20461   "TARGET_SSE"
20462   "rcpps\t{%1, %0|%0, %1}"
20463   [(set_attr "type" "sse")
20464    (set_attr "mode" "V4SF")])
20465
20466 (define_insn "vmrcpv4sf2"
20467   [(set (match_operand:V4SF 0 "register_operand" "=x")
20468         (vec_merge:V4SF
20469          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20470                       UNSPEC_RCP)
20471          (match_operand:V4SF 2 "register_operand" "0")
20472          (const_int 1)))]
20473   "TARGET_SSE"
20474   "rcpss\t{%1, %0|%0, %1}"
20475   [(set_attr "type" "sse")
20476    (set_attr "mode" "SF")])
20477
20478 (define_insn "rsqrtv4sf2"
20479   [(set (match_operand:V4SF 0 "register_operand" "=x")
20480         (unspec:V4SF
20481          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20482   "TARGET_SSE"
20483   "rsqrtps\t{%1, %0|%0, %1}"
20484   [(set_attr "type" "sse")
20485    (set_attr "mode" "V4SF")])
20486
20487 (define_insn "vmrsqrtv4sf2"
20488   [(set (match_operand:V4SF 0 "register_operand" "=x")
20489         (vec_merge:V4SF
20490          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20491                       UNSPEC_RSQRT)
20492          (match_operand:V4SF 2 "register_operand" "0")
20493          (const_int 1)))]
20494   "TARGET_SSE"
20495   "rsqrtss\t{%1, %0|%0, %1}"
20496   [(set_attr "type" "sse")
20497    (set_attr "mode" "SF")])
20498
20499 (define_insn "sqrtv4sf2"
20500   [(set (match_operand:V4SF 0 "register_operand" "=x")
20501         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20502   "TARGET_SSE"
20503   "sqrtps\t{%1, %0|%0, %1}"
20504   [(set_attr "type" "sse")
20505    (set_attr "mode" "V4SF")])
20506
20507 (define_insn "vmsqrtv4sf2"
20508   [(set (match_operand:V4SF 0 "register_operand" "=x")
20509         (vec_merge:V4SF
20510          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20511          (match_operand:V4SF 2 "register_operand" "0")
20512          (const_int 1)))]
20513   "TARGET_SSE"
20514   "sqrtss\t{%1, %0|%0, %1}"
20515   [(set_attr "type" "sse")
20516    (set_attr "mode" "SF")])
20517
20518 ;; SSE logical operations.
20519
20520 ;; SSE defines logical operations on floating point values.  This brings
20521 ;; interesting challenge to RTL representation where logicals are only valid
20522 ;; on integral types.  We deal with this by representing the floating point
20523 ;; logical as logical on arguments casted to TImode as this is what hardware
20524 ;; really does.  Unfortunately hardware requires the type information to be
20525 ;; present and thus we must avoid subregs from being simplified and eliminated
20526 ;; in later compilation phases.
20527 ;;
20528 ;; We have following variants from each instruction:
20529 ;; sse_andsf3 - the operation taking V4SF vector operands
20530 ;;              and doing TImode cast on them
20531 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20532 ;;                      TImode, since backend insist on eliminating casts
20533 ;;                      on memory operands
20534 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20535 ;;                   We cannot accept memory operand here as instruction reads
20536 ;;                   whole scalar.  This is generated only post reload by GCC
20537 ;;                   scalar float operations that expands to logicals (fabs)
20538 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20539 ;;                   memory operand.  Eventually combine can be able
20540 ;;                   to synthesize these using splitter.
20541 ;; sse2_anddf3, *sse2_anddf3_memory
20542 ;;              
20543 ;; 
20544 ;; These are not called andti3 etc. because we really really don't want
20545 ;; the compiler to widen DImode ands to TImode ands and then try to move
20546 ;; into DImode subregs of SSE registers, and them together, and move out
20547 ;; of DImode subregs again!
20548 ;; SSE1 single precision floating point logical operation
20549 (define_expand "sse_andv4sf3"
20550   [(set (match_operand:V4SF 0 "register_operand" "")
20551         (and:V4SF (match_operand:V4SF 1 "register_operand" "")
20552                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20553   "TARGET_SSE"
20554   "")
20555
20556 (define_insn "*sse_andv4sf3"
20557   [(set (match_operand:V4SF 0 "register_operand" "=x")
20558         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20559                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20560   "TARGET_SSE
20561    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20562   "andps\t{%2, %0|%0, %2}"
20563   [(set_attr "type" "sselog")
20564    (set_attr "mode" "V4SF")])
20565
20566 (define_expand "sse_nandv4sf3"
20567   [(set (match_operand:V4SF 0 "register_operand" "")
20568         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
20569                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20570   "TARGET_SSE"
20571   "")
20572
20573 (define_insn "*sse_nandv4sf3"
20574   [(set (match_operand:V4SF 0 "register_operand" "=x")
20575         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
20576                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20577   "TARGET_SSE"
20578   "andnps\t{%2, %0|%0, %2}"
20579   [(set_attr "type" "sselog")
20580    (set_attr "mode" "V4SF")])
20581
20582 (define_expand "sse_iorv4sf3"
20583   [(set (match_operand:V4SF 0 "register_operand" "")
20584         (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
20585                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20586   "TARGET_SSE"
20587   "")
20588
20589 (define_insn "*sse_iorv4sf3"
20590   [(set (match_operand:V4SF 0 "register_operand" "=x")
20591         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20592                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20593   "TARGET_SSE
20594    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20595   "orps\t{%2, %0|%0, %2}"
20596   [(set_attr "type" "sselog")
20597    (set_attr "mode" "V4SF")])
20598
20599 (define_expand "sse_xorv4sf3"
20600   [(set (match_operand:V4SF 0 "register_operand" "")
20601         (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
20602                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20603   "TARGET_SSE"
20604   "")
20605
20606 (define_insn "*sse_xorv4sf3"
20607   [(set (match_operand:V4SF 0 "register_operand" "=x")
20608         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20609                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20610   "TARGET_SSE
20611    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20612   "xorps\t{%2, %0|%0, %2}"
20613   [(set_attr "type" "sselog")
20614    (set_attr "mode" "V4SF")])
20615
20616 ;; SSE2 double precision floating point logical operation
20617
20618 (define_expand "sse2_andv2df3"
20619   [(set (match_operand:V2DF 0 "register_operand" "")
20620         (and:V2DF (match_operand:V2DF 1 "register_operand" "")
20621                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20622   "TARGET_SSE2"
20623   "")
20624
20625 (define_insn "*sse2_andv2df3"
20626   [(set (match_operand:V2DF 0 "register_operand" "=x")
20627         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20628                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20629   "TARGET_SSE2
20630    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20631   "andpd\t{%2, %0|%0, %2}"
20632   [(set_attr "type" "sselog")
20633    (set_attr "mode" "V2DF")])
20634
20635 (define_expand "sse2_nandv2df3"
20636   [(set (match_operand:V2DF 0 "register_operand" "")
20637         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
20638                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20639   "TARGET_SSE2"
20640   "")
20641
20642 (define_insn "*sse2_nandv2df3"
20643   [(set (match_operand:V2DF 0 "register_operand" "=x")
20644         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
20645                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20646   "TARGET_SSE2"
20647   "andnpd\t{%2, %0|%0, %2}"
20648   [(set_attr "type" "sselog")
20649    (set_attr "mode" "V2DF")])
20650
20651 (define_expand "sse2_iorv2df3"
20652   [(set (match_operand:V2DF 0 "register_operand" "")
20653         (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
20654                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20655   "TARGET_SSE2"
20656   "")
20657
20658 (define_insn "*sse2_iorv2df3"
20659   [(set (match_operand:V2DF 0 "register_operand" "=x")
20660         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20661                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20662   "TARGET_SSE2
20663    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20664   "orpd\t{%2, %0|%0, %2}"
20665   [(set_attr "type" "sselog")
20666    (set_attr "mode" "V2DF")])
20667
20668 (define_expand "sse2_xorv2df3"
20669   [(set (match_operand:V2DF 0 "register_operand" "")
20670         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
20671                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20672   "TARGET_SSE2"
20673   "")
20674
20675 (define_insn "*sse2_xorv2df3"
20676   [(set (match_operand:V2DF 0 "register_operand" "=x")
20677         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20678                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20679   "TARGET_SSE2
20680    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20681   "xorpd\t{%2, %0|%0, %2}"
20682   [(set_attr "type" "sselog")
20683    (set_attr "mode" "V2DF")])
20684
20685 ;; SSE2 integral logicals.  These patterns must always come after floating
20686 ;; point ones since we don't want compiler to use integer opcodes on floating
20687 ;; point SSE values to avoid matching of subregs in the match_operand.
20688 (define_insn "*sse2_andti3"
20689   [(set (match_operand:TI 0 "register_operand" "=x")
20690         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20691                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20692   "TARGET_SSE2
20693    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20694   "pand\t{%2, %0|%0, %2}"
20695   [(set_attr "type" "sselog")
20696    (set_attr "mode" "TI")])
20697
20698 (define_insn "sse2_andv2di3"
20699   [(set (match_operand:V2DI 0 "register_operand" "=x")
20700         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20701                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20702   "TARGET_SSE2
20703    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20704   "pand\t{%2, %0|%0, %2}"
20705   [(set_attr "type" "sselog")
20706    (set_attr "mode" "TI")])
20707
20708 (define_insn "*sse2_nandti3"
20709   [(set (match_operand:TI 0 "register_operand" "=x")
20710         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20711                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20712   "TARGET_SSE2"
20713   "pandn\t{%2, %0|%0, %2}"
20714   [(set_attr "type" "sselog")
20715    (set_attr "mode" "TI")])
20716
20717 (define_insn "sse2_nandv2di3"
20718   [(set (match_operand:V2DI 0 "register_operand" "=x")
20719         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20720                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20721   "TARGET_SSE2
20722    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20723   "pandn\t{%2, %0|%0, %2}"
20724   [(set_attr "type" "sselog")
20725    (set_attr "mode" "TI")])
20726
20727 (define_insn "*sse2_iorti3"
20728   [(set (match_operand:TI 0 "register_operand" "=x")
20729         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20730                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20731   "TARGET_SSE2
20732    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20733   "por\t{%2, %0|%0, %2}"
20734   [(set_attr "type" "sselog")
20735    (set_attr "mode" "TI")])
20736
20737 (define_insn "sse2_iorv2di3"
20738   [(set (match_operand:V2DI 0 "register_operand" "=x")
20739         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20740                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20741   "TARGET_SSE2
20742    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20743   "por\t{%2, %0|%0, %2}"
20744   [(set_attr "type" "sselog")
20745    (set_attr "mode" "TI")])
20746
20747 (define_insn "*sse2_xorti3"
20748   [(set (match_operand:TI 0 "register_operand" "=x")
20749         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20750                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20751   "TARGET_SSE2
20752    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20753   "pxor\t{%2, %0|%0, %2}"
20754   [(set_attr "type" "sselog")
20755    (set_attr "mode" "TI")])
20756
20757 (define_insn "sse2_xorv2di3"
20758   [(set (match_operand:V2DI 0 "register_operand" "=x")
20759         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20760                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20761   "TARGET_SSE2
20762    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20763   "pxor\t{%2, %0|%0, %2}"
20764   [(set_attr "type" "sselog")
20765    (set_attr "mode" "TI")])
20766
20767 ;; Use xor, but don't show input operands so they aren't live before
20768 ;; this insn.
20769 (define_insn "sse_clrv4sf"
20770   [(set (match_operand:V4SF 0 "register_operand" "=x")
20771         (match_operand:V4SF 1 "const0_operand" "X"))]
20772   "TARGET_SSE"
20773 {
20774   if (get_attr_mode (insn) == MODE_TI)
20775     return "pxor\t{%0, %0|%0, %0}";
20776   else
20777     return "xorps\t{%0, %0|%0, %0}";
20778 }
20779   [(set_attr "type" "sselog")
20780    (set_attr "memory" "none")
20781    (set (attr "mode")
20782         (if_then_else
20783            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
20784                          (const_int 0))
20785                      (ne (symbol_ref "TARGET_SSE2")
20786                          (const_int 0)))
20787                 (eq (symbol_ref "optimize_size")
20788                     (const_int 0)))
20789          (const_string "TI")
20790          (const_string "V4SF")))])
20791
20792 ;; Use xor, but don't show input operands so they aren't live before
20793 ;; this insn.
20794 (define_insn "sse_clrv2df"
20795   [(set (match_operand:V2DF 0 "register_operand" "=x")
20796         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
20797   "TARGET_SSE2"
20798   "xorpd\t{%0, %0|%0, %0}"
20799   [(set_attr "type" "sselog")
20800    (set_attr "memory" "none")
20801    (set_attr "mode" "V4SF")])
20802
20803 ;; SSE mask-generating compares
20804
20805 (define_insn "maskcmpv4sf3"
20806   [(set (match_operand:V4SI 0 "register_operand" "=x")
20807         (match_operator:V4SI 3 "sse_comparison_operator"
20808                 [(match_operand:V4SF 1 "register_operand" "0")
20809                  (match_operand:V4SF 2 "register_operand" "x")]))]
20810   "TARGET_SSE"
20811   "cmp%D3ps\t{%2, %0|%0, %2}"
20812   [(set_attr "type" "ssecmp")
20813    (set_attr "mode" "V4SF")])
20814
20815 (define_insn "maskncmpv4sf3"
20816   [(set (match_operand:V4SI 0 "register_operand" "=x")
20817         (not:V4SI
20818          (match_operator:V4SI 3 "sse_comparison_operator"
20819                 [(match_operand:V4SF 1 "register_operand" "0")
20820                  (match_operand:V4SF 2 "register_operand" "x")])))]
20821   "TARGET_SSE"
20822 {
20823   if (GET_CODE (operands[3]) == UNORDERED)
20824     return "cmpordps\t{%2, %0|%0, %2}";
20825   else
20826     return "cmpn%D3ps\t{%2, %0|%0, %2}";
20827 }
20828   [(set_attr "type" "ssecmp")
20829    (set_attr "mode" "V4SF")])
20830
20831 (define_insn "vmmaskcmpv4sf3"
20832   [(set (match_operand:V4SI 0 "register_operand" "=x")
20833         (vec_merge:V4SI
20834          (match_operator:V4SI 3 "sse_comparison_operator"
20835                 [(match_operand:V4SF 1 "register_operand" "0")
20836                  (match_operand:V4SF 2 "register_operand" "x")])
20837          (subreg:V4SI (match_dup 1) 0)
20838          (const_int 1)))]
20839   "TARGET_SSE"
20840   "cmp%D3ss\t{%2, %0|%0, %2}"
20841   [(set_attr "type" "ssecmp")
20842    (set_attr "mode" "SF")])
20843
20844 (define_insn "vmmaskncmpv4sf3"
20845   [(set (match_operand:V4SI 0 "register_operand" "=x")
20846         (vec_merge:V4SI
20847          (not:V4SI
20848           (match_operator:V4SI 3 "sse_comparison_operator"
20849                 [(match_operand:V4SF 1 "register_operand" "0")
20850                  (match_operand:V4SF 2 "register_operand" "x")]))
20851          (subreg:V4SI (match_dup 1) 0)
20852          (const_int 1)))]
20853   "TARGET_SSE"
20854 {
20855   if (GET_CODE (operands[3]) == UNORDERED)
20856     return "cmpordss\t{%2, %0|%0, %2}";
20857   else
20858     return "cmpn%D3ss\t{%2, %0|%0, %2}";
20859 }
20860   [(set_attr "type" "ssecmp")
20861    (set_attr "mode" "SF")])
20862
20863 (define_insn "sse_comi"
20864   [(set (reg:CCFP FLAGS_REG)
20865         (compare:CCFP (vec_select:SF
20866                        (match_operand:V4SF 0 "register_operand" "x")
20867                        (parallel [(const_int 0)]))
20868                       (vec_select:SF
20869                        (match_operand:V4SF 1 "register_operand" "x")
20870                        (parallel [(const_int 0)]))))]
20871   "TARGET_SSE"
20872   "comiss\t{%1, %0|%0, %1}"
20873   [(set_attr "type" "ssecomi")
20874    (set_attr "mode" "SF")])
20875
20876 (define_insn "sse_ucomi"
20877   [(set (reg:CCFPU FLAGS_REG)
20878         (compare:CCFPU (vec_select:SF
20879                         (match_operand:V4SF 0 "register_operand" "x")
20880                         (parallel [(const_int 0)]))
20881                        (vec_select:SF
20882                         (match_operand:V4SF 1 "register_operand" "x")
20883                         (parallel [(const_int 0)]))))]
20884   "TARGET_SSE"
20885   "ucomiss\t{%1, %0|%0, %1}"
20886   [(set_attr "type" "ssecomi")
20887    (set_attr "mode" "SF")])
20888
20889
20890 ;; SSE unpack
20891
20892 (define_insn "sse_unpckhps"
20893   [(set (match_operand:V4SF 0 "register_operand" "=x")
20894         (vec_merge:V4SF
20895          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20896                           (parallel [(const_int 2)
20897                                      (const_int 0)
20898                                      (const_int 3)
20899                                      (const_int 1)]))
20900          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20901                           (parallel [(const_int 0)
20902                                      (const_int 2)
20903                                      (const_int 1)
20904                                      (const_int 3)]))
20905          (const_int 5)))]
20906   "TARGET_SSE"
20907   "unpckhps\t{%2, %0|%0, %2}"
20908   [(set_attr "type" "ssecvt")
20909    (set_attr "mode" "V4SF")])
20910
20911 (define_insn "sse_unpcklps"
20912   [(set (match_operand:V4SF 0 "register_operand" "=x")
20913         (vec_merge:V4SF
20914          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20915                           (parallel [(const_int 0)
20916                                      (const_int 2)
20917                                      (const_int 1)
20918                                      (const_int 3)]))
20919          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20920                           (parallel [(const_int 2)
20921                                      (const_int 0)
20922                                      (const_int 3)
20923                                      (const_int 1)]))
20924          (const_int 5)))]
20925   "TARGET_SSE"
20926   "unpcklps\t{%2, %0|%0, %2}"
20927   [(set_attr "type" "ssecvt")
20928    (set_attr "mode" "V4SF")])
20929
20930
20931 ;; SSE min/max
20932
20933 (define_insn "smaxv4sf3"
20934   [(set (match_operand:V4SF 0 "register_operand" "=x")
20935         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20936                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20937   "TARGET_SSE"
20938   "maxps\t{%2, %0|%0, %2}"
20939   [(set_attr "type" "sse")
20940    (set_attr "mode" "V4SF")])
20941
20942 (define_insn "vmsmaxv4sf3"
20943   [(set (match_operand:V4SF 0 "register_operand" "=x")
20944         (vec_merge:V4SF
20945          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20946                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20947          (match_dup 1)
20948          (const_int 1)))]
20949   "TARGET_SSE"
20950   "maxss\t{%2, %0|%0, %2}"
20951   [(set_attr "type" "sse")
20952    (set_attr "mode" "SF")])
20953
20954 (define_insn "sminv4sf3"
20955   [(set (match_operand:V4SF 0 "register_operand" "=x")
20956         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20957                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20958   "TARGET_SSE"
20959   "minps\t{%2, %0|%0, %2}"
20960   [(set_attr "type" "sse")
20961    (set_attr "mode" "V4SF")])
20962
20963 (define_insn "vmsminv4sf3"
20964   [(set (match_operand:V4SF 0 "register_operand" "=x")
20965         (vec_merge:V4SF
20966          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20967                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20968          (match_dup 1)
20969          (const_int 1)))]
20970   "TARGET_SSE"
20971   "minss\t{%2, %0|%0, %2}"
20972   [(set_attr "type" "sse")
20973    (set_attr "mode" "SF")])
20974
20975 ;; SSE <-> integer/MMX conversions
20976
20977 (define_insn "cvtpi2ps"
20978   [(set (match_operand:V4SF 0 "register_operand" "=x")
20979         (vec_merge:V4SF
20980          (match_operand:V4SF 1 "register_operand" "0")
20981          (vec_duplicate:V4SF
20982           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20983          (const_int 12)))]
20984   "TARGET_SSE"
20985   "cvtpi2ps\t{%2, %0|%0, %2}"
20986   [(set_attr "type" "ssecvt")
20987    (set_attr "mode" "V4SF")])
20988
20989 (define_insn "cvtps2pi"
20990   [(set (match_operand:V2SI 0 "register_operand" "=y")
20991         (vec_select:V2SI
20992          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20993          (parallel [(const_int 0) (const_int 1)])))]
20994   "TARGET_SSE"
20995   "cvtps2pi\t{%1, %0|%0, %1}"
20996   [(set_attr "type" "ssecvt")
20997    (set_attr "mode" "V4SF")])
20998
20999 (define_insn "cvttps2pi"
21000   [(set (match_operand:V2SI 0 "register_operand" "=y")
21001         (vec_select:V2SI
21002          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21003                       UNSPEC_FIX)
21004          (parallel [(const_int 0) (const_int 1)])))]
21005   "TARGET_SSE"
21006   "cvttps2pi\t{%1, %0|%0, %1}"
21007   [(set_attr "type" "ssecvt")
21008    (set_attr "mode" "SF")])
21009
21010 (define_insn "cvtsi2ss"
21011   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21012         (vec_merge:V4SF
21013          (match_operand:V4SF 1 "register_operand" "0,0")
21014          (vec_duplicate:V4SF
21015           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21016          (const_int 14)))]
21017   "TARGET_SSE"
21018   "cvtsi2ss\t{%2, %0|%0, %2}"
21019   [(set_attr "type" "sseicvt")
21020    (set_attr "athlon_decode" "vector,double")
21021    (set_attr "mode" "SF")])
21022
21023 (define_insn "cvtsi2ssq"
21024   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21025         (vec_merge:V4SF
21026          (match_operand:V4SF 1 "register_operand" "0,0")
21027          (vec_duplicate:V4SF
21028           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21029          (const_int 14)))]
21030   "TARGET_SSE && TARGET_64BIT"
21031   "cvtsi2ssq\t{%2, %0|%0, %2}"
21032   [(set_attr "type" "sseicvt")
21033    (set_attr "athlon_decode" "vector,double")
21034    (set_attr "mode" "SF")])
21035
21036 (define_insn "cvtss2si"
21037   [(set (match_operand:SI 0 "register_operand" "=r,r")
21038         (vec_select:SI
21039          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21040          (parallel [(const_int 0)])))]
21041   "TARGET_SSE"
21042   "cvtss2si\t{%1, %0|%0, %1}"
21043   [(set_attr "type" "sseicvt")
21044    (set_attr "athlon_decode" "double,vector")
21045    (set_attr "mode" "SI")])
21046
21047 (define_insn "cvtss2siq"
21048   [(set (match_operand:DI 0 "register_operand" "=r,r")
21049         (vec_select:DI
21050          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21051          (parallel [(const_int 0)])))]
21052   "TARGET_SSE"
21053   "cvtss2siq\t{%1, %0|%0, %1}"
21054   [(set_attr "type" "sseicvt")
21055    (set_attr "athlon_decode" "double,vector")
21056    (set_attr "mode" "DI")])
21057
21058 (define_insn "cvttss2si"
21059   [(set (match_operand:SI 0 "register_operand" "=r,r")
21060         (vec_select:SI
21061          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21062                       UNSPEC_FIX)
21063          (parallel [(const_int 0)])))]
21064   "TARGET_SSE"
21065   "cvttss2si\t{%1, %0|%0, %1}"
21066   [(set_attr "type" "sseicvt")
21067    (set_attr "mode" "SF")
21068    (set_attr "athlon_decode" "double,vector")])
21069
21070 (define_insn "cvttss2siq"
21071   [(set (match_operand:DI 0 "register_operand" "=r,r")
21072         (vec_select:DI
21073          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21074                       UNSPEC_FIX)
21075          (parallel [(const_int 0)])))]
21076   "TARGET_SSE && TARGET_64BIT"
21077   "cvttss2siq\t{%1, %0|%0, %1}"
21078   [(set_attr "type" "sseicvt")
21079    (set_attr "mode" "SF")
21080    (set_attr "athlon_decode" "double,vector")])
21081
21082
21083 ;; MMX insns
21084
21085 ;; MMX arithmetic
21086
21087 (define_insn "addv8qi3"
21088   [(set (match_operand:V8QI 0 "register_operand" "=y")
21089         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21090                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21091   "TARGET_MMX"
21092   "paddb\t{%2, %0|%0, %2}"
21093   [(set_attr "type" "mmxadd")
21094    (set_attr "mode" "DI")])
21095
21096 (define_insn "addv4hi3"
21097   [(set (match_operand:V4HI 0 "register_operand" "=y")
21098         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21099                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21100   "TARGET_MMX"
21101   "paddw\t{%2, %0|%0, %2}"
21102   [(set_attr "type" "mmxadd")
21103    (set_attr "mode" "DI")])
21104
21105 (define_insn "addv2si3"
21106   [(set (match_operand:V2SI 0 "register_operand" "=y")
21107         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21108                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21109   "TARGET_MMX"
21110   "paddd\t{%2, %0|%0, %2}"
21111   [(set_attr "type" "mmxadd")
21112    (set_attr "mode" "DI")])
21113
21114 (define_insn "mmx_adddi3"
21115   [(set (match_operand:DI 0 "register_operand" "=y")
21116         (unspec:DI
21117          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21118                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21119          UNSPEC_NOP))]
21120   "TARGET_MMX"
21121   "paddq\t{%2, %0|%0, %2}"
21122   [(set_attr "type" "mmxadd")
21123    (set_attr "mode" "DI")])
21124
21125 (define_insn "ssaddv8qi3"
21126   [(set (match_operand:V8QI 0 "register_operand" "=y")
21127         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21128                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21129   "TARGET_MMX"
21130   "paddsb\t{%2, %0|%0, %2}"
21131   [(set_attr "type" "mmxadd")
21132    (set_attr "mode" "DI")])
21133
21134 (define_insn "ssaddv4hi3"
21135   [(set (match_operand:V4HI 0 "register_operand" "=y")
21136         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21137                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21138   "TARGET_MMX"
21139   "paddsw\t{%2, %0|%0, %2}"
21140   [(set_attr "type" "mmxadd")
21141    (set_attr "mode" "DI")])
21142
21143 (define_insn "usaddv8qi3"
21144   [(set (match_operand:V8QI 0 "register_operand" "=y")
21145         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21146                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21147   "TARGET_MMX"
21148   "paddusb\t{%2, %0|%0, %2}"
21149   [(set_attr "type" "mmxadd")
21150    (set_attr "mode" "DI")])
21151
21152 (define_insn "usaddv4hi3"
21153   [(set (match_operand:V4HI 0 "register_operand" "=y")
21154         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21155                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21156   "TARGET_MMX"
21157   "paddusw\t{%2, %0|%0, %2}"
21158   [(set_attr "type" "mmxadd")
21159    (set_attr "mode" "DI")])
21160
21161 (define_insn "subv8qi3"
21162   [(set (match_operand:V8QI 0 "register_operand" "=y")
21163         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21164                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21165   "TARGET_MMX"
21166   "psubb\t{%2, %0|%0, %2}"
21167   [(set_attr "type" "mmxadd")
21168    (set_attr "mode" "DI")])
21169
21170 (define_insn "subv4hi3"
21171   [(set (match_operand:V4HI 0 "register_operand" "=y")
21172         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21173                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21174   "TARGET_MMX"
21175   "psubw\t{%2, %0|%0, %2}"
21176   [(set_attr "type" "mmxadd")
21177    (set_attr "mode" "DI")])
21178
21179 (define_insn "subv2si3"
21180   [(set (match_operand:V2SI 0 "register_operand" "=y")
21181         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21182                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21183   "TARGET_MMX"
21184   "psubd\t{%2, %0|%0, %2}"
21185   [(set_attr "type" "mmxadd")
21186    (set_attr "mode" "DI")])
21187
21188 (define_insn "mmx_subdi3"
21189   [(set (match_operand:DI 0 "register_operand" "=y")
21190         (unspec:DI
21191          [(minus:DI (match_operand:DI 1 "register_operand" "0")
21192                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21193          UNSPEC_NOP))]
21194   "TARGET_MMX"
21195   "psubq\t{%2, %0|%0, %2}"
21196   [(set_attr "type" "mmxadd")
21197    (set_attr "mode" "DI")])
21198
21199 (define_insn "sssubv8qi3"
21200   [(set (match_operand:V8QI 0 "register_operand" "=y")
21201         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21202                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21203   "TARGET_MMX"
21204   "psubsb\t{%2, %0|%0, %2}"
21205   [(set_attr "type" "mmxadd")
21206    (set_attr "mode" "DI")])
21207
21208 (define_insn "sssubv4hi3"
21209   [(set (match_operand:V4HI 0 "register_operand" "=y")
21210         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21211                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21212   "TARGET_MMX"
21213   "psubsw\t{%2, %0|%0, %2}"
21214   [(set_attr "type" "mmxadd")
21215    (set_attr "mode" "DI")])
21216
21217 (define_insn "ussubv8qi3"
21218   [(set (match_operand:V8QI 0 "register_operand" "=y")
21219         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21220                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21221   "TARGET_MMX"
21222   "psubusb\t{%2, %0|%0, %2}"
21223   [(set_attr "type" "mmxadd")
21224    (set_attr "mode" "DI")])
21225
21226 (define_insn "ussubv4hi3"
21227   [(set (match_operand:V4HI 0 "register_operand" "=y")
21228         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21229                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21230   "TARGET_MMX"
21231   "psubusw\t{%2, %0|%0, %2}"
21232   [(set_attr "type" "mmxadd")
21233    (set_attr "mode" "DI")])
21234
21235 (define_insn "mulv4hi3"
21236   [(set (match_operand:V4HI 0 "register_operand" "=y")
21237         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21238                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21239   "TARGET_MMX"
21240   "pmullw\t{%2, %0|%0, %2}"
21241   [(set_attr "type" "mmxmul")
21242    (set_attr "mode" "DI")])
21243
21244 (define_insn "smulv4hi3_highpart"
21245   [(set (match_operand:V4HI 0 "register_operand" "=y")
21246         (truncate:V4HI
21247          (lshiftrt:V4SI
21248           (mult:V4SI (sign_extend:V4SI
21249                       (match_operand:V4HI 1 "register_operand" "0"))
21250                      (sign_extend:V4SI
21251                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21252           (const_int 16))))]
21253   "TARGET_MMX"
21254   "pmulhw\t{%2, %0|%0, %2}"
21255   [(set_attr "type" "mmxmul")
21256    (set_attr "mode" "DI")])
21257
21258 (define_insn "umulv4hi3_highpart"
21259   [(set (match_operand:V4HI 0 "register_operand" "=y")
21260         (truncate:V4HI
21261          (lshiftrt:V4SI
21262           (mult:V4SI (zero_extend:V4SI
21263                       (match_operand:V4HI 1 "register_operand" "0"))
21264                      (zero_extend:V4SI
21265                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21266           (const_int 16))))]
21267   "TARGET_SSE || TARGET_3DNOW_A"
21268   "pmulhuw\t{%2, %0|%0, %2}"
21269   [(set_attr "type" "mmxmul")
21270    (set_attr "mode" "DI")])
21271
21272 (define_insn "mmx_pmaddwd"
21273   [(set (match_operand:V2SI 0 "register_operand" "=y")
21274         (plus:V2SI
21275          (mult:V2SI
21276           (sign_extend:V2SI
21277            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21278                             (parallel [(const_int 0) (const_int 2)])))
21279           (sign_extend:V2SI
21280            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21281                             (parallel [(const_int 0) (const_int 2)]))))
21282          (mult:V2SI
21283           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21284                                              (parallel [(const_int 1)
21285                                                         (const_int 3)])))
21286           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21287                                              (parallel [(const_int 1)
21288                                                         (const_int 3)]))))))]
21289   "TARGET_MMX"
21290   "pmaddwd\t{%2, %0|%0, %2}"
21291   [(set_attr "type" "mmxmul")
21292    (set_attr "mode" "DI")])
21293
21294
21295 ;; MMX logical operations
21296 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21297 ;; normal code that also wants to use the FPU from getting broken.
21298 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21299 (define_insn "mmx_iordi3"
21300   [(set (match_operand:DI 0 "register_operand" "=y")
21301         (unspec:DI
21302          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21303                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21304          UNSPEC_NOP))]
21305   "TARGET_MMX"
21306   "por\t{%2, %0|%0, %2}"
21307   [(set_attr "type" "mmxadd")
21308    (set_attr "mode" "DI")])
21309
21310 (define_insn "mmx_xordi3"
21311   [(set (match_operand:DI 0 "register_operand" "=y")
21312         (unspec:DI
21313          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21314                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21315          UNSPEC_NOP))]
21316   "TARGET_MMX"
21317   "pxor\t{%2, %0|%0, %2}"
21318   [(set_attr "type" "mmxadd")
21319    (set_attr "mode" "DI")
21320    (set_attr "memory" "none")])
21321
21322 ;; Same as pxor, but don't show input operands so that we don't think
21323 ;; they are live.
21324 (define_insn "mmx_clrdi"
21325   [(set (match_operand:DI 0 "register_operand" "=y")
21326         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21327   "TARGET_MMX"
21328   "pxor\t{%0, %0|%0, %0}"
21329   [(set_attr "type" "mmxadd")
21330    (set_attr "mode" "DI")
21331    (set_attr "memory" "none")])
21332
21333 (define_insn "mmx_anddi3"
21334   [(set (match_operand:DI 0 "register_operand" "=y")
21335         (unspec:DI
21336          [(and:DI (match_operand:DI 1 "register_operand" "%0")
21337                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21338          UNSPEC_NOP))]
21339   "TARGET_MMX"
21340   "pand\t{%2, %0|%0, %2}"
21341   [(set_attr "type" "mmxadd")
21342    (set_attr "mode" "DI")])
21343
21344 (define_insn "mmx_nanddi3"
21345   [(set (match_operand:DI 0 "register_operand" "=y")
21346         (unspec:DI
21347          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21348                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21349          UNSPEC_NOP))]
21350   "TARGET_MMX"
21351   "pandn\t{%2, %0|%0, %2}"
21352   [(set_attr "type" "mmxadd")
21353    (set_attr "mode" "DI")])
21354
21355
21356 ;; MMX unsigned averages/sum of absolute differences
21357
21358 (define_insn "mmx_uavgv8qi3"
21359   [(set (match_operand:V8QI 0 "register_operand" "=y")
21360         (ashiftrt:V8QI
21361          (plus:V8QI (plus:V8QI
21362                      (match_operand:V8QI 1 "register_operand" "0")
21363                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21364                     (const_vector:V8QI [(const_int 1)
21365                                         (const_int 1)
21366                                         (const_int 1)
21367                                         (const_int 1)
21368                                         (const_int 1)
21369                                         (const_int 1)
21370                                         (const_int 1)
21371                                         (const_int 1)]))
21372          (const_int 1)))]
21373   "TARGET_SSE || TARGET_3DNOW_A"
21374   "pavgb\t{%2, %0|%0, %2}"
21375   [(set_attr "type" "mmxshft")
21376    (set_attr "mode" "DI")])
21377
21378 (define_insn "mmx_uavgv4hi3"
21379   [(set (match_operand:V4HI 0 "register_operand" "=y")
21380         (ashiftrt:V4HI
21381          (plus:V4HI (plus:V4HI
21382                      (match_operand:V4HI 1 "register_operand" "0")
21383                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21384                     (const_vector:V4HI [(const_int 1)
21385                                         (const_int 1)
21386                                         (const_int 1)
21387                                         (const_int 1)]))
21388          (const_int 1)))]
21389   "TARGET_SSE || TARGET_3DNOW_A"
21390   "pavgw\t{%2, %0|%0, %2}"
21391   [(set_attr "type" "mmxshft")
21392    (set_attr "mode" "DI")])
21393
21394 (define_insn "mmx_psadbw"
21395   [(set (match_operand:DI 0 "register_operand" "=y")
21396         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21397                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21398                    UNSPEC_PSADBW))]
21399   "TARGET_SSE || TARGET_3DNOW_A"
21400   "psadbw\t{%2, %0|%0, %2}"
21401   [(set_attr "type" "mmxshft")
21402    (set_attr "mode" "DI")])
21403
21404
21405 ;; MMX insert/extract/shuffle
21406
21407 (define_insn "mmx_pinsrw"
21408   [(set (match_operand:V4HI 0 "register_operand" "=y")
21409         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21410                         (vec_duplicate:V4HI
21411                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21412                         (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21413   "TARGET_SSE || TARGET_3DNOW_A"
21414   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21415   [(set_attr "type" "mmxcvt")
21416    (set_attr "mode" "DI")])
21417
21418 (define_insn "mmx_pextrw"
21419   [(set (match_operand:SI 0 "register_operand" "=r")
21420         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21421                                        (parallel
21422                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21423   "TARGET_SSE || TARGET_3DNOW_A"
21424   "pextrw\t{%2, %1, %0|%0, %1, %2}"
21425   [(set_attr "type" "mmxcvt")
21426    (set_attr "mode" "DI")])
21427
21428 (define_insn "mmx_pshufw"
21429   [(set (match_operand:V4HI 0 "register_operand" "=y")
21430         (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21431                       (match_operand:SI 2 "immediate_operand" "i")]
21432                      UNSPEC_SHUFFLE))]
21433   "TARGET_SSE || TARGET_3DNOW_A"
21434   "pshufw\t{%2, %1, %0|%0, %1, %2}"
21435   [(set_attr "type" "mmxcvt")
21436    (set_attr "mode" "DI")])
21437
21438
21439 ;; MMX mask-generating comparisons
21440
21441 (define_insn "eqv8qi3"
21442   [(set (match_operand:V8QI 0 "register_operand" "=y")
21443         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21444                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21445   "TARGET_MMX"
21446   "pcmpeqb\t{%2, %0|%0, %2}"
21447   [(set_attr "type" "mmxcmp")
21448    (set_attr "mode" "DI")])
21449
21450 (define_insn "eqv4hi3"
21451   [(set (match_operand:V4HI 0 "register_operand" "=y")
21452         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21453                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21454   "TARGET_MMX"
21455   "pcmpeqw\t{%2, %0|%0, %2}"
21456   [(set_attr "type" "mmxcmp")
21457    (set_attr "mode" "DI")])
21458
21459 (define_insn "eqv2si3"
21460   [(set (match_operand:V2SI 0 "register_operand" "=y")
21461         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21462                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21463   "TARGET_MMX"
21464   "pcmpeqd\t{%2, %0|%0, %2}"
21465   [(set_attr "type" "mmxcmp")
21466    (set_attr "mode" "DI")])
21467
21468 (define_insn "gtv8qi3"
21469   [(set (match_operand:V8QI 0 "register_operand" "=y")
21470         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21471                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21472   "TARGET_MMX"
21473   "pcmpgtb\t{%2, %0|%0, %2}"
21474   [(set_attr "type" "mmxcmp")
21475    (set_attr "mode" "DI")])
21476
21477 (define_insn "gtv4hi3"
21478   [(set (match_operand:V4HI 0 "register_operand" "=y")
21479         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21480                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21481   "TARGET_MMX"
21482   "pcmpgtw\t{%2, %0|%0, %2}"
21483   [(set_attr "type" "mmxcmp")
21484    (set_attr "mode" "DI")])
21485
21486 (define_insn "gtv2si3"
21487   [(set (match_operand:V2SI 0 "register_operand" "=y")
21488         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21489                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21490   "TARGET_MMX"
21491   "pcmpgtd\t{%2, %0|%0, %2}"
21492   [(set_attr "type" "mmxcmp")
21493    (set_attr "mode" "DI")])
21494
21495
21496 ;; MMX max/min insns
21497
21498 (define_insn "umaxv8qi3"
21499   [(set (match_operand:V8QI 0 "register_operand" "=y")
21500         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21501                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21502   "TARGET_SSE || TARGET_3DNOW_A"
21503   "pmaxub\t{%2, %0|%0, %2}"
21504   [(set_attr "type" "mmxadd")
21505    (set_attr "mode" "DI")])
21506
21507 (define_insn "smaxv4hi3"
21508   [(set (match_operand:V4HI 0 "register_operand" "=y")
21509         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21510                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21511   "TARGET_SSE || TARGET_3DNOW_A"
21512   "pmaxsw\t{%2, %0|%0, %2}"
21513   [(set_attr "type" "mmxadd")
21514    (set_attr "mode" "DI")])
21515
21516 (define_insn "uminv8qi3"
21517   [(set (match_operand:V8QI 0 "register_operand" "=y")
21518         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21519                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21520   "TARGET_SSE || TARGET_3DNOW_A"
21521   "pminub\t{%2, %0|%0, %2}"
21522   [(set_attr "type" "mmxadd")
21523    (set_attr "mode" "DI")])
21524
21525 (define_insn "sminv4hi3"
21526   [(set (match_operand:V4HI 0 "register_operand" "=y")
21527         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21528                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21529   "TARGET_SSE || TARGET_3DNOW_A"
21530   "pminsw\t{%2, %0|%0, %2}"
21531   [(set_attr "type" "mmxadd")
21532    (set_attr "mode" "DI")])
21533
21534
21535 ;; MMX shifts
21536
21537 (define_insn "ashrv4hi3"
21538   [(set (match_operand:V4HI 0 "register_operand" "=y")
21539         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21540                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21541   "TARGET_MMX"
21542   "psraw\t{%2, %0|%0, %2}"
21543   [(set_attr "type" "mmxshft")
21544    (set_attr "mode" "DI")])
21545
21546 (define_insn "ashrv2si3"
21547   [(set (match_operand:V2SI 0 "register_operand" "=y")
21548         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21549                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21550   "TARGET_MMX"
21551   "psrad\t{%2, %0|%0, %2}"
21552   [(set_attr "type" "mmxshft")
21553    (set_attr "mode" "DI")])
21554
21555 (define_insn "lshrv4hi3"
21556   [(set (match_operand:V4HI 0 "register_operand" "=y")
21557         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21558                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21559   "TARGET_MMX"
21560   "psrlw\t{%2, %0|%0, %2}"
21561   [(set_attr "type" "mmxshft")
21562    (set_attr "mode" "DI")])
21563
21564 (define_insn "lshrv2si3"
21565   [(set (match_operand:V2SI 0 "register_operand" "=y")
21566         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21567                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21568   "TARGET_MMX"
21569   "psrld\t{%2, %0|%0, %2}"
21570   [(set_attr "type" "mmxshft")
21571    (set_attr "mode" "DI")])
21572
21573 ;; See logical MMX insns.
21574 (define_insn "mmx_lshrdi3"
21575   [(set (match_operand:DI 0 "register_operand" "=y")
21576         (unspec:DI
21577           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21578                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
21579           UNSPEC_NOP))]
21580   "TARGET_MMX"
21581   "psrlq\t{%2, %0|%0, %2}"
21582   [(set_attr "type" "mmxshft")
21583    (set_attr "mode" "DI")])
21584
21585 (define_insn "ashlv4hi3"
21586   [(set (match_operand:V4HI 0 "register_operand" "=y")
21587         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21588                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21589   "TARGET_MMX"
21590   "psllw\t{%2, %0|%0, %2}"
21591   [(set_attr "type" "mmxshft")
21592    (set_attr "mode" "DI")])
21593
21594 (define_insn "ashlv2si3"
21595   [(set (match_operand:V2SI 0 "register_operand" "=y")
21596         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21597                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21598   "TARGET_MMX"
21599   "pslld\t{%2, %0|%0, %2}"
21600   [(set_attr "type" "mmxshft")
21601    (set_attr "mode" "DI")])
21602
21603 ;; See logical MMX insns.
21604 (define_insn "mmx_ashldi3"
21605   [(set (match_operand:DI 0 "register_operand" "=y")
21606         (unspec:DI
21607          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21608                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
21609          UNSPEC_NOP))]
21610   "TARGET_MMX"
21611   "psllq\t{%2, %0|%0, %2}"
21612   [(set_attr "type" "mmxshft")
21613    (set_attr "mode" "DI")])
21614
21615
21616 ;; MMX pack/unpack insns.
21617
21618 (define_insn "mmx_packsswb"
21619   [(set (match_operand:V8QI 0 "register_operand" "=y")
21620         (vec_concat:V8QI
21621          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21622          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21623   "TARGET_MMX"
21624   "packsswb\t{%2, %0|%0, %2}"
21625   [(set_attr "type" "mmxshft")
21626    (set_attr "mode" "DI")])
21627
21628 (define_insn "mmx_packssdw"
21629   [(set (match_operand:V4HI 0 "register_operand" "=y")
21630         (vec_concat:V4HI
21631          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21632          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21633   "TARGET_MMX"
21634   "packssdw\t{%2, %0|%0, %2}"
21635   [(set_attr "type" "mmxshft")
21636    (set_attr "mode" "DI")])
21637
21638 (define_insn "mmx_packuswb"
21639   [(set (match_operand:V8QI 0 "register_operand" "=y")
21640         (vec_concat:V8QI
21641          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21642          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21643   "TARGET_MMX"
21644   "packuswb\t{%2, %0|%0, %2}"
21645   [(set_attr "type" "mmxshft")
21646    (set_attr "mode" "DI")])
21647
21648 (define_insn "mmx_punpckhbw"
21649   [(set (match_operand:V8QI 0 "register_operand" "=y")
21650         (vec_merge:V8QI
21651          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21652                           (parallel [(const_int 4)
21653                                      (const_int 0)
21654                                      (const_int 5)
21655                                      (const_int 1)
21656                                      (const_int 6)
21657                                      (const_int 2)
21658                                      (const_int 7)
21659                                      (const_int 3)]))
21660          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21661                           (parallel [(const_int 0)
21662                                      (const_int 4)
21663                                      (const_int 1)
21664                                      (const_int 5)
21665                                      (const_int 2)
21666                                      (const_int 6)
21667                                      (const_int 3)
21668                                      (const_int 7)]))
21669          (const_int 85)))]
21670   "TARGET_MMX"
21671   "punpckhbw\t{%2, %0|%0, %2}"
21672   [(set_attr "type" "mmxcvt")
21673    (set_attr "mode" "DI")])
21674
21675 (define_insn "mmx_punpckhwd"
21676   [(set (match_operand:V4HI 0 "register_operand" "=y")
21677         (vec_merge:V4HI
21678          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21679                           (parallel [(const_int 0)
21680                                      (const_int 2)
21681                                      (const_int 1)
21682                                      (const_int 3)]))
21683          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21684                           (parallel [(const_int 2)
21685                                      (const_int 0)
21686                                      (const_int 3)
21687                                      (const_int 1)]))
21688          (const_int 5)))]
21689   "TARGET_MMX"
21690   "punpckhwd\t{%2, %0|%0, %2}"
21691   [(set_attr "type" "mmxcvt")
21692    (set_attr "mode" "DI")])
21693
21694 (define_insn "mmx_punpckhdq"
21695   [(set (match_operand:V2SI 0 "register_operand" "=y")
21696         (vec_merge:V2SI
21697          (match_operand:V2SI 1 "register_operand" "0")
21698          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21699                           (parallel [(const_int 1)
21700                                      (const_int 0)]))
21701          (const_int 1)))]
21702   "TARGET_MMX"
21703   "punpckhdq\t{%2, %0|%0, %2}"
21704   [(set_attr "type" "mmxcvt")
21705    (set_attr "mode" "DI")])
21706
21707 (define_insn "mmx_punpcklbw"
21708   [(set (match_operand:V8QI 0 "register_operand" "=y")
21709         (vec_merge:V8QI
21710          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21711                           (parallel [(const_int 0)
21712                                      (const_int 4)
21713                                      (const_int 1)
21714                                      (const_int 5)
21715                                      (const_int 2)
21716                                      (const_int 6)
21717                                      (const_int 3)
21718                                      (const_int 7)]))
21719          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21720                           (parallel [(const_int 4)
21721                                      (const_int 0)
21722                                      (const_int 5)
21723                                      (const_int 1)
21724                                      (const_int 6)
21725                                      (const_int 2)
21726                                      (const_int 7)
21727                                      (const_int 3)]))
21728          (const_int 85)))]
21729   "TARGET_MMX"
21730   "punpcklbw\t{%2, %0|%0, %2}"
21731   [(set_attr "type" "mmxcvt")
21732    (set_attr "mode" "DI")])
21733
21734 (define_insn "mmx_punpcklwd"
21735   [(set (match_operand:V4HI 0 "register_operand" "=y")
21736         (vec_merge:V4HI
21737          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21738                           (parallel [(const_int 2)
21739                                      (const_int 0)
21740                                      (const_int 3)
21741                                      (const_int 1)]))
21742          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21743                           (parallel [(const_int 0)
21744                                      (const_int 2)
21745                                      (const_int 1)
21746                                      (const_int 3)]))
21747          (const_int 5)))]
21748   "TARGET_MMX"
21749   "punpcklwd\t{%2, %0|%0, %2}"
21750   [(set_attr "type" "mmxcvt")
21751    (set_attr "mode" "DI")])
21752
21753 (define_insn "mmx_punpckldq"
21754   [(set (match_operand:V2SI 0 "register_operand" "=y")
21755         (vec_merge:V2SI
21756          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
21757                            (parallel [(const_int 1)
21758                                       (const_int 0)]))
21759          (match_operand:V2SI 2 "register_operand" "y")
21760          (const_int 1)))]
21761   "TARGET_MMX"
21762   "punpckldq\t{%2, %0|%0, %2}"
21763   [(set_attr "type" "mmxcvt")
21764    (set_attr "mode" "DI")])
21765
21766
21767 ;; Miscellaneous stuff
21768
21769 (define_insn "emms"
21770   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
21771    (clobber (reg:XF 8))
21772    (clobber (reg:XF 9))
21773    (clobber (reg:XF 10))
21774    (clobber (reg:XF 11))
21775    (clobber (reg:XF 12))
21776    (clobber (reg:XF 13))
21777    (clobber (reg:XF 14))
21778    (clobber (reg:XF 15))
21779    (clobber (reg:DI 29))
21780    (clobber (reg:DI 30))
21781    (clobber (reg:DI 31))
21782    (clobber (reg:DI 32))
21783    (clobber (reg:DI 33))
21784    (clobber (reg:DI 34))
21785    (clobber (reg:DI 35))
21786    (clobber (reg:DI 36))]
21787   "TARGET_MMX"
21788   "emms"
21789   [(set_attr "type" "mmx")
21790    (set_attr "memory" "unknown")])
21791
21792 (define_insn "ldmxcsr"
21793   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
21794                     UNSPECV_LDMXCSR)]
21795   "TARGET_SSE"
21796   "ldmxcsr\t%0"
21797   [(set_attr "type" "sse")
21798    (set_attr "memory" "load")])
21799
21800 (define_insn "stmxcsr"
21801   [(set (match_operand:SI 0 "memory_operand" "=m")
21802         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21803   "TARGET_SSE"
21804   "stmxcsr\t%0"
21805   [(set_attr "type" "sse")
21806    (set_attr "memory" "store")])
21807
21808 (define_expand "sfence"
21809   [(set (match_dup 0)
21810         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21811   "TARGET_SSE || TARGET_3DNOW_A"
21812 {
21813   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21814   MEM_VOLATILE_P (operands[0]) = 1;
21815 })
21816
21817 (define_insn "*sfence_insn"
21818   [(set (match_operand:BLK 0 "" "")
21819         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21820   "TARGET_SSE || TARGET_3DNOW_A"
21821   "sfence"
21822   [(set_attr "type" "sse")
21823    (set_attr "memory" "unknown")])
21824
21825 (define_expand "sse_prologue_save"
21826   [(parallel [(set (match_operand:BLK 0 "" "")
21827                    (unspec:BLK [(reg:DI 21)
21828                                 (reg:DI 22)
21829                                 (reg:DI 23)
21830                                 (reg:DI 24)
21831                                 (reg:DI 25)
21832                                 (reg:DI 26)
21833                                 (reg:DI 27)
21834                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21835               (use (match_operand:DI 1 "register_operand" ""))
21836               (use (match_operand:DI 2 "immediate_operand" ""))
21837               (use (label_ref:DI (match_operand 3 "" "")))])]
21838   "TARGET_64BIT"
21839   "")
21840
21841 (define_insn "*sse_prologue_save_insn"
21842   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21843                           (match_operand:DI 4 "const_int_operand" "n")))
21844         (unspec:BLK [(reg:DI 21)
21845                      (reg:DI 22)
21846                      (reg:DI 23)
21847                      (reg:DI 24)
21848                      (reg:DI 25)
21849                      (reg:DI 26)
21850                      (reg:DI 27)
21851                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21852    (use (match_operand:DI 1 "register_operand" "r"))
21853    (use (match_operand:DI 2 "const_int_operand" "i"))
21854    (use (label_ref:DI (match_operand 3 "" "X")))]
21855   "TARGET_64BIT
21856    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21857    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21858   "*
21859 {
21860   int i;
21861   operands[0] = gen_rtx_MEM (Pmode,
21862                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21863   output_asm_insn (\"jmp\\t%A1\", operands);
21864   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21865     {
21866       operands[4] = adjust_address (operands[0], DImode, i*16);
21867       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21868       PUT_MODE (operands[4], TImode);
21869       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21870         output_asm_insn (\"rex\", operands);
21871       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21872     }
21873   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21874                              CODE_LABEL_NUMBER (operands[3]));
21875   RET;
21876 }
21877   "
21878   [(set_attr "type" "other")
21879    (set_attr "length_immediate" "0")
21880    (set_attr "length_address" "0")
21881    (set_attr "length" "135")
21882    (set_attr "memory" "store")
21883    (set_attr "modrm" "0")
21884    (set_attr "mode" "DI")])
21885
21886 ;; 3Dnow! instructions
21887
21888 (define_insn "addv2sf3"
21889   [(set (match_operand:V2SF 0 "register_operand" "=y")
21890         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21891                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21892   "TARGET_3DNOW"
21893   "pfadd\\t{%2, %0|%0, %2}"
21894   [(set_attr "type" "mmxadd")
21895    (set_attr "mode" "V2SF")])
21896
21897 (define_insn "subv2sf3"
21898   [(set (match_operand:V2SF 0 "register_operand" "=y")
21899         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21900                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21901   "TARGET_3DNOW"
21902   "pfsub\\t{%2, %0|%0, %2}"
21903   [(set_attr "type" "mmxadd")
21904    (set_attr "mode" "V2SF")])
21905
21906 (define_insn "subrv2sf3"
21907   [(set (match_operand:V2SF 0 "register_operand" "=y")
21908         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
21909                     (match_operand:V2SF 1 "register_operand" "0")))]
21910   "TARGET_3DNOW"
21911   "pfsubr\\t{%2, %0|%0, %2}"
21912   [(set_attr "type" "mmxadd")
21913    (set_attr "mode" "V2SF")])
21914
21915 (define_insn "gtv2sf3"
21916   [(set (match_operand:V2SI 0 "register_operand" "=y")
21917         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
21918                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21919   "TARGET_3DNOW"
21920   "pfcmpgt\\t{%2, %0|%0, %2}"
21921   [(set_attr "type" "mmxcmp")
21922    (set_attr "mode" "V2SF")])
21923
21924 (define_insn "gev2sf3"
21925   [(set (match_operand:V2SI 0 "register_operand" "=y")
21926         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
21927                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21928   "TARGET_3DNOW"
21929   "pfcmpge\\t{%2, %0|%0, %2}"
21930   [(set_attr "type" "mmxcmp")
21931    (set_attr "mode" "V2SF")])
21932
21933 (define_insn "eqv2sf3"
21934   [(set (match_operand:V2SI 0 "register_operand" "=y")
21935         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
21936                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21937   "TARGET_3DNOW"
21938   "pfcmpeq\\t{%2, %0|%0, %2}"
21939   [(set_attr "type" "mmxcmp")
21940    (set_attr "mode" "V2SF")])
21941
21942 (define_insn "pfmaxv2sf3"
21943   [(set (match_operand:V2SF 0 "register_operand" "=y")
21944         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
21945                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21946   "TARGET_3DNOW"
21947   "pfmax\\t{%2, %0|%0, %2}"
21948   [(set_attr "type" "mmxadd")
21949    (set_attr "mode" "V2SF")])
21950
21951 (define_insn "pfminv2sf3"
21952   [(set (match_operand:V2SF 0 "register_operand" "=y")
21953         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
21954                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21955   "TARGET_3DNOW"
21956   "pfmin\\t{%2, %0|%0, %2}"
21957   [(set_attr "type" "mmxadd")
21958    (set_attr "mode" "V2SF")])
21959
21960 (define_insn "mulv2sf3"
21961   [(set (match_operand:V2SF 0 "register_operand" "=y")
21962         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
21963                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21964   "TARGET_3DNOW"
21965   "pfmul\\t{%2, %0|%0, %2}"
21966   [(set_attr "type" "mmxmul")
21967    (set_attr "mode" "V2SF")])
21968
21969 (define_insn "femms"
21970   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21971    (clobber (reg:XF 8))
21972    (clobber (reg:XF 9))
21973    (clobber (reg:XF 10))
21974    (clobber (reg:XF 11))
21975    (clobber (reg:XF 12))
21976    (clobber (reg:XF 13))
21977    (clobber (reg:XF 14))
21978    (clobber (reg:XF 15))
21979    (clobber (reg:DI 29))
21980    (clobber (reg:DI 30))
21981    (clobber (reg:DI 31))
21982    (clobber (reg:DI 32))
21983    (clobber (reg:DI 33))
21984    (clobber (reg:DI 34))
21985    (clobber (reg:DI 35))
21986    (clobber (reg:DI 36))]
21987   "TARGET_3DNOW"
21988   "femms"
21989   [(set_attr "type" "mmx")
21990    (set_attr "memory" "none")]) 
21991
21992 (define_insn "pf2id"
21993   [(set (match_operand:V2SI 0 "register_operand" "=y")
21994         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21995   "TARGET_3DNOW"
21996   "pf2id\\t{%1, %0|%0, %1}"
21997   [(set_attr "type" "mmxcvt")
21998    (set_attr "mode" "V2SF")])
21999
22000 (define_insn "pf2iw"
22001   [(set (match_operand:V2SI 0 "register_operand" "=y")
22002         (sign_extend:V2SI
22003            (ss_truncate:V2HI
22004               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22005   "TARGET_3DNOW_A"
22006   "pf2iw\\t{%1, %0|%0, %1}"
22007   [(set_attr "type" "mmxcvt")
22008    (set_attr "mode" "V2SF")])
22009
22010 (define_insn "pfacc"
22011   [(set (match_operand:V2SF 0 "register_operand" "=y")
22012         (vec_concat:V2SF
22013            (plus:SF
22014               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22015                              (parallel [(const_int  0)]))
22016               (vec_select:SF (match_dup 1)
22017                              (parallel [(const_int 1)])))
22018            (plus:SF
22019               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22020                              (parallel [(const_int  0)]))
22021               (vec_select:SF (match_dup 2)
22022                              (parallel [(const_int 1)])))))]
22023   "TARGET_3DNOW"
22024   "pfacc\\t{%2, %0|%0, %2}"
22025   [(set_attr "type" "mmxadd")
22026    (set_attr "mode" "V2SF")])
22027
22028 (define_insn "pfnacc"
22029   [(set (match_operand:V2SF 0 "register_operand" "=y")
22030         (vec_concat:V2SF
22031            (minus:SF
22032               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22033                              (parallel [(const_int 0)]))
22034               (vec_select:SF (match_dup 1)
22035                              (parallel [(const_int 1)])))
22036            (minus:SF
22037               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22038                              (parallel [(const_int  0)]))
22039               (vec_select:SF (match_dup 2)
22040                              (parallel [(const_int 1)])))))]
22041   "TARGET_3DNOW_A"
22042   "pfnacc\\t{%2, %0|%0, %2}"
22043   [(set_attr "type" "mmxadd")
22044    (set_attr "mode" "V2SF")])
22045
22046 (define_insn "pfpnacc"
22047   [(set (match_operand:V2SF 0 "register_operand" "=y")
22048         (vec_concat:V2SF
22049            (minus:SF
22050               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22051                              (parallel [(const_int 0)]))
22052               (vec_select:SF (match_dup 1)
22053                              (parallel [(const_int 1)])))
22054            (plus:SF
22055               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22056                              (parallel [(const_int 0)]))
22057               (vec_select:SF (match_dup 2)
22058                              (parallel [(const_int 1)])))))]
22059   "TARGET_3DNOW_A"
22060   "pfpnacc\\t{%2, %0|%0, %2}"
22061   [(set_attr "type" "mmxadd")
22062    (set_attr "mode" "V2SF")])
22063
22064 (define_insn "pi2fw"
22065   [(set (match_operand:V2SF 0 "register_operand" "=y")
22066         (float:V2SF
22067            (vec_concat:V2SI
22068               (sign_extend:SI
22069                  (truncate:HI
22070                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22071                                    (parallel [(const_int 0)]))))
22072               (sign_extend:SI
22073                  (truncate:HI
22074                     (vec_select:SI (match_dup 1)
22075                                    (parallel [(const_int  1)])))))))]
22076   "TARGET_3DNOW_A"
22077   "pi2fw\\t{%1, %0|%0, %1}"
22078   [(set_attr "type" "mmxcvt")
22079    (set_attr "mode" "V2SF")])
22080
22081 (define_insn "floatv2si2"
22082   [(set (match_operand:V2SF 0 "register_operand" "=y")
22083         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22084   "TARGET_3DNOW"
22085   "pi2fd\\t{%1, %0|%0, %1}"
22086   [(set_attr "type" "mmxcvt")
22087    (set_attr "mode" "V2SF")])
22088
22089 ;; This insn is identical to pavgb in operation, but the opcode is
22090 ;; different.  To avoid accidentally matching pavgb, use an unspec.
22091
22092 (define_insn "pavgusb"
22093  [(set (match_operand:V8QI 0 "register_operand" "=y")
22094        (unspec:V8QI
22095           [(match_operand:V8QI 1 "register_operand" "0")
22096            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22097           UNSPEC_PAVGUSB))]
22098   "TARGET_3DNOW"
22099   "pavgusb\\t{%2, %0|%0, %2}"
22100   [(set_attr "type" "mmxshft")
22101    (set_attr "mode" "TI")])
22102
22103 ;; 3DNow reciprocal and sqrt
22104  
22105 (define_insn "pfrcpv2sf2"
22106   [(set (match_operand:V2SF 0 "register_operand" "=y")
22107         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22108         UNSPEC_PFRCP))]
22109   "TARGET_3DNOW"
22110   "pfrcp\\t{%1, %0|%0, %1}"
22111   [(set_attr "type" "mmx")
22112    (set_attr "mode" "TI")])
22113
22114 (define_insn "pfrcpit1v2sf3"
22115   [(set (match_operand:V2SF 0 "register_operand" "=y")
22116         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22117                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22118                      UNSPEC_PFRCPIT1))]
22119   "TARGET_3DNOW"
22120   "pfrcpit1\\t{%2, %0|%0, %2}"
22121   [(set_attr "type" "mmx")
22122    (set_attr "mode" "TI")])
22123
22124 (define_insn "pfrcpit2v2sf3"
22125   [(set (match_operand:V2SF 0 "register_operand" "=y")
22126         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22127                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22128                      UNSPEC_PFRCPIT2))]
22129   "TARGET_3DNOW"
22130   "pfrcpit2\\t{%2, %0|%0, %2}"
22131   [(set_attr "type" "mmx")
22132    (set_attr "mode" "TI")])
22133
22134 (define_insn "pfrsqrtv2sf2"
22135   [(set (match_operand:V2SF 0 "register_operand" "=y")
22136         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22137                      UNSPEC_PFRSQRT))]
22138   "TARGET_3DNOW"
22139   "pfrsqrt\\t{%1, %0|%0, %1}"
22140   [(set_attr "type" "mmx")
22141    (set_attr "mode" "TI")])
22142                 
22143 (define_insn "pfrsqit1v2sf3"
22144   [(set (match_operand:V2SF 0 "register_operand" "=y")
22145         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22146                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22147                      UNSPEC_PFRSQIT1))]
22148   "TARGET_3DNOW"
22149   "pfrsqit1\\t{%2, %0|%0, %2}"
22150   [(set_attr "type" "mmx")
22151    (set_attr "mode" "TI")])
22152
22153 (define_insn "pmulhrwv4hi3"
22154   [(set (match_operand:V4HI 0 "register_operand" "=y")
22155         (truncate:V4HI
22156            (lshiftrt:V4SI
22157               (plus:V4SI
22158                  (mult:V4SI
22159                     (sign_extend:V4SI
22160                        (match_operand:V4HI 1 "register_operand" "0"))
22161                     (sign_extend:V4SI
22162                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22163                  (const_vector:V4SI [(const_int 32768)
22164                                      (const_int 32768)
22165                                      (const_int 32768)
22166                                      (const_int 32768)]))
22167               (const_int 16))))]
22168   "TARGET_3DNOW"
22169   "pmulhrw\\t{%2, %0|%0, %2}"
22170   [(set_attr "type" "mmxmul")
22171    (set_attr "mode" "TI")])
22172
22173 (define_insn "pswapdv2si2"
22174   [(set (match_operand:V2SI 0 "register_operand" "=y")
22175         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22176                          (parallel [(const_int 1) (const_int 0)])))]
22177   "TARGET_3DNOW_A"
22178   "pswapd\\t{%1, %0|%0, %1}"
22179   [(set_attr "type" "mmxcvt")
22180    (set_attr "mode" "TI")])
22181
22182 (define_insn "pswapdv2sf2"
22183   [(set (match_operand:V2SF 0 "register_operand" "=y")
22184         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22185                          (parallel [(const_int 1) (const_int 0)])))]
22186   "TARGET_3DNOW_A"
22187   "pswapd\\t{%1, %0|%0, %1}"
22188   [(set_attr "type" "mmxcvt")
22189    (set_attr "mode" "TI")])
22190
22191 (define_expand "prefetch"
22192   [(prefetch (match_operand 0 "address_operand" "")
22193              (match_operand:SI 1 "const_int_operand" "")
22194              (match_operand:SI 2 "const_int_operand" ""))]
22195   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22196 {
22197   int rw = INTVAL (operands[1]);
22198   int locality = INTVAL (operands[2]);
22199
22200   if (rw != 0 && rw != 1)
22201     abort ();
22202   if (locality < 0 || locality > 3)
22203     abort ();
22204   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22205     abort ();
22206
22207   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22208      suported by SSE counterpart or the SSE prefetch is not available
22209      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22210      of locality.  */
22211   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22212     operands[2] = GEN_INT (3);
22213   else
22214     operands[1] = const0_rtx;
22215 })
22216
22217 (define_insn "*prefetch_sse"
22218   [(prefetch (match_operand:SI 0 "address_operand" "p")
22219              (const_int 0)
22220              (match_operand:SI 1 "const_int_operand" ""))]
22221   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22222 {
22223   static const char * const patterns[4] = {
22224    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22225   };
22226
22227   int locality = INTVAL (operands[1]);
22228   if (locality < 0 || locality > 3)
22229     abort ();
22230
22231   return patterns[locality];  
22232 }
22233   [(set_attr "type" "sse")
22234    (set_attr "memory" "none")])
22235
22236 (define_insn "*prefetch_sse_rex"
22237   [(prefetch (match_operand:DI 0 "address_operand" "p")
22238              (const_int 0)
22239              (match_operand:SI 1 "const_int_operand" ""))]
22240   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22241 {
22242   static const char * const patterns[4] = {
22243    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22244   };
22245
22246   int locality = INTVAL (operands[1]);
22247   if (locality < 0 || locality > 3)
22248     abort ();
22249
22250   return patterns[locality];  
22251 }
22252   [(set_attr "type" "sse")
22253    (set_attr "memory" "none")])
22254
22255 (define_insn "*prefetch_3dnow"
22256   [(prefetch (match_operand:SI 0 "address_operand" "p")
22257              (match_operand:SI 1 "const_int_operand" "n")
22258              (const_int 3))]
22259   "TARGET_3DNOW && !TARGET_64BIT"
22260 {
22261   if (INTVAL (operands[1]) == 0)
22262     return "prefetch\t%a0";
22263   else
22264     return "prefetchw\t%a0";
22265 }
22266   [(set_attr "type" "mmx")
22267    (set_attr "memory" "none")])
22268
22269 (define_insn "*prefetch_3dnow_rex"
22270   [(prefetch (match_operand:DI 0 "address_operand" "p")
22271              (match_operand:SI 1 "const_int_operand" "n")
22272              (const_int 3))]
22273   "TARGET_3DNOW && TARGET_64BIT"
22274 {
22275   if (INTVAL (operands[1]) == 0)
22276     return "prefetch\t%a0";
22277   else
22278     return "prefetchw\t%a0";
22279 }
22280   [(set_attr "type" "mmx")
22281    (set_attr "memory" "none")])
22282
22283 ;; SSE2 support
22284
22285 (define_insn "addv2df3"
22286   [(set (match_operand:V2DF 0 "register_operand" "=x")
22287         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22288                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22289   "TARGET_SSE2"
22290   "addpd\t{%2, %0|%0, %2}"
22291   [(set_attr "type" "sseadd")
22292    (set_attr "mode" "V2DF")])
22293
22294 (define_insn "vmaddv2df3"
22295   [(set (match_operand:V2DF 0 "register_operand" "=x")
22296         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22297                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22298                         (match_dup 1)
22299                         (const_int 1)))]
22300   "TARGET_SSE2"
22301   "addsd\t{%2, %0|%0, %2}"
22302   [(set_attr "type" "sseadd")
22303    (set_attr "mode" "DF")])
22304
22305 (define_insn "subv2df3"
22306   [(set (match_operand:V2DF 0 "register_operand" "=x")
22307         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22308                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22309   "TARGET_SSE2"
22310   "subpd\t{%2, %0|%0, %2}"
22311   [(set_attr "type" "sseadd")
22312    (set_attr "mode" "V2DF")])
22313
22314 (define_insn "vmsubv2df3"
22315   [(set (match_operand:V2DF 0 "register_operand" "=x")
22316         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22317                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22318                         (match_dup 1)
22319                         (const_int 1)))]
22320   "TARGET_SSE2"
22321   "subsd\t{%2, %0|%0, %2}"
22322   [(set_attr "type" "sseadd")
22323    (set_attr "mode" "DF")])
22324
22325 (define_insn "mulv2df3"
22326   [(set (match_operand:V2DF 0 "register_operand" "=x")
22327         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22328                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22329   "TARGET_SSE2"
22330   "mulpd\t{%2, %0|%0, %2}"
22331   [(set_attr "type" "ssemul")
22332    (set_attr "mode" "V2DF")])
22333
22334 (define_insn "vmmulv2df3"
22335   [(set (match_operand:V2DF 0 "register_operand" "=x")
22336         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22337                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22338                         (match_dup 1)
22339                         (const_int 1)))]
22340   "TARGET_SSE2"
22341   "mulsd\t{%2, %0|%0, %2}"
22342   [(set_attr "type" "ssemul")
22343    (set_attr "mode" "DF")])
22344
22345 (define_insn "divv2df3"
22346   [(set (match_operand:V2DF 0 "register_operand" "=x")
22347         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22348                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22349   "TARGET_SSE2"
22350   "divpd\t{%2, %0|%0, %2}"
22351   [(set_attr "type" "ssediv")
22352    (set_attr "mode" "V2DF")])
22353
22354 (define_insn "vmdivv2df3"
22355   [(set (match_operand:V2DF 0 "register_operand" "=x")
22356         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22357                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22358                         (match_dup 1)
22359                         (const_int 1)))]
22360   "TARGET_SSE2"
22361   "divsd\t{%2, %0|%0, %2}"
22362   [(set_attr "type" "ssediv")
22363    (set_attr "mode" "DF")])
22364
22365 ;; SSE min/max
22366
22367 (define_insn "smaxv2df3"
22368   [(set (match_operand:V2DF 0 "register_operand" "=x")
22369         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22370                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22371   "TARGET_SSE2"
22372   "maxpd\t{%2, %0|%0, %2}"
22373   [(set_attr "type" "sseadd")
22374    (set_attr "mode" "V2DF")])
22375
22376 (define_insn "vmsmaxv2df3"
22377   [(set (match_operand:V2DF 0 "register_operand" "=x")
22378         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22379                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22380                         (match_dup 1)
22381                         (const_int 1)))]
22382   "TARGET_SSE2"
22383   "maxsd\t{%2, %0|%0, %2}"
22384   [(set_attr "type" "sseadd")
22385    (set_attr "mode" "DF")])
22386
22387 (define_insn "sminv2df3"
22388   [(set (match_operand:V2DF 0 "register_operand" "=x")
22389         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22390                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22391   "TARGET_SSE2"
22392   "minpd\t{%2, %0|%0, %2}"
22393   [(set_attr "type" "sseadd")
22394    (set_attr "mode" "V2DF")])
22395
22396 (define_insn "vmsminv2df3"
22397   [(set (match_operand:V2DF 0 "register_operand" "=x")
22398         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22399                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22400                         (match_dup 1)
22401                         (const_int 1)))]
22402   "TARGET_SSE2"
22403   "minsd\t{%2, %0|%0, %2}"
22404   [(set_attr "type" "sseadd")
22405    (set_attr "mode" "DF")])
22406 ;; SSE2 square root.  There doesn't appear to be an extension for the
22407 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22408
22409 (define_insn "sqrtv2df2"
22410   [(set (match_operand:V2DF 0 "register_operand" "=x")
22411         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22412   "TARGET_SSE2"
22413   "sqrtpd\t{%1, %0|%0, %1}"
22414   [(set_attr "type" "sse")
22415    (set_attr "mode" "V2DF")])
22416
22417 (define_insn "vmsqrtv2df2"
22418   [(set (match_operand:V2DF 0 "register_operand" "=x")
22419         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22420                         (match_operand:V2DF 2 "register_operand" "0")
22421                         (const_int 1)))]
22422   "TARGET_SSE2"
22423   "sqrtsd\t{%1, %0|%0, %1}"
22424   [(set_attr "type" "sse")
22425    (set_attr "mode" "SF")])
22426
22427 ;; SSE mask-generating compares
22428
22429 (define_insn "maskcmpv2df3"
22430   [(set (match_operand:V2DI 0 "register_operand" "=x")
22431         (match_operator:V2DI 3 "sse_comparison_operator"
22432                              [(match_operand:V2DF 1 "register_operand" "0")
22433                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22434   "TARGET_SSE2"
22435   "cmp%D3pd\t{%2, %0|%0, %2}"
22436   [(set_attr "type" "ssecmp")
22437    (set_attr "mode" "V2DF")])
22438
22439 (define_insn "maskncmpv2df3"
22440   [(set (match_operand:V2DI 0 "register_operand" "=x")
22441         (not:V2DI
22442          (match_operator:V2DI 3 "sse_comparison_operator"
22443                               [(match_operand:V2DF 1 "register_operand" "0")
22444                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22445   "TARGET_SSE2"
22446 {
22447   if (GET_CODE (operands[3]) == UNORDERED)
22448     return "cmpordps\t{%2, %0|%0, %2}";
22449   else
22450     return "cmpn%D3pd\t{%2, %0|%0, %2}";
22451 }
22452   [(set_attr "type" "ssecmp")
22453    (set_attr "mode" "V2DF")])
22454
22455 (define_insn "vmmaskcmpv2df3"
22456   [(set (match_operand:V2DI 0 "register_operand" "=x")
22457         (vec_merge:V2DI
22458          (match_operator:V2DI 3 "sse_comparison_operator"
22459                               [(match_operand:V2DF 1 "register_operand" "0")
22460                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22461          (subreg:V2DI (match_dup 1) 0)
22462          (const_int 1)))]
22463   "TARGET_SSE2"
22464   "cmp%D3sd\t{%2, %0|%0, %2}"
22465   [(set_attr "type" "ssecmp")
22466    (set_attr "mode" "DF")])
22467
22468 (define_insn "vmmaskncmpv2df3"
22469   [(set (match_operand:V2DI 0 "register_operand" "=x")
22470         (vec_merge:V2DI
22471          (not:V2DI
22472           (match_operator:V2DI 3 "sse_comparison_operator"
22473                                [(match_operand:V2DF 1 "register_operand" "0")
22474                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22475          (subreg:V2DI (match_dup 1) 0)
22476          (const_int 1)))]
22477   "TARGET_SSE2"
22478 {
22479   if (GET_CODE (operands[3]) == UNORDERED)
22480     return "cmpordsd\t{%2, %0|%0, %2}";
22481   else
22482     return "cmpn%D3sd\t{%2, %0|%0, %2}";
22483 }
22484   [(set_attr "type" "ssecmp")
22485    (set_attr "mode" "DF")])
22486
22487 (define_insn "sse2_comi"
22488   [(set (reg:CCFP FLAGS_REG)
22489         (compare:CCFP (vec_select:DF
22490                        (match_operand:V2DF 0 "register_operand" "x")
22491                        (parallel [(const_int 0)]))
22492                       (vec_select:DF
22493                        (match_operand:V2DF 1 "register_operand" "x")
22494                        (parallel [(const_int 0)]))))]
22495   "TARGET_SSE2"
22496   "comisd\t{%1, %0|%0, %1}"
22497   [(set_attr "type" "ssecomi")
22498    (set_attr "mode" "DF")])
22499
22500 (define_insn "sse2_ucomi"
22501   [(set (reg:CCFPU FLAGS_REG)
22502         (compare:CCFPU (vec_select:DF
22503                          (match_operand:V2DF 0 "register_operand" "x")
22504                          (parallel [(const_int 0)]))
22505                         (vec_select:DF
22506                          (match_operand:V2DF 1 "register_operand" "x")
22507                          (parallel [(const_int 0)]))))]
22508   "TARGET_SSE2"
22509   "ucomisd\t{%1, %0|%0, %1}"
22510   [(set_attr "type" "ssecomi")
22511    (set_attr "mode" "DF")])
22512
22513 ;; SSE Strange Moves.
22514
22515 (define_insn "sse2_movmskpd"
22516   [(set (match_operand:SI 0 "register_operand" "=r")
22517         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22518                    UNSPEC_MOVMSK))]
22519   "TARGET_SSE2"
22520   "movmskpd\t{%1, %0|%0, %1}"
22521   [(set_attr "type" "ssecvt")
22522    (set_attr "mode" "V2DF")])
22523
22524 (define_insn "sse2_pmovmskb"
22525   [(set (match_operand:SI 0 "register_operand" "=r")
22526         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22527                    UNSPEC_MOVMSK))]
22528   "TARGET_SSE2"
22529   "pmovmskb\t{%1, %0|%0, %1}"
22530   [(set_attr "type" "ssecvt")
22531    (set_attr "mode" "V2DF")])
22532
22533 (define_insn "sse2_maskmovdqu"
22534   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22535         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22536                        (match_operand:V16QI 2 "register_operand" "x")]
22537                       UNSPEC_MASKMOV))]
22538   "TARGET_SSE2"
22539   ;; @@@ check ordering of operands in intel/nonintel syntax
22540   "maskmovdqu\t{%2, %1|%1, %2}"
22541   [(set_attr "type" "ssecvt")
22542    (set_attr "mode" "TI")])
22543
22544 (define_insn "sse2_maskmovdqu_rex64"
22545   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22546         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22547                        (match_operand:V16QI 2 "register_operand" "x")]
22548                       UNSPEC_MASKMOV))]
22549   "TARGET_SSE2"
22550   ;; @@@ check ordering of operands in intel/nonintel syntax
22551   "maskmovdqu\t{%2, %1|%1, %2}"
22552   [(set_attr "type" "ssecvt")
22553    (set_attr "mode" "TI")])
22554
22555 (define_insn "sse2_movntv2df"
22556   [(set (match_operand:V2DF 0 "memory_operand" "=m")
22557         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22558                      UNSPEC_MOVNT))]
22559   "TARGET_SSE2"
22560   "movntpd\t{%1, %0|%0, %1}"
22561   [(set_attr "type" "ssecvt")
22562    (set_attr "mode" "V2DF")])
22563
22564 (define_insn "sse2_movntv2di"
22565   [(set (match_operand:V2DI 0 "memory_operand" "=m")
22566         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22567                      UNSPEC_MOVNT))]
22568   "TARGET_SSE2"
22569   "movntdq\t{%1, %0|%0, %1}"
22570   [(set_attr "type" "ssecvt")
22571    (set_attr "mode" "TI")])
22572
22573 (define_insn "sse2_movntsi"
22574   [(set (match_operand:SI 0 "memory_operand" "=m")
22575         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22576                    UNSPEC_MOVNT))]
22577   "TARGET_SSE2"
22578   "movnti\t{%1, %0|%0, %1}"
22579   [(set_attr "type" "ssecvt")
22580    (set_attr "mode" "V2DF")])
22581
22582 ;; SSE <-> integer/MMX conversions
22583
22584 ;; Conversions between SI and SF
22585
22586 (define_insn "cvtdq2ps"
22587   [(set (match_operand:V4SF 0 "register_operand" "=x")
22588         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22589   "TARGET_SSE2"
22590   "cvtdq2ps\t{%1, %0|%0, %1}"
22591   [(set_attr "type" "ssecvt")
22592    (set_attr "mode" "V2DF")])
22593
22594 (define_insn "cvtps2dq"
22595   [(set (match_operand:V4SI 0 "register_operand" "=x")
22596         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22597   "TARGET_SSE2"
22598   "cvtps2dq\t{%1, %0|%0, %1}"
22599   [(set_attr "type" "ssecvt")
22600    (set_attr "mode" "TI")])
22601
22602 (define_insn "cvttps2dq"
22603   [(set (match_operand:V4SI 0 "register_operand" "=x")
22604         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22605                      UNSPEC_FIX))]
22606   "TARGET_SSE2"
22607   "cvttps2dq\t{%1, %0|%0, %1}"
22608   [(set_attr "type" "ssecvt")
22609    (set_attr "mode" "TI")])
22610
22611 ;; Conversions between SI and DF
22612
22613 (define_insn "cvtdq2pd"
22614   [(set (match_operand:V2DF 0 "register_operand" "=x")
22615         (float:V2DF (vec_select:V2SI
22616                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22617                      (parallel
22618                       [(const_int 0)
22619                        (const_int 1)]))))]
22620   "TARGET_SSE2"
22621   "cvtdq2pd\t{%1, %0|%0, %1}"
22622   [(set_attr "type" "ssecvt")
22623    (set_attr "mode" "V2DF")])
22624
22625 (define_insn "cvtpd2dq"
22626   [(set (match_operand:V4SI 0 "register_operand" "=x")
22627         (vec_concat:V4SI
22628          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22629          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22630   "TARGET_SSE2"
22631   "cvtpd2dq\t{%1, %0|%0, %1}"
22632   [(set_attr "type" "ssecvt")
22633    (set_attr "mode" "TI")])
22634
22635 (define_insn "cvttpd2dq"
22636   [(set (match_operand:V4SI 0 "register_operand" "=x")
22637         (vec_concat:V4SI
22638          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22639                       UNSPEC_FIX)
22640          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22641   "TARGET_SSE2"
22642   "cvttpd2dq\t{%1, %0|%0, %1}"
22643   [(set_attr "type" "ssecvt")
22644    (set_attr "mode" "TI")])
22645
22646 (define_insn "cvtpd2pi"
22647   [(set (match_operand:V2SI 0 "register_operand" "=y")
22648         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22649   "TARGET_SSE2"
22650   "cvtpd2pi\t{%1, %0|%0, %1}"
22651   [(set_attr "type" "ssecvt")
22652    (set_attr "mode" "TI")])
22653
22654 (define_insn "cvttpd2pi"
22655   [(set (match_operand:V2SI 0 "register_operand" "=y")
22656         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22657                      UNSPEC_FIX))]
22658   "TARGET_SSE2"
22659   "cvttpd2pi\t{%1, %0|%0, %1}"
22660   [(set_attr "type" "ssecvt")
22661    (set_attr "mode" "TI")])
22662
22663 (define_insn "cvtpi2pd"
22664   [(set (match_operand:V2DF 0 "register_operand" "=x")
22665         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22666   "TARGET_SSE2"
22667   "cvtpi2pd\t{%1, %0|%0, %1}"
22668   [(set_attr "type" "ssecvt")
22669    (set_attr "mode" "TI")])
22670
22671 ;; Conversions between SI and DF
22672
22673 (define_insn "cvtsd2si"
22674   [(set (match_operand:SI 0 "register_operand" "=r,r")
22675         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22676                                (parallel [(const_int 0)]))))]
22677   "TARGET_SSE2"
22678   "cvtsd2si\t{%1, %0|%0, %1}"
22679   [(set_attr "type" "sseicvt")
22680    (set_attr "athlon_decode" "double,vector")
22681    (set_attr "mode" "SI")])
22682
22683 (define_insn "cvtsd2siq"
22684   [(set (match_operand:DI 0 "register_operand" "=r,r")
22685         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22686                                (parallel [(const_int 0)]))))]
22687   "TARGET_SSE2 && TARGET_64BIT"
22688   "cvtsd2siq\t{%1, %0|%0, %1}"
22689   [(set_attr "type" "sseicvt")
22690    (set_attr "athlon_decode" "double,vector")
22691    (set_attr "mode" "DI")])
22692
22693 (define_insn "cvttsd2si"
22694   [(set (match_operand:SI 0 "register_operand" "=r,r")
22695         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22696                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22697   "TARGET_SSE2"
22698   "cvttsd2si\t{%1, %0|%0, %1}"
22699   [(set_attr "type" "sseicvt")
22700    (set_attr "mode" "SI")
22701    (set_attr "athlon_decode" "double,vector")])
22702
22703 (define_insn "cvttsd2siq"
22704   [(set (match_operand:DI 0 "register_operand" "=r,r")
22705         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22706                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22707   "TARGET_SSE2 && TARGET_64BIT"
22708   "cvttsd2siq\t{%1, %0|%0, %1}"
22709   [(set_attr "type" "sseicvt")
22710    (set_attr "mode" "DI")
22711    (set_attr "athlon_decode" "double,vector")])
22712
22713 (define_insn "cvtsi2sd"
22714   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22715         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22716                         (vec_duplicate:V2DF
22717                           (float:DF
22718                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22719                         (const_int 2)))]
22720   "TARGET_SSE2"
22721   "cvtsi2sd\t{%2, %0|%0, %2}"
22722   [(set_attr "type" "sseicvt")
22723    (set_attr "mode" "DF")
22724    (set_attr "athlon_decode" "double,direct")])
22725
22726 (define_insn "cvtsi2sdq"
22727   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22728         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22729                         (vec_duplicate:V2DF
22730                           (float:DF
22731                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22732                         (const_int 2)))]
22733   "TARGET_SSE2 && TARGET_64BIT"
22734   "cvtsi2sdq\t{%2, %0|%0, %2}"
22735   [(set_attr "type" "sseicvt")
22736    (set_attr "mode" "DF")
22737    (set_attr "athlon_decode" "double,direct")])
22738
22739 ;; Conversions between SF and DF
22740
22741 (define_insn "cvtsd2ss"
22742   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22743         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22744                         (vec_duplicate:V4SF
22745                           (float_truncate:V2SF
22746                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22747                         (const_int 14)))]
22748   "TARGET_SSE2"
22749   "cvtsd2ss\t{%2, %0|%0, %2}"
22750   [(set_attr "type" "ssecvt")
22751    (set_attr "athlon_decode" "vector,double")
22752    (set_attr "mode" "SF")])
22753
22754 (define_insn "cvtss2sd"
22755   [(set (match_operand:V2DF 0 "register_operand" "=x")
22756         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
22757                         (float_extend:V2DF
22758                           (vec_select:V2SF
22759                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
22760                             (parallel [(const_int 0)
22761                                        (const_int 1)])))
22762                         (const_int 2)))]
22763   "TARGET_SSE2"
22764   "cvtss2sd\t{%2, %0|%0, %2}"
22765   [(set_attr "type" "ssecvt")
22766    (set_attr "mode" "DF")])
22767
22768 (define_insn "cvtpd2ps"
22769   [(set (match_operand:V4SF 0 "register_operand" "=x")
22770         (subreg:V4SF
22771           (vec_concat:V4SI
22772             (subreg:V2SI (float_truncate:V2SF
22773                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
22774             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
22775   "TARGET_SSE2"
22776   "cvtpd2ps\t{%1, %0|%0, %1}"
22777   [(set_attr "type" "ssecvt")
22778    (set_attr "mode" "V4SF")])
22779
22780 (define_insn "cvtps2pd"
22781   [(set (match_operand:V2DF 0 "register_operand" "=x")
22782         (float_extend:V2DF
22783           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
22784                            (parallel [(const_int 0)
22785                                       (const_int 1)]))))]
22786   "TARGET_SSE2"
22787   "cvtps2pd\t{%1, %0|%0, %1}"
22788   [(set_attr "type" "ssecvt")
22789    (set_attr "mode" "V2DF")])
22790
22791 ;; SSE2 variants of MMX insns
22792
22793 ;; MMX arithmetic
22794
22795 (define_insn "addv16qi3"
22796   [(set (match_operand:V16QI 0 "register_operand" "=x")
22797         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22798                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22799   "TARGET_SSE2"
22800   "paddb\t{%2, %0|%0, %2}"
22801   [(set_attr "type" "sseiadd")
22802    (set_attr "mode" "TI")])
22803
22804 (define_insn "addv8hi3"
22805   [(set (match_operand:V8HI 0 "register_operand" "=x")
22806         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22807                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22808   "TARGET_SSE2"
22809   "paddw\t{%2, %0|%0, %2}"
22810   [(set_attr "type" "sseiadd")
22811    (set_attr "mode" "TI")])
22812
22813 (define_insn "addv4si3"
22814   [(set (match_operand:V4SI 0 "register_operand" "=x")
22815         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22816                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22817   "TARGET_SSE2"
22818   "paddd\t{%2, %0|%0, %2}"
22819   [(set_attr "type" "sseiadd")
22820    (set_attr "mode" "TI")])
22821
22822 (define_insn "addv2di3"
22823   [(set (match_operand:V2DI 0 "register_operand" "=x")
22824         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
22825                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22826   "TARGET_SSE2"
22827   "paddq\t{%2, %0|%0, %2}"
22828   [(set_attr "type" "sseiadd")
22829    (set_attr "mode" "TI")])
22830
22831 (define_insn "ssaddv16qi3"
22832   [(set (match_operand:V16QI 0 "register_operand" "=x")
22833         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22834                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22835   "TARGET_SSE2"
22836   "paddsb\t{%2, %0|%0, %2}"
22837   [(set_attr "type" "sseiadd")
22838    (set_attr "mode" "TI")])
22839
22840 (define_insn "ssaddv8hi3"
22841   [(set (match_operand:V8HI 0 "register_operand" "=x")
22842         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22843                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22844   "TARGET_SSE2"
22845   "paddsw\t{%2, %0|%0, %2}"
22846   [(set_attr "type" "sseiadd")
22847    (set_attr "mode" "TI")])
22848
22849 (define_insn "usaddv16qi3"
22850   [(set (match_operand:V16QI 0 "register_operand" "=x")
22851         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22852                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22853   "TARGET_SSE2"
22854   "paddusb\t{%2, %0|%0, %2}"
22855   [(set_attr "type" "sseiadd")
22856    (set_attr "mode" "TI")])
22857
22858 (define_insn "usaddv8hi3"
22859   [(set (match_operand:V8HI 0 "register_operand" "=x")
22860         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22861                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22862   "TARGET_SSE2"
22863   "paddusw\t{%2, %0|%0, %2}"
22864   [(set_attr "type" "sseiadd")
22865    (set_attr "mode" "TI")])
22866
22867 (define_insn "subv16qi3"
22868   [(set (match_operand:V16QI 0 "register_operand" "=x")
22869         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22870                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22871   "TARGET_SSE2"
22872   "psubb\t{%2, %0|%0, %2}"
22873   [(set_attr "type" "sseiadd")
22874    (set_attr "mode" "TI")])
22875
22876 (define_insn "subv8hi3"
22877   [(set (match_operand:V8HI 0 "register_operand" "=x")
22878         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22879                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22880   "TARGET_SSE2"
22881   "psubw\t{%2, %0|%0, %2}"
22882   [(set_attr "type" "sseiadd")
22883    (set_attr "mode" "TI")])
22884
22885 (define_insn "subv4si3"
22886   [(set (match_operand:V4SI 0 "register_operand" "=x")
22887         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
22888                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22889   "TARGET_SSE2"
22890   "psubd\t{%2, %0|%0, %2}"
22891   [(set_attr "type" "sseiadd")
22892    (set_attr "mode" "TI")])
22893
22894 (define_insn "subv2di3"
22895   [(set (match_operand:V2DI 0 "register_operand" "=x")
22896         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
22897                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22898   "TARGET_SSE2"
22899   "psubq\t{%2, %0|%0, %2}"
22900   [(set_attr "type" "sseiadd")
22901    (set_attr "mode" "TI")])
22902
22903 (define_insn "sssubv16qi3"
22904   [(set (match_operand:V16QI 0 "register_operand" "=x")
22905         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22906                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22907   "TARGET_SSE2"
22908   "psubsb\t{%2, %0|%0, %2}"
22909   [(set_attr "type" "sseiadd")
22910    (set_attr "mode" "TI")])
22911
22912 (define_insn "sssubv8hi3"
22913   [(set (match_operand:V8HI 0 "register_operand" "=x")
22914         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22915                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22916   "TARGET_SSE2"
22917   "psubsw\t{%2, %0|%0, %2}"
22918   [(set_attr "type" "sseiadd")
22919    (set_attr "mode" "TI")])
22920
22921 (define_insn "ussubv16qi3"
22922   [(set (match_operand:V16QI 0 "register_operand" "=x")
22923         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22924                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22925   "TARGET_SSE2"
22926   "psubusb\t{%2, %0|%0, %2}"
22927   [(set_attr "type" "sseiadd")
22928    (set_attr "mode" "TI")])
22929
22930 (define_insn "ussubv8hi3"
22931   [(set (match_operand:V8HI 0 "register_operand" "=x")
22932         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22933                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22934   "TARGET_SSE2"
22935   "psubusw\t{%2, %0|%0, %2}"
22936   [(set_attr "type" "sseiadd")
22937    (set_attr "mode" "TI")])
22938
22939 (define_insn "mulv8hi3"
22940   [(set (match_operand:V8HI 0 "register_operand" "=x")
22941         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
22942                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22943   "TARGET_SSE2"
22944   "pmullw\t{%2, %0|%0, %2}"
22945   [(set_attr "type" "sseimul")
22946    (set_attr "mode" "TI")])
22947
22948 (define_insn "smulv8hi3_highpart"
22949   [(set (match_operand:V8HI 0 "register_operand" "=x")
22950         (truncate:V8HI
22951          (lshiftrt:V8SI
22952           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22953                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22954           (const_int 16))))]
22955   "TARGET_SSE2"
22956   "pmulhw\t{%2, %0|%0, %2}"
22957   [(set_attr "type" "sseimul")
22958    (set_attr "mode" "TI")])
22959
22960 (define_insn "umulv8hi3_highpart"
22961   [(set (match_operand:V8HI 0 "register_operand" "=x")
22962         (truncate:V8HI
22963          (lshiftrt:V8SI
22964           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22965                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22966           (const_int 16))))]
22967   "TARGET_SSE2"
22968   "pmulhuw\t{%2, %0|%0, %2}"
22969   [(set_attr "type" "sseimul")
22970    (set_attr "mode" "TI")])
22971
22972 (define_insn "sse2_umulsidi3"
22973   [(set (match_operand:DI 0 "register_operand" "=y")
22974         (mult:DI (zero_extend:DI (vec_select:SI
22975                                   (match_operand:V2SI 1 "register_operand" "0")
22976                                   (parallel [(const_int 0)])))
22977                  (zero_extend:DI (vec_select:SI
22978                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22979                                   (parallel [(const_int 0)])))))]
22980   "TARGET_SSE2"
22981   "pmuludq\t{%2, %0|%0, %2}"
22982   [(set_attr "type" "mmxmul")
22983    (set_attr "mode" "DI")])
22984
22985 (define_insn "sse2_umulv2siv2di3"
22986   [(set (match_operand:V2DI 0 "register_operand" "=x")
22987         (mult:V2DI (zero_extend:V2DI
22988                      (vec_select:V2SI
22989                        (match_operand:V4SI 1 "register_operand" "0")
22990                        (parallel [(const_int 0) (const_int 2)])))
22991                    (zero_extend:V2DI
22992                      (vec_select:V2SI
22993                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22994                        (parallel [(const_int 0) (const_int 2)])))))]
22995   "TARGET_SSE2"
22996   "pmuludq\t{%2, %0|%0, %2}"
22997   [(set_attr "type" "sseimul")
22998    (set_attr "mode" "TI")])
22999
23000 (define_insn "sse2_pmaddwd"
23001   [(set (match_operand:V4SI 0 "register_operand" "=x")
23002         (plus:V4SI
23003          (mult:V4SI
23004           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23005                                              (parallel [(const_int 0)
23006                                                         (const_int 2)
23007                                                         (const_int 4)
23008                                                         (const_int 6)])))
23009           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23010                                              (parallel [(const_int 0)
23011                                                         (const_int 2)
23012                                                         (const_int 4)
23013                                                         (const_int 6)]))))
23014          (mult:V4SI
23015           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23016                                              (parallel [(const_int 1)
23017                                                         (const_int 3)
23018                                                         (const_int 5)
23019                                                         (const_int 7)])))
23020           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23021                                              (parallel [(const_int 1)
23022                                                         (const_int 3)
23023                                                         (const_int 5)
23024                                                         (const_int 7)]))))))]
23025   "TARGET_SSE2"
23026   "pmaddwd\t{%2, %0|%0, %2}"
23027   [(set_attr "type" "sseiadd")
23028    (set_attr "mode" "TI")])
23029
23030 ;; Same as pxor, but don't show input operands so that we don't think
23031 ;; they are live.
23032 (define_insn "sse2_clrti"
23033   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23034   "TARGET_SSE2"
23035 {
23036   if (get_attr_mode (insn) == MODE_TI)
23037     return "pxor\t%0, %0";
23038   else
23039     return "xorps\t%0, %0";
23040 }
23041   [(set_attr "type" "ssemov")
23042    (set_attr "memory" "none")
23043    (set (attr "mode")
23044               (if_then_else
23045                 (ne (symbol_ref "optimize_size")
23046                     (const_int 0))
23047                 (const_string "V4SF")
23048                 (const_string "TI")))])
23049
23050 ;; MMX unsigned averages/sum of absolute differences
23051
23052 (define_insn "sse2_uavgv16qi3"
23053   [(set (match_operand:V16QI 0 "register_operand" "=x")
23054         (ashiftrt:V16QI
23055          (plus:V16QI (plus:V16QI
23056                      (match_operand:V16QI 1 "register_operand" "0")
23057                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23058                      (const_vector:V16QI [(const_int 1) (const_int 1)
23059                                           (const_int 1) (const_int 1)
23060                                           (const_int 1) (const_int 1)
23061                                           (const_int 1) (const_int 1)
23062                                           (const_int 1) (const_int 1)
23063                                           (const_int 1) (const_int 1)
23064                                           (const_int 1) (const_int 1)
23065                                           (const_int 1) (const_int 1)]))
23066          (const_int 1)))]
23067   "TARGET_SSE2"
23068   "pavgb\t{%2, %0|%0, %2}"
23069   [(set_attr "type" "sseiadd")
23070    (set_attr "mode" "TI")])
23071
23072 (define_insn "sse2_uavgv8hi3"
23073   [(set (match_operand:V8HI 0 "register_operand" "=x")
23074         (ashiftrt:V8HI
23075          (plus:V8HI (plus:V8HI
23076                      (match_operand:V8HI 1 "register_operand" "0")
23077                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23078                     (const_vector:V8HI [(const_int 1) (const_int 1)
23079                                         (const_int 1) (const_int 1)
23080                                         (const_int 1) (const_int 1)
23081                                         (const_int 1) (const_int 1)]))
23082          (const_int 1)))]
23083   "TARGET_SSE2"
23084   "pavgw\t{%2, %0|%0, %2}"
23085   [(set_attr "type" "sseiadd")
23086    (set_attr "mode" "TI")])
23087
23088 ;; @@@ this isn't the right representation.
23089 (define_insn "sse2_psadbw"
23090   [(set (match_operand:V2DI 0 "register_operand" "=x")
23091         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23092                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23093                      UNSPEC_PSADBW))]
23094   "TARGET_SSE2"
23095   "psadbw\t{%2, %0|%0, %2}"
23096   [(set_attr "type" "sseiadd")
23097    (set_attr "mode" "TI")])
23098
23099
23100 ;; MMX insert/extract/shuffle
23101
23102 (define_insn "sse2_pinsrw"
23103   [(set (match_operand:V8HI 0 "register_operand" "=x")
23104         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
23105                         (vec_duplicate:V8HI
23106                          (truncate:HI
23107                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
23108                         (match_operand:SI 3 "const_0_to_255_operand" "N")))]
23109   "TARGET_SSE2"
23110   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
23111   [(set_attr "type" "ssecvt")
23112    (set_attr "mode" "TI")])
23113
23114 (define_insn "sse2_pextrw"
23115   [(set (match_operand:SI 0 "register_operand" "=r")
23116         (zero_extend:SI
23117           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23118                          (parallel
23119                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23120   "TARGET_SSE2"
23121   "pextrw\t{%2, %1, %0|%0, %1, %2}"
23122   [(set_attr "type" "ssecvt")
23123    (set_attr "mode" "TI")])
23124
23125 (define_insn "sse2_pshufd"
23126   [(set (match_operand:V4SI 0 "register_operand" "=x")
23127         (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23128                       (match_operand:SI 2 "immediate_operand" "i")]
23129                      UNSPEC_SHUFFLE))]
23130   "TARGET_SSE2"
23131   "pshufd\t{%2, %1, %0|%0, %1, %2}"
23132   [(set_attr "type" "ssecvt")
23133    (set_attr "mode" "TI")])
23134
23135 (define_insn "sse2_pshuflw"
23136   [(set (match_operand:V8HI 0 "register_operand" "=x")
23137         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23138                       (match_operand:SI 2 "immediate_operand" "i")]
23139                      UNSPEC_PSHUFLW))]
23140   "TARGET_SSE2"
23141   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23142   [(set_attr "type" "ssecvt")
23143    (set_attr "mode" "TI")])
23144
23145 (define_insn "sse2_pshufhw"
23146   [(set (match_operand:V8HI 0 "register_operand" "=x")
23147         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23148                       (match_operand:SI 2 "immediate_operand" "i")]
23149                      UNSPEC_PSHUFHW))]
23150   "TARGET_SSE2"
23151   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23152   [(set_attr "type" "ssecvt")
23153    (set_attr "mode" "TI")])
23154
23155 ;; MMX mask-generating comparisons
23156
23157 (define_insn "eqv16qi3"
23158   [(set (match_operand:V16QI 0 "register_operand" "=x")
23159         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23160                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23161   "TARGET_SSE2"
23162   "pcmpeqb\t{%2, %0|%0, %2}"
23163   [(set_attr "type" "ssecmp")
23164    (set_attr "mode" "TI")])
23165
23166 (define_insn "eqv8hi3"
23167   [(set (match_operand:V8HI 0 "register_operand" "=x")
23168         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23169                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23170   "TARGET_SSE2"
23171   "pcmpeqw\t{%2, %0|%0, %2}"
23172   [(set_attr "type" "ssecmp")
23173    (set_attr "mode" "TI")])
23174
23175 (define_insn "eqv4si3"
23176   [(set (match_operand:V4SI 0 "register_operand" "=x")
23177         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23178                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23179   "TARGET_SSE2"
23180   "pcmpeqd\t{%2, %0|%0, %2}"
23181   [(set_attr "type" "ssecmp")
23182    (set_attr "mode" "TI")])
23183
23184 (define_insn "gtv16qi3"
23185   [(set (match_operand:V16QI 0 "register_operand" "=x")
23186         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23187                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23188   "TARGET_SSE2"
23189   "pcmpgtb\t{%2, %0|%0, %2}"
23190   [(set_attr "type" "ssecmp")
23191    (set_attr "mode" "TI")])
23192
23193 (define_insn "gtv8hi3"
23194   [(set (match_operand:V8HI 0 "register_operand" "=x")
23195         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23196                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23197   "TARGET_SSE2"
23198   "pcmpgtw\t{%2, %0|%0, %2}"
23199   [(set_attr "type" "ssecmp")
23200    (set_attr "mode" "TI")])
23201
23202 (define_insn "gtv4si3"
23203   [(set (match_operand:V4SI 0 "register_operand" "=x")
23204         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23205                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23206   "TARGET_SSE2"
23207   "pcmpgtd\t{%2, %0|%0, %2}"
23208   [(set_attr "type" "ssecmp")
23209    (set_attr "mode" "TI")])
23210
23211
23212 ;; MMX max/min insns
23213
23214 (define_insn "umaxv16qi3"
23215   [(set (match_operand:V16QI 0 "register_operand" "=x")
23216         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23217                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23218   "TARGET_SSE2"
23219   "pmaxub\t{%2, %0|%0, %2}"
23220   [(set_attr "type" "sseiadd")
23221    (set_attr "mode" "TI")])
23222
23223 (define_insn "smaxv8hi3"
23224   [(set (match_operand:V8HI 0 "register_operand" "=x")
23225         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23226                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23227   "TARGET_SSE2"
23228   "pmaxsw\t{%2, %0|%0, %2}"
23229   [(set_attr "type" "sseiadd")
23230    (set_attr "mode" "TI")])
23231
23232 (define_insn "uminv16qi3"
23233   [(set (match_operand:V16QI 0 "register_operand" "=x")
23234         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23235                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23236   "TARGET_SSE2"
23237   "pminub\t{%2, %0|%0, %2}"
23238   [(set_attr "type" "sseiadd")
23239    (set_attr "mode" "TI")])
23240
23241 (define_insn "sminv8hi3"
23242   [(set (match_operand:V8HI 0 "register_operand" "=x")
23243         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23244                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23245   "TARGET_SSE2"
23246   "pminsw\t{%2, %0|%0, %2}"
23247   [(set_attr "type" "sseiadd")
23248    (set_attr "mode" "TI")])
23249
23250
23251 ;; MMX shifts
23252
23253 (define_insn "ashrv8hi3"
23254   [(set (match_operand:V8HI 0 "register_operand" "=x")
23255         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23256                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23257   "TARGET_SSE2"
23258   "psraw\t{%2, %0|%0, %2}"
23259   [(set_attr "type" "sseishft")
23260    (set_attr "mode" "TI")])
23261
23262 (define_insn "ashrv4si3"
23263   [(set (match_operand:V4SI 0 "register_operand" "=x")
23264         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23265                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23266   "TARGET_SSE2"
23267   "psrad\t{%2, %0|%0, %2}"
23268   [(set_attr "type" "sseishft")
23269    (set_attr "mode" "TI")])
23270
23271 (define_insn "lshrv8hi3"
23272   [(set (match_operand:V8HI 0 "register_operand" "=x")
23273         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23274                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23275   "TARGET_SSE2"
23276   "psrlw\t{%2, %0|%0, %2}"
23277   [(set_attr "type" "sseishft")
23278    (set_attr "mode" "TI")])
23279
23280 (define_insn "lshrv4si3"
23281   [(set (match_operand:V4SI 0 "register_operand" "=x")
23282         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23283                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23284   "TARGET_SSE2"
23285   "psrld\t{%2, %0|%0, %2}"
23286   [(set_attr "type" "sseishft")
23287    (set_attr "mode" "TI")])
23288
23289 (define_insn "lshrv2di3"
23290   [(set (match_operand:V2DI 0 "register_operand" "=x")
23291         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23292                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23293   "TARGET_SSE2"
23294   "psrlq\t{%2, %0|%0, %2}"
23295   [(set_attr "type" "sseishft")
23296    (set_attr "mode" "TI")])
23297
23298 (define_insn "ashlv8hi3"
23299   [(set (match_operand:V8HI 0 "register_operand" "=x")
23300         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23301                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23302   "TARGET_SSE2"
23303   "psllw\t{%2, %0|%0, %2}"
23304   [(set_attr "type" "sseishft")
23305    (set_attr "mode" "TI")])
23306
23307 (define_insn "ashlv4si3"
23308   [(set (match_operand:V4SI 0 "register_operand" "=x")
23309         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23310                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23311   "TARGET_SSE2"
23312   "pslld\t{%2, %0|%0, %2}"
23313   [(set_attr "type" "sseishft")
23314    (set_attr "mode" "TI")])
23315
23316 (define_insn "ashlv2di3"
23317   [(set (match_operand:V2DI 0 "register_operand" "=x")
23318         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23319                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23320   "TARGET_SSE2"
23321   "psllq\t{%2, %0|%0, %2}"
23322   [(set_attr "type" "sseishft")
23323    (set_attr "mode" "TI")])
23324
23325 (define_insn "ashrv8hi3_ti"
23326   [(set (match_operand:V8HI 0 "register_operand" "=x")
23327         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23328                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23329   "TARGET_SSE2"
23330   "psraw\t{%2, %0|%0, %2}"
23331   [(set_attr "type" "sseishft")
23332    (set_attr "mode" "TI")])
23333
23334 (define_insn "ashrv4si3_ti"
23335   [(set (match_operand:V4SI 0 "register_operand" "=x")
23336         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23337                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23338   "TARGET_SSE2"
23339   "psrad\t{%2, %0|%0, %2}"
23340   [(set_attr "type" "sseishft")
23341    (set_attr "mode" "TI")])
23342
23343 (define_insn "lshrv8hi3_ti"
23344   [(set (match_operand:V8HI 0 "register_operand" "=x")
23345         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23346                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23347   "TARGET_SSE2"
23348   "psrlw\t{%2, %0|%0, %2}"
23349   [(set_attr "type" "sseishft")
23350    (set_attr "mode" "TI")])
23351
23352 (define_insn "lshrv4si3_ti"
23353   [(set (match_operand:V4SI 0 "register_operand" "=x")
23354         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23355                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23356   "TARGET_SSE2"
23357   "psrld\t{%2, %0|%0, %2}"
23358   [(set_attr "type" "sseishft")
23359    (set_attr "mode" "TI")])
23360
23361 (define_insn "lshrv2di3_ti"
23362   [(set (match_operand:V2DI 0 "register_operand" "=x")
23363         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23364                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23365   "TARGET_SSE2"
23366   "psrlq\t{%2, %0|%0, %2}"
23367   [(set_attr "type" "sseishft")
23368    (set_attr "mode" "TI")])
23369
23370 (define_insn "ashlv8hi3_ti"
23371   [(set (match_operand:V8HI 0 "register_operand" "=x")
23372         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23373                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23374   "TARGET_SSE2"
23375   "psllw\t{%2, %0|%0, %2}"
23376   [(set_attr "type" "sseishft")
23377    (set_attr "mode" "TI")])
23378
23379 (define_insn "ashlv4si3_ti"
23380   [(set (match_operand:V4SI 0 "register_operand" "=x")
23381         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23382                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23383   "TARGET_SSE2"
23384   "pslld\t{%2, %0|%0, %2}"
23385   [(set_attr "type" "sseishft")
23386    (set_attr "mode" "TI")])
23387
23388 (define_insn "ashlv2di3_ti"
23389   [(set (match_operand:V2DI 0 "register_operand" "=x")
23390         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23391                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23392   "TARGET_SSE2"
23393   "psllq\t{%2, %0|%0, %2}"
23394   [(set_attr "type" "sseishft")
23395    (set_attr "mode" "TI")])
23396
23397 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
23398 ;; we wouldn't need here it since we never generate TImode arithmetic.
23399
23400 ;; There has to be some kind of prize for the weirdest new instruction...
23401 (define_insn "sse2_ashlti3"
23402   [(set (match_operand:TI 0 "register_operand" "=x")
23403         (unspec:TI
23404          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23405                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23406                                (const_int 8)))] UNSPEC_NOP))]
23407   "TARGET_SSE2"
23408   "pslldq\t{%2, %0|%0, %2}"
23409   [(set_attr "type" "sseishft")
23410    (set_attr "mode" "TI")])
23411
23412 (define_insn "sse2_lshrti3"
23413   [(set (match_operand:TI 0 "register_operand" "=x")
23414         (unspec:TI
23415          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23416                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23417                                 (const_int 8)))] UNSPEC_NOP))]
23418   "TARGET_SSE2"
23419   "psrldq\t{%2, %0|%0, %2}"
23420   [(set_attr "type" "sseishft")
23421    (set_attr "mode" "TI")])
23422
23423 ;; SSE unpack
23424
23425 (define_insn "sse2_unpckhpd"
23426   [(set (match_operand:V2DF 0 "register_operand" "=x")
23427         (vec_concat:V2DF
23428          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23429                         (parallel [(const_int 1)]))
23430          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23431                         (parallel [(const_int 1)]))))]
23432   "TARGET_SSE2"
23433   "unpckhpd\t{%2, %0|%0, %2}"
23434   [(set_attr "type" "ssecvt")
23435    (set_attr "mode" "V2DF")])
23436
23437 (define_insn "sse2_unpcklpd"
23438   [(set (match_operand:V2DF 0 "register_operand" "=x")
23439         (vec_concat:V2DF
23440          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23441                         (parallel [(const_int 0)]))
23442          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23443                         (parallel [(const_int 0)]))))]
23444   "TARGET_SSE2"
23445   "unpcklpd\t{%2, %0|%0, %2}"
23446   [(set_attr "type" "ssecvt")
23447    (set_attr "mode" "V2DF")])
23448
23449 ;; MMX pack/unpack insns.
23450
23451 (define_insn "sse2_packsswb"
23452   [(set (match_operand:V16QI 0 "register_operand" "=x")
23453         (vec_concat:V16QI
23454          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23455          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23456   "TARGET_SSE2"
23457   "packsswb\t{%2, %0|%0, %2}"
23458   [(set_attr "type" "ssecvt")
23459    (set_attr "mode" "TI")])
23460
23461 (define_insn "sse2_packssdw"
23462   [(set (match_operand:V8HI 0 "register_operand" "=x")
23463         (vec_concat:V8HI
23464          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23465          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23466   "TARGET_SSE2"
23467   "packssdw\t{%2, %0|%0, %2}"
23468   [(set_attr "type" "ssecvt")
23469    (set_attr "mode" "TI")])
23470
23471 (define_insn "sse2_packuswb"
23472   [(set (match_operand:V16QI 0 "register_operand" "=x")
23473         (vec_concat:V16QI
23474          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23475          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23476   "TARGET_SSE2"
23477   "packuswb\t{%2, %0|%0, %2}"
23478   [(set_attr "type" "ssecvt")
23479    (set_attr "mode" "TI")])
23480
23481 (define_insn "sse2_punpckhbw"
23482   [(set (match_operand:V16QI 0 "register_operand" "=x")
23483         (vec_merge:V16QI
23484          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23485                            (parallel [(const_int 8) (const_int 0)
23486                                       (const_int 9) (const_int 1)
23487                                       (const_int 10) (const_int 2)
23488                                       (const_int 11) (const_int 3)
23489                                       (const_int 12) (const_int 4)
23490                                       (const_int 13) (const_int 5)
23491                                       (const_int 14) (const_int 6)
23492                                       (const_int 15) (const_int 7)]))
23493          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23494                            (parallel [(const_int 0) (const_int 8)
23495                                       (const_int 1) (const_int 9)
23496                                       (const_int 2) (const_int 10)
23497                                       (const_int 3) (const_int 11)
23498                                       (const_int 4) (const_int 12)
23499                                       (const_int 5) (const_int 13)
23500                                       (const_int 6) (const_int 14)
23501                                       (const_int 7) (const_int 15)]))
23502          (const_int 21845)))]
23503   "TARGET_SSE2"
23504   "punpckhbw\t{%2, %0|%0, %2}"
23505   [(set_attr "type" "ssecvt")
23506    (set_attr "mode" "TI")])
23507
23508 (define_insn "sse2_punpckhwd"
23509   [(set (match_operand:V8HI 0 "register_operand" "=x")
23510         (vec_merge:V8HI
23511          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23512                           (parallel [(const_int 4) (const_int 0)
23513                                      (const_int 5) (const_int 1)
23514                                      (const_int 6) (const_int 2)
23515                                      (const_int 7) (const_int 3)]))
23516          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23517                           (parallel [(const_int 0) (const_int 4)
23518                                      (const_int 1) (const_int 5)
23519                                      (const_int 2) (const_int 6)
23520                                      (const_int 3) (const_int 7)]))
23521          (const_int 85)))]
23522   "TARGET_SSE2"
23523   "punpckhwd\t{%2, %0|%0, %2}"
23524   [(set_attr "type" "ssecvt")
23525    (set_attr "mode" "TI")])
23526
23527 (define_insn "sse2_punpckhdq"
23528   [(set (match_operand:V4SI 0 "register_operand" "=x")
23529         (vec_merge:V4SI
23530          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23531                           (parallel [(const_int 2) (const_int 0)
23532                                      (const_int 3) (const_int 1)]))
23533          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23534                           (parallel [(const_int 0) (const_int 2)
23535                                      (const_int 1) (const_int 3)]))
23536          (const_int 5)))]
23537   "TARGET_SSE2"
23538   "punpckhdq\t{%2, %0|%0, %2}"
23539   [(set_attr "type" "ssecvt")
23540    (set_attr "mode" "TI")])
23541
23542 (define_insn "sse2_punpcklbw"
23543   [(set (match_operand:V16QI 0 "register_operand" "=x")
23544         (vec_merge:V16QI
23545          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23546                            (parallel [(const_int 0) (const_int 8)
23547                                       (const_int 1) (const_int 9)
23548                                       (const_int 2) (const_int 10)
23549                                       (const_int 3) (const_int 11)
23550                                       (const_int 4) (const_int 12)
23551                                       (const_int 5) (const_int 13)
23552                                       (const_int 6) (const_int 14)
23553                                       (const_int 7) (const_int 15)]))
23554          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23555                            (parallel [(const_int 8) (const_int 0)
23556                                       (const_int 9) (const_int 1)
23557                                       (const_int 10) (const_int 2)
23558                                       (const_int 11) (const_int 3)
23559                                       (const_int 12) (const_int 4)
23560                                       (const_int 13) (const_int 5)
23561                                       (const_int 14) (const_int 6)
23562                                       (const_int 15) (const_int 7)]))
23563          (const_int 21845)))]
23564   "TARGET_SSE2"
23565   "punpcklbw\t{%2, %0|%0, %2}"
23566   [(set_attr "type" "ssecvt")
23567    (set_attr "mode" "TI")])
23568
23569 (define_insn "sse2_punpcklwd"
23570   [(set (match_operand:V8HI 0 "register_operand" "=x")
23571         (vec_merge:V8HI
23572          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23573                           (parallel [(const_int 0) (const_int 4)
23574                                      (const_int 1) (const_int 5)
23575                                      (const_int 2) (const_int 6)
23576                                      (const_int 3) (const_int 7)]))
23577          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23578                           (parallel [(const_int 4) (const_int 0)
23579                                      (const_int 5) (const_int 1)
23580                                      (const_int 6) (const_int 2)
23581                                      (const_int 7) (const_int 3)]))
23582          (const_int 85)))]
23583   "TARGET_SSE2"
23584   "punpcklwd\t{%2, %0|%0, %2}"
23585   [(set_attr "type" "ssecvt")
23586    (set_attr "mode" "TI")])
23587
23588 (define_insn "sse2_punpckldq"
23589   [(set (match_operand:V4SI 0 "register_operand" "=x")
23590         (vec_merge:V4SI
23591          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23592                           (parallel [(const_int 0) (const_int 2)
23593                                      (const_int 1) (const_int 3)]))
23594          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23595                           (parallel [(const_int 2) (const_int 0)
23596                                      (const_int 3) (const_int 1)]))
23597          (const_int 5)))]
23598   "TARGET_SSE2"
23599   "punpckldq\t{%2, %0|%0, %2}"
23600   [(set_attr "type" "ssecvt")
23601    (set_attr "mode" "TI")])
23602
23603 (define_insn "sse2_punpcklqdq"
23604   [(set (match_operand:V2DI 0 "register_operand" "=x")
23605         (vec_merge:V2DI
23606          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23607                           (parallel [(const_int 1)
23608                                      (const_int 0)]))
23609          (match_operand:V2DI 1 "register_operand" "0")
23610          (const_int 1)))]
23611   "TARGET_SSE2"
23612   "punpcklqdq\t{%2, %0|%0, %2}"
23613   [(set_attr "type" "ssecvt")
23614    (set_attr "mode" "TI")])
23615
23616 (define_insn "sse2_punpckhqdq"
23617   [(set (match_operand:V2DI 0 "register_operand" "=x")
23618         (vec_merge:V2DI
23619          (match_operand:V2DI 1 "register_operand" "0")
23620          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23621                           (parallel [(const_int 1)
23622                                      (const_int 0)]))
23623          (const_int 1)))]
23624   "TARGET_SSE2"
23625   "punpckhqdq\t{%2, %0|%0, %2}"
23626   [(set_attr "type" "ssecvt")
23627    (set_attr "mode" "TI")])
23628
23629 ;; SSE2 moves
23630
23631 (define_insn "sse2_movapd"
23632   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23633         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23634                      UNSPEC_MOVA))]
23635   "TARGET_SSE2
23636    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23637   "movapd\t{%1, %0|%0, %1}"
23638   [(set_attr "type" "ssemov")
23639    (set_attr "mode" "V2DF")])
23640
23641 (define_insn "sse2_movupd"
23642   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23643         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23644                      UNSPEC_MOVU))]
23645   "TARGET_SSE2
23646    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23647   "movupd\t{%1, %0|%0, %1}"
23648   [(set_attr "type" "ssecvt")
23649    (set_attr "mode" "V2DF")])
23650
23651 (define_insn "sse2_movdqa"
23652   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23653         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23654                        UNSPEC_MOVA))]
23655   "TARGET_SSE2
23656    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23657   "movdqa\t{%1, %0|%0, %1}"
23658   [(set_attr "type" "ssemov")
23659    (set_attr "mode" "TI")])
23660
23661 (define_insn "sse2_movdqu"
23662   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23663         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23664                        UNSPEC_MOVU))]
23665   "TARGET_SSE2
23666    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23667   "movdqu\t{%1, %0|%0, %1}"
23668   [(set_attr "type" "ssecvt")
23669    (set_attr "mode" "TI")])
23670
23671 (define_insn "sse2_movdq2q"
23672   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23673         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23674                        (parallel [(const_int 0)])))]
23675   "TARGET_SSE2 && !TARGET_64BIT"
23676   "@
23677    movq\t{%1, %0|%0, %1}
23678    movdq2q\t{%1, %0|%0, %1}"
23679   [(set_attr "type" "ssecvt")
23680    (set_attr "mode" "TI")])
23681
23682 (define_insn "sse2_movdq2q_rex64"
23683   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23684         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23685                        (parallel [(const_int 0)])))]
23686   "TARGET_SSE2 && TARGET_64BIT"
23687   "@
23688    movq\t{%1, %0|%0, %1}
23689    movdq2q\t{%1, %0|%0, %1}
23690    movd\t{%1, %0|%0, %1}"
23691   [(set_attr "type" "ssecvt")
23692    (set_attr "mode" "TI")])
23693
23694 (define_insn "sse2_movq2dq"
23695   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23696         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23697                          (const_int 0)))]
23698   "TARGET_SSE2 && !TARGET_64BIT"
23699   "@
23700    movq\t{%1, %0|%0, %1}
23701    movq2dq\t{%1, %0|%0, %1}"
23702   [(set_attr "type" "ssecvt,ssemov")
23703    (set_attr "mode" "TI")])
23704
23705 (define_insn "sse2_movq2dq_rex64"
23706   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23707         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23708                          (const_int 0)))]
23709   "TARGET_SSE2 && TARGET_64BIT"
23710   "@
23711    movq\t{%1, %0|%0, %1}
23712    movq2dq\t{%1, %0|%0, %1}
23713    movd\t{%1, %0|%0, %1}"
23714   [(set_attr "type" "ssecvt,ssemov,ssecvt")
23715    (set_attr "mode" "TI")])
23716
23717 (define_insn "sse2_movq"
23718   [(set (match_operand:V2DI 0 "register_operand" "=x")
23719         (vec_concat:V2DI (vec_select:DI
23720                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23721                           (parallel [(const_int 0)]))
23722                          (const_int 0)))]
23723   "TARGET_SSE2"
23724   "movq\t{%1, %0|%0, %1}"
23725   [(set_attr "type" "ssemov")
23726    (set_attr "mode" "TI")])
23727
23728 (define_insn "sse2_loadd"
23729   [(set (match_operand:V4SI 0 "register_operand" "=x")
23730         (vec_merge:V4SI
23731          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23732          (const_vector:V4SI [(const_int 0)
23733                              (const_int 0)
23734                              (const_int 0)
23735                              (const_int 0)])
23736          (const_int 1)))]
23737   "TARGET_SSE2"
23738   "movd\t{%1, %0|%0, %1}"
23739   [(set_attr "type" "ssemov")
23740    (set_attr "mode" "TI")])
23741
23742 (define_insn "sse2_stored"
23743   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23744         (vec_select:SI
23745          (match_operand:V4SI 1 "register_operand" "x")
23746          (parallel [(const_int 0)])))]
23747   "TARGET_SSE2"
23748   "movd\t{%1, %0|%0, %1}"
23749   [(set_attr "type" "ssemov")
23750    (set_attr "mode" "TI")])
23751
23752 (define_insn "sse2_movhpd"
23753   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23754         (vec_merge:V2DF
23755          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23756          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23757          (const_int 1)))]
23758   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23759   "movhpd\t{%2, %0|%0, %2}"
23760   [(set_attr "type" "ssecvt")
23761    (set_attr "mode" "V2DF")])
23762
23763 (define_expand "sse2_loadsd"
23764   [(match_operand:V2DF 0 "register_operand" "")
23765    (match_operand:DF 1 "memory_operand" "")]
23766   "TARGET_SSE2"
23767 {
23768   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
23769                                 CONST0_RTX (V2DFmode)));
23770   DONE;
23771 })
23772
23773 (define_insn "sse2_loadsd_1"
23774   [(set (match_operand:V2DF 0 "register_operand" "=x")
23775         (vec_merge:V2DF
23776          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
23777          (match_operand:V2DF 2 "const0_operand" "X")
23778          (const_int 1)))]
23779   "TARGET_SSE2"
23780   "movsd\t{%1, %0|%0, %1}"
23781   [(set_attr "type" "ssecvt")
23782    (set_attr "mode" "DF")])
23783
23784 ;; ??? We ought to be using ix86_binary_operator_ok on this pattern, so
23785 ;; that we enforce the whole matching memory thing through combine et al.
23786 ;; But that requires that things be set up properly when invoked via an
23787 ;; intrinsic, which we don't do.  Which leads to instantiate virtual regs
23788 ;; lossage, as seen compiling gcc.dg/i386-sse-2.c for x86_64 at -O0.
23789 (define_insn "sse2_movsd"
23790   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
23791         (vec_merge:V2DF
23792          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
23793          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
23794          (const_int 2)))]
23795   "TARGET_SSE2"
23796   "@movsd\t{%2, %0|%0, %2}
23797     movlpd\t{%2, %0|%0, %2}
23798     movlpd\t{%2, %0|%0, %2}"
23799   [(set_attr "type" "ssecvt")
23800    (set_attr "mode" "DF,V2DF,V2DF")])
23801
23802 (define_insn "sse2_storesd"
23803   [(set (match_operand:DF 0 "memory_operand" "=m")
23804         (vec_select:DF
23805          (match_operand:V2DF 1 "register_operand" "x")
23806          (parallel [(const_int 0)])))]
23807   "TARGET_SSE2"
23808   "movsd\t{%1, %0|%0, %1}"
23809   [(set_attr "type" "ssecvt")
23810    (set_attr "mode" "DF")])
23811
23812 (define_insn "sse2_shufpd"
23813   [(set (match_operand:V2DF 0 "register_operand" "=x")
23814         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23815                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
23816                       (match_operand:SI 3 "immediate_operand" "i")]
23817                      UNSPEC_SHUFFLE))]
23818   "TARGET_SSE2"
23819   ;; @@@ check operand order for intel/nonintel syntax
23820   "shufpd\t{%3, %2, %0|%0, %2, %3}"
23821   [(set_attr "type" "ssecvt")
23822    (set_attr "mode" "V2DF")])
23823
23824 (define_insn "sse2_clflush"
23825   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
23826                     UNSPECV_CLFLUSH)]
23827   "TARGET_SSE2"
23828   "clflush\t%a0"
23829   [(set_attr "type" "sse")
23830    (set_attr "memory" "unknown")])
23831
23832 (define_expand "sse2_mfence"
23833   [(set (match_dup 0)
23834         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23835   "TARGET_SSE2"
23836 {
23837   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23838   MEM_VOLATILE_P (operands[0]) = 1;
23839 })
23840
23841 (define_insn "*mfence_insn"
23842   [(set (match_operand:BLK 0 "" "")
23843         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23844   "TARGET_SSE2"
23845   "mfence"
23846   [(set_attr "type" "sse")
23847    (set_attr "memory" "unknown")])
23848
23849 (define_expand "sse2_lfence"
23850   [(set (match_dup 0)
23851         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23852   "TARGET_SSE2"
23853 {
23854   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23855   MEM_VOLATILE_P (operands[0]) = 1;
23856 })
23857
23858 (define_insn "*lfence_insn"
23859   [(set (match_operand:BLK 0 "" "")
23860         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23861   "TARGET_SSE2"
23862   "lfence"
23863   [(set_attr "type" "sse")
23864    (set_attr "memory" "unknown")])
23865
23866 ;; SSE3
23867
23868 (define_insn "mwait"
23869   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23870                      (match_operand:SI 1 "register_operand" "c")]
23871                     UNSPECV_MWAIT)]
23872   "TARGET_SSE3"
23873   "mwait\t%0, %1"
23874   [(set_attr "length" "3")])
23875
23876 (define_insn "monitor"
23877   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23878                      (match_operand:SI 1 "register_operand" "c")
23879                      (match_operand:SI 2 "register_operand" "d")]
23880                     UNSPECV_MONITOR)]
23881   "TARGET_SSE3"
23882   "monitor\t%0, %1, %2"
23883   [(set_attr "length" "3")])
23884
23885 ;; SSE3 arithmetic
23886
23887 (define_insn "addsubv4sf3"
23888   [(set (match_operand:V4SF 0 "register_operand" "=x")
23889         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23890                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23891                      UNSPEC_ADDSUB))]
23892   "TARGET_SSE3"
23893   "addsubps\t{%2, %0|%0, %2}"
23894   [(set_attr "type" "sseadd")
23895    (set_attr "mode" "V4SF")])
23896
23897 (define_insn "addsubv2df3"
23898   [(set (match_operand:V2DF 0 "register_operand" "=x")
23899         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23900                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23901                      UNSPEC_ADDSUB))]
23902   "TARGET_SSE3"
23903   "addsubpd\t{%2, %0|%0, %2}"
23904   [(set_attr "type" "sseadd")
23905    (set_attr "mode" "V2DF")])
23906
23907 (define_insn "haddv4sf3"
23908   [(set (match_operand:V4SF 0 "register_operand" "=x")
23909         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23910                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23911                      UNSPEC_HADD))]
23912   "TARGET_SSE3"
23913   "haddps\t{%2, %0|%0, %2}"
23914   [(set_attr "type" "sseadd")
23915    (set_attr "mode" "V4SF")])
23916
23917 (define_insn "haddv2df3"
23918   [(set (match_operand:V2DF 0 "register_operand" "=x")
23919         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23920                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23921                      UNSPEC_HADD))]
23922   "TARGET_SSE3"
23923   "haddpd\t{%2, %0|%0, %2}"
23924   [(set_attr "type" "sseadd")
23925    (set_attr "mode" "V2DF")])
23926
23927 (define_insn "hsubv4sf3"
23928   [(set (match_operand:V4SF 0 "register_operand" "=x")
23929         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23930                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23931                      UNSPEC_HSUB))]
23932   "TARGET_SSE3"
23933   "hsubps\t{%2, %0|%0, %2}"
23934   [(set_attr "type" "sseadd")
23935    (set_attr "mode" "V4SF")])
23936
23937 (define_insn "hsubv2df3"
23938   [(set (match_operand:V2DF 0 "register_operand" "=x")
23939         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23940                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23941                      UNSPEC_HSUB))]
23942   "TARGET_SSE3"
23943   "hsubpd\t{%2, %0|%0, %2}"
23944   [(set_attr "type" "sseadd")
23945    (set_attr "mode" "V2DF")])
23946
23947 (define_insn "movshdup"
23948   [(set (match_operand:V4SF 0 "register_operand" "=x")
23949         (unspec:V4SF
23950          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
23951   "TARGET_SSE3"
23952   "movshdup\t{%1, %0|%0, %1}"
23953   [(set_attr "type" "sse")
23954    (set_attr "mode" "V4SF")])
23955
23956 (define_insn "movsldup"
23957   [(set (match_operand:V4SF 0 "register_operand" "=x")
23958         (unspec:V4SF
23959          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
23960   "TARGET_SSE3"
23961   "movsldup\t{%1, %0|%0, %1}"
23962   [(set_attr "type" "sse")
23963    (set_attr "mode" "V4SF")])
23964
23965 (define_insn "lddqu"
23966   [(set (match_operand:V16QI 0 "register_operand" "=x")
23967         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
23968                        UNSPEC_LDQQU))]
23969   "TARGET_SSE3"
23970   "lddqu\t{%1, %0|%0, %1}"
23971   [(set_attr "type" "ssecvt")
23972    (set_attr "mode" "TI")])
23973
23974 (define_insn "loadddup"
23975   [(set (match_operand:V2DF 0 "register_operand" "=x")
23976         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
23977   "TARGET_SSE3"
23978   "movddup\t{%1, %0|%0, %1}"
23979   [(set_attr "type" "ssecvt")
23980    (set_attr "mode" "DF")])
23981
23982 (define_insn "movddup"
23983   [(set (match_operand:V2DF 0 "register_operand" "=x")
23984         (vec_duplicate:V2DF
23985          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
23986                         (parallel [(const_int 0)]))))]
23987   "TARGET_SSE3"
23988   "movddup\t{%1, %0|%0, %1}"
23989   [(set_attr "type" "ssecvt")
23990    (set_attr "mode" "DF")])