OSDN Git Service

* config/i386/i386.md (btsq, btrq, btcq): Fix modes.
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69
70    ; TLS support
71    (UNSPEC_TP                   15)
72    (UNSPEC_TLS_GD               16)
73    (UNSPEC_TLS_LD_BASE          17)
74
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_SIN                  21)
78    (UNSPEC_COS                  22)
79    (UNSPEC_FNSTSW               24)
80    (UNSPEC_SAHF                 25)
81    (UNSPEC_FSTCW                26)
82    (UNSPEC_ADD_CARRY            27)
83    (UNSPEC_FLDCW                28)
84
85    ; For SSE/MMX support:
86    (UNSPEC_FIX                  30)
87    (UNSPEC_MASKMOV              32)
88    (UNSPEC_MOVMSK               33)
89    (UNSPEC_MOVNT                34)
90    (UNSPEC_MOVA                 38)
91    (UNSPEC_MOVU                 39)
92    (UNSPEC_SHUFFLE              41)
93    (UNSPEC_RCP                  42)
94    (UNSPEC_RSQRT                43)
95    (UNSPEC_SFENCE               44)
96    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
97    (UNSPEC_PAVGUSB              49)
98    (UNSPEC_PFRCP                50)
99    (UNSPEC_PFRCPIT1             51)
100    (UNSPEC_PFRCPIT2             52)
101    (UNSPEC_PFRSQRT              53)
102    (UNSPEC_PFRSQIT1             54)
103    (UNSPEC_PSHUFLW              55)
104    (UNSPEC_PSHUFHW              56)
105    (UNSPEC_MFENCE               59)
106    (UNSPEC_LFENCE               60)
107    (UNSPEC_PSADBW               61)
108    (UNSPEC_ADDSUB               71)
109    (UNSPEC_HADD                 72)
110    (UNSPEC_HSUB                 73)
111    (UNSPEC_MOVSHDUP             74)
112    (UNSPEC_MOVSLDUP             75)
113    (UNSPEC_LDQQU                76)
114    (UNSPEC_MOVDDUP              77)
115
116    ; x87 Floating point
117    (UNSPEC_FPATAN               65)
118    (UNSPEC_FYL2X                66)
119    (UNSPEC_FYL2XP1              67)
120    (UNSPEC_FRNDINT              68)
121    (UNSPEC_F2XM1                69)
122
123    ; x87 Double output FP
124    (UNSPEC_SINCOS_COS           80)
125    (UNSPEC_SINCOS_SIN           81)
126    (UNSPEC_TAN_ONE              82)
127    (UNSPEC_TAN_TAN              83)
128    (UNSPEC_XTRACT_FRACT         84)
129    (UNSPEC_XTRACT_EXP           85)
130    (UNSPEC_FSCALE_FRACT         86)
131    (UNSPEC_FSCALE_EXP           87)
132    (UNSPEC_FPREM_F              88)
133    (UNSPEC_FPREM_U              89)
134    (UNSPEC_FPREM1_F             90)
135    (UNSPEC_FPREM1_U             91)
136
137    ; x87 Rounding
138    (UNSPEC_FRNDINT_FLOOR        96)
139    (UNSPEC_FRNDINT_CEIL         97)
140    (UNSPEC_FRNDINT_TRUNC        98)
141    (UNSPEC_FRNDINT_MASK_PM      99)
142
143    ; REP instruction
144    (UNSPEC_REP                  75)
145
146    (UNSPEC_EH_RETURN            76)
147   ])
148
149 (define_constants
150   [(UNSPECV_BLOCKAGE            0)
151    (UNSPECV_STACK_PROBE         10)
152    (UNSPECV_EMMS                31)
153    (UNSPECV_LDMXCSR             37)
154    (UNSPECV_STMXCSR             40)
155    (UNSPECV_FEMMS               46)
156    (UNSPECV_CLFLUSH             57)
157    (UNSPECV_ALIGN               68)
158    (UNSPECV_MONITOR             69)
159    (UNSPECV_MWAIT               70)
160   ])
161
162 ;; Registers by name.
163 (define_constants
164   [(BP_REG                       6)
165    (SP_REG                       7)
166    (FLAGS_REG                   17)
167    (FPSR_REG                    18)
168    (DIRFLAG_REG                 19)
169   ])
170
171 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
172 ;; from i386.c.
173
174 ;; In C guard expressions, put expressions which may be compile-time
175 ;; constants first.  This allows for better optimization.  For
176 ;; example, write "TARGET_64BIT && reload_completed", not
177 ;; "reload_completed && TARGET_64BIT".
178
179 \f
180 ;; Processor type.  This attribute must exactly match the processor_type
181 ;; enumeration in i386.h.
182 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
183   (const (symbol_ref "ix86_tune")))
184
185 ;; A basic instruction type.  Refinements due to arguments to be
186 ;; provided in other attributes.
187 (define_attr "type"
188   "other,multi,
189    alu,alu1,negnot,imov,imovx,lea,
190    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
191    icmp,test,ibr,setcc,icmov,
192    push,pop,call,callv,leave,
193    str,cld,
194    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint,
195    sselog,sseiadd,sseishft,sseimul,
196    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
197    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
198   (const_string "other"))
199
200 ;; Main data type used by the insn
201 (define_attr "mode"
202   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
203   (const_string "unknown"))
204
205 ;; The CPU unit operations uses.
206 (define_attr "unit" "integer,i387,sse,mmx,unknown"
207   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint")
208            (const_string "i387")
209          (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
210                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
211            (const_string "sse")
212          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
213            (const_string "mmx")
214          (eq_attr "type" "other")
215            (const_string "unknown")]
216          (const_string "integer")))
217
218 ;; The (bounding maximum) length of an instruction immediate.
219 (define_attr "length_immediate" ""
220   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
221            (const_int 0)
222          (eq_attr "unit" "i387,sse,mmx")
223            (const_int 0)
224          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
225                           imul,icmp,push,pop")
226            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
227          (eq_attr "type" "imov,test")
228            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
229          (eq_attr "type" "call")
230            (if_then_else (match_operand 0 "constant_call_address_operand" "")
231              (const_int 4)
232              (const_int 0))
233          (eq_attr "type" "callv")
234            (if_then_else (match_operand 1 "constant_call_address_operand" "")
235              (const_int 4)
236              (const_int 0))
237          ;; We don't know the size before shorten_branches.  Expect
238          ;; the instruction to fit for better scheduling.
239          (eq_attr "type" "ibr")
240            (const_int 1)
241          ]
242          (symbol_ref "/* Update immediate_length and other attributes! */
243                       abort(),1")))
244
245 ;; The (bounding maximum) length of an instruction address.
246 (define_attr "length_address" ""
247   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
248            (const_int 0)
249          (and (eq_attr "type" "call")
250               (match_operand 0 "constant_call_address_operand" ""))
251              (const_int 0)
252          (and (eq_attr "type" "callv")
253               (match_operand 1 "constant_call_address_operand" ""))
254              (const_int 0)
255          ]
256          (symbol_ref "ix86_attr_length_address_default (insn)")))
257
258 ;; Set when length prefix is used.
259 (define_attr "prefix_data16" ""
260   (if_then_else (ior (eq_attr "mode" "HI")
261                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
262     (const_int 1)
263     (const_int 0)))
264
265 ;; Set when string REP prefix is used.
266 (define_attr "prefix_rep" "" 
267   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
268     (const_int 1)
269     (const_int 0)))
270
271 ;; Set when 0f opcode prefix is used.
272 (define_attr "prefix_0f" ""
273   (if_then_else 
274     (ior (eq_attr "type" "imovx,setcc,icmov")
275          (eq_attr "unit" "sse,mmx"))
276     (const_int 1)
277     (const_int 0)))
278
279 ;; Set when REX opcode prefix is used.
280 (define_attr "prefix_rex" ""
281   (cond [(and (eq_attr "mode" "DI")
282               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
283            (const_int 1)
284          (and (eq_attr "mode" "QI")
285               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
286                   (const_int 0)))
287            (const_int 1)
288          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
289              (const_int 0))
290            (const_int 1)
291         ]
292         (const_int 0)))
293
294 ;; Set when modrm byte is used.
295 (define_attr "modrm" ""
296   (cond [(eq_attr "type" "str,cld,leave")
297            (const_int 0)
298          (eq_attr "unit" "i387")
299            (const_int 0)
300          (and (eq_attr "type" "incdec")
301               (ior (match_operand:SI 1 "register_operand" "")
302                    (match_operand:HI 1 "register_operand" "")))
303            (const_int 0)
304          (and (eq_attr "type" "push")
305               (not (match_operand 1 "memory_operand" "")))
306            (const_int 0)
307          (and (eq_attr "type" "pop")
308               (not (match_operand 0 "memory_operand" "")))
309            (const_int 0)
310          (and (eq_attr "type" "imov")
311               (and (match_operand 0 "register_operand" "")
312                    (match_operand 1 "immediate_operand" "")))
313            (const_int 0)
314          (and (eq_attr "type" "call")
315               (match_operand 0 "constant_call_address_operand" ""))
316              (const_int 0)
317          (and (eq_attr "type" "callv")
318               (match_operand 1 "constant_call_address_operand" ""))
319              (const_int 0)
320          ]
321          (const_int 1)))
322
323 ;; The (bounding maximum) length of an instruction in bytes.
324 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
325 ;; Later we may want to split them and compute proper length as for
326 ;; other insns.
327 (define_attr "length" ""
328   (cond [(eq_attr "type" "other,multi,fistp,frndint")
329            (const_int 16)
330          (eq_attr "type" "fcmp")
331            (const_int 4)
332          (eq_attr "unit" "i387")
333            (plus (const_int 2)
334                  (plus (attr "prefix_data16")
335                        (attr "length_address")))]
336          (plus (plus (attr "modrm")
337                      (plus (attr "prefix_0f")
338                            (plus (attr "prefix_rex")
339                                  (const_int 1))))
340                (plus (attr "prefix_rep")
341                      (plus (attr "prefix_data16")
342                            (plus (attr "length_immediate")
343                                  (attr "length_address")))))))
344
345 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
346 ;; `store' if there is a simple memory reference therein, or `unknown'
347 ;; if the instruction is complex.
348
349 (define_attr "memory" "none,load,store,both,unknown"
350   (cond [(eq_attr "type" "other,multi,str")
351            (const_string "unknown")
352          (eq_attr "type" "lea,fcmov,fpspc,cld")
353            (const_string "none")
354          (eq_attr "type" "fistp,leave")
355            (const_string "both")
356          (eq_attr "type" "frndint")
357            (const_string "load")
358          (eq_attr "type" "push")
359            (if_then_else (match_operand 1 "memory_operand" "")
360              (const_string "both")
361              (const_string "store"))
362          (eq_attr "type" "pop")
363            (if_then_else (match_operand 0 "memory_operand" "")
364              (const_string "both")
365              (const_string "load"))
366          (eq_attr "type" "setcc")
367            (if_then_else (match_operand 0 "memory_operand" "")
368              (const_string "store")
369              (const_string "none"))
370          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
371            (if_then_else (ior (match_operand 0 "memory_operand" "")
372                               (match_operand 1 "memory_operand" ""))
373              (const_string "load")
374              (const_string "none"))
375          (eq_attr "type" "ibr")
376            (if_then_else (match_operand 0 "memory_operand" "")
377              (const_string "load")
378              (const_string "none"))
379          (eq_attr "type" "call")
380            (if_then_else (match_operand 0 "constant_call_address_operand" "")
381              (const_string "none")
382              (const_string "load"))
383          (eq_attr "type" "callv")
384            (if_then_else (match_operand 1 "constant_call_address_operand" "")
385              (const_string "none")
386              (const_string "load"))
387          (and (eq_attr "type" "alu1,negnot,ishift1")
388               (match_operand 1 "memory_operand" ""))
389            (const_string "both")
390          (and (match_operand 0 "memory_operand" "")
391               (match_operand 1 "memory_operand" ""))
392            (const_string "both")
393          (match_operand 0 "memory_operand" "")
394            (const_string "store")
395          (match_operand 1 "memory_operand" "")
396            (const_string "load")
397          (and (eq_attr "type"
398                  "!alu1,negnot,ishift1,
399                    imov,imovx,icmp,test,
400                    fmov,fcmp,fsgn,
401                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
402                    mmx,mmxmov,mmxcmp,mmxcvt")
403               (match_operand 2 "memory_operand" ""))
404            (const_string "load")
405          (and (eq_attr "type" "icmov")
406               (match_operand 3 "memory_operand" ""))
407            (const_string "load")
408         ]
409         (const_string "none")))
410
411 ;; Indicates if an instruction has both an immediate and a displacement.
412
413 (define_attr "imm_disp" "false,true,unknown"
414   (cond [(eq_attr "type" "other,multi")
415            (const_string "unknown")
416          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
417               (and (match_operand 0 "memory_displacement_operand" "")
418                    (match_operand 1 "immediate_operand" "")))
419            (const_string "true")
420          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
421               (and (match_operand 0 "memory_displacement_operand" "")
422                    (match_operand 2 "immediate_operand" "")))
423            (const_string "true")
424         ]
425         (const_string "false")))
426
427 ;; Indicates if an FP operation has an integer source.
428
429 (define_attr "fp_int_src" "false,true"
430   (const_string "false"))
431
432 ;; Defines rounding mode of an FP operation.
433
434 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
435   (const_string "any"))
436
437 ;; Describe a user's asm statement.
438 (define_asm_attributes
439   [(set_attr "length" "128")
440    (set_attr "type" "multi")])
441 \f
442 ;; Scheduling descriptions
443
444 (include "pentium.md")
445 (include "ppro.md")
446 (include "k6.md")
447 (include "athlon.md")
448
449 \f
450 ;; Operand and operator predicates
451
452 (include "predicates.md")
453
454 \f
455 ;; Compare instructions.
456
457 ;; All compare insns have expanders that save the operands away without
458 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
459 ;; after the cmp) will actually emit the cmpM.
460
461 (define_expand "cmpdi"
462   [(set (reg:CC FLAGS_REG)
463         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
464                     (match_operand:DI 1 "x86_64_general_operand" "")))]
465   ""
466 {
467   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
468     operands[0] = force_reg (DImode, operands[0]);
469   ix86_compare_op0 = operands[0];
470   ix86_compare_op1 = operands[1];
471   DONE;
472 })
473
474 (define_expand "cmpsi"
475   [(set (reg:CC FLAGS_REG)
476         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
477                     (match_operand:SI 1 "general_operand" "")))]
478   ""
479 {
480   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
481     operands[0] = force_reg (SImode, operands[0]);
482   ix86_compare_op0 = operands[0];
483   ix86_compare_op1 = operands[1];
484   DONE;
485 })
486
487 (define_expand "cmphi"
488   [(set (reg:CC FLAGS_REG)
489         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
490                     (match_operand:HI 1 "general_operand" "")))]
491   ""
492 {
493   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494     operands[0] = force_reg (HImode, operands[0]);
495   ix86_compare_op0 = operands[0];
496   ix86_compare_op1 = operands[1];
497   DONE;
498 })
499
500 (define_expand "cmpqi"
501   [(set (reg:CC FLAGS_REG)
502         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
503                     (match_operand:QI 1 "general_operand" "")))]
504   "TARGET_QIMODE_MATH"
505 {
506   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
507     operands[0] = force_reg (QImode, operands[0]);
508   ix86_compare_op0 = operands[0];
509   ix86_compare_op1 = operands[1];
510   DONE;
511 })
512
513 (define_insn "cmpdi_ccno_1_rex64"
514   [(set (reg FLAGS_REG)
515         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
516                  (match_operand:DI 1 "const0_operand" "n,n")))]
517   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
518   "@
519    test{q}\t{%0, %0|%0, %0}
520    cmp{q}\t{%1, %0|%0, %1}"
521   [(set_attr "type" "test,icmp")
522    (set_attr "length_immediate" "0,1")
523    (set_attr "mode" "DI")])
524
525 (define_insn "*cmpdi_minus_1_rex64"
526   [(set (reg FLAGS_REG)
527         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
528                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
529                  (const_int 0)))]
530   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
531   "cmp{q}\t{%1, %0|%0, %1}"
532   [(set_attr "type" "icmp")
533    (set_attr "mode" "DI")])
534
535 (define_expand "cmpdi_1_rex64"
536   [(set (reg:CC FLAGS_REG)
537         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
538                     (match_operand:DI 1 "general_operand" "")))]
539   "TARGET_64BIT"
540   "")
541
542 (define_insn "cmpdi_1_insn_rex64"
543   [(set (reg FLAGS_REG)
544         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
545                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
546   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
547   "cmp{q}\t{%1, %0|%0, %1}"
548   [(set_attr "type" "icmp")
549    (set_attr "mode" "DI")])
550
551
552 (define_insn "*cmpsi_ccno_1"
553   [(set (reg FLAGS_REG)
554         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
555                  (match_operand:SI 1 "const0_operand" "n,n")))]
556   "ix86_match_ccmode (insn, CCNOmode)"
557   "@
558    test{l}\t{%0, %0|%0, %0}
559    cmp{l}\t{%1, %0|%0, %1}"
560   [(set_attr "type" "test,icmp")
561    (set_attr "length_immediate" "0,1")
562    (set_attr "mode" "SI")])
563
564 (define_insn "*cmpsi_minus_1"
565   [(set (reg FLAGS_REG)
566         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
567                            (match_operand:SI 1 "general_operand" "ri,mr"))
568                  (const_int 0)))]
569   "ix86_match_ccmode (insn, CCGOCmode)"
570   "cmp{l}\t{%1, %0|%0, %1}"
571   [(set_attr "type" "icmp")
572    (set_attr "mode" "SI")])
573
574 (define_expand "cmpsi_1"
575   [(set (reg:CC FLAGS_REG)
576         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
577                     (match_operand:SI 1 "general_operand" "ri,mr")))]
578   ""
579   "")
580
581 (define_insn "*cmpsi_1_insn"
582   [(set (reg FLAGS_REG)
583         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
584                  (match_operand:SI 1 "general_operand" "ri,mr")))]
585   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
586     && ix86_match_ccmode (insn, CCmode)"
587   "cmp{l}\t{%1, %0|%0, %1}"
588   [(set_attr "type" "icmp")
589    (set_attr "mode" "SI")])
590
591 (define_insn "*cmphi_ccno_1"
592   [(set (reg FLAGS_REG)
593         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
594                  (match_operand:HI 1 "const0_operand" "n,n")))]
595   "ix86_match_ccmode (insn, CCNOmode)"
596   "@
597    test{w}\t{%0, %0|%0, %0}
598    cmp{w}\t{%1, %0|%0, %1}"
599   [(set_attr "type" "test,icmp")
600    (set_attr "length_immediate" "0,1")
601    (set_attr "mode" "HI")])
602
603 (define_insn "*cmphi_minus_1"
604   [(set (reg FLAGS_REG)
605         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
606                            (match_operand:HI 1 "general_operand" "ri,mr"))
607                  (const_int 0)))]
608   "ix86_match_ccmode (insn, CCGOCmode)"
609   "cmp{w}\t{%1, %0|%0, %1}"
610   [(set_attr "type" "icmp")
611    (set_attr "mode" "HI")])
612
613 (define_insn "*cmphi_1"
614   [(set (reg FLAGS_REG)
615         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
616                  (match_operand:HI 1 "general_operand" "ri,mr")))]
617   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
618    && ix86_match_ccmode (insn, CCmode)"
619   "cmp{w}\t{%1, %0|%0, %1}"
620   [(set_attr "type" "icmp")
621    (set_attr "mode" "HI")])
622
623 (define_insn "*cmpqi_ccno_1"
624   [(set (reg FLAGS_REG)
625         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
626                  (match_operand:QI 1 "const0_operand" "n,n")))]
627   "ix86_match_ccmode (insn, CCNOmode)"
628   "@
629    test{b}\t{%0, %0|%0, %0}
630    cmp{b}\t{$0, %0|%0, 0}"
631   [(set_attr "type" "test,icmp")
632    (set_attr "length_immediate" "0,1")
633    (set_attr "mode" "QI")])
634
635 (define_insn "*cmpqi_1"
636   [(set (reg FLAGS_REG)
637         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
638                  (match_operand:QI 1 "general_operand" "qi,mq")))]
639   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
640     && ix86_match_ccmode (insn, CCmode)"
641   "cmp{b}\t{%1, %0|%0, %1}"
642   [(set_attr "type" "icmp")
643    (set_attr "mode" "QI")])
644
645 (define_insn "*cmpqi_minus_1"
646   [(set (reg FLAGS_REG)
647         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
648                            (match_operand:QI 1 "general_operand" "qi,mq"))
649                  (const_int 0)))]
650   "ix86_match_ccmode (insn, CCGOCmode)"
651   "cmp{b}\t{%1, %0|%0, %1}"
652   [(set_attr "type" "icmp")
653    (set_attr "mode" "QI")])
654
655 (define_insn "*cmpqi_ext_1"
656   [(set (reg FLAGS_REG)
657         (compare
658           (match_operand:QI 0 "general_operand" "Qm")
659           (subreg:QI
660             (zero_extract:SI
661               (match_operand 1 "ext_register_operand" "Q")
662               (const_int 8)
663               (const_int 8)) 0)))]
664   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
665   "cmp{b}\t{%h1, %0|%0, %h1}"
666   [(set_attr "type" "icmp")
667    (set_attr "mode" "QI")])
668
669 (define_insn "*cmpqi_ext_1_rex64"
670   [(set (reg FLAGS_REG)
671         (compare
672           (match_operand:QI 0 "register_operand" "Q")
673           (subreg:QI
674             (zero_extract:SI
675               (match_operand 1 "ext_register_operand" "Q")
676               (const_int 8)
677               (const_int 8)) 0)))]
678   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
679   "cmp{b}\t{%h1, %0|%0, %h1}"
680   [(set_attr "type" "icmp")
681    (set_attr "mode" "QI")])
682
683 (define_insn "*cmpqi_ext_2"
684   [(set (reg FLAGS_REG)
685         (compare
686           (subreg:QI
687             (zero_extract:SI
688               (match_operand 0 "ext_register_operand" "Q")
689               (const_int 8)
690               (const_int 8)) 0)
691           (match_operand:QI 1 "const0_operand" "n")))]
692   "ix86_match_ccmode (insn, CCNOmode)"
693   "test{b}\t%h0, %h0"
694   [(set_attr "type" "test")
695    (set_attr "length_immediate" "0")
696    (set_attr "mode" "QI")])
697
698 (define_expand "cmpqi_ext_3"
699   [(set (reg:CC FLAGS_REG)
700         (compare:CC
701           (subreg:QI
702             (zero_extract:SI
703               (match_operand 0 "ext_register_operand" "")
704               (const_int 8)
705               (const_int 8)) 0)
706           (match_operand:QI 1 "general_operand" "")))]
707   ""
708   "")
709
710 (define_insn "cmpqi_ext_3_insn"
711   [(set (reg FLAGS_REG)
712         (compare
713           (subreg:QI
714             (zero_extract:SI
715               (match_operand 0 "ext_register_operand" "Q")
716               (const_int 8)
717               (const_int 8)) 0)
718           (match_operand:QI 1 "general_operand" "Qmn")))]
719   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720   "cmp{b}\t{%1, %h0|%h0, %1}"
721   [(set_attr "type" "icmp")
722    (set_attr "mode" "QI")])
723
724 (define_insn "cmpqi_ext_3_insn_rex64"
725   [(set (reg FLAGS_REG)
726         (compare
727           (subreg:QI
728             (zero_extract:SI
729               (match_operand 0 "ext_register_operand" "Q")
730               (const_int 8)
731               (const_int 8)) 0)
732           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
733   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
734   "cmp{b}\t{%1, %h0|%h0, %1}"
735   [(set_attr "type" "icmp")
736    (set_attr "mode" "QI")])
737
738 (define_insn "*cmpqi_ext_4"
739   [(set (reg FLAGS_REG)
740         (compare
741           (subreg:QI
742             (zero_extract:SI
743               (match_operand 0 "ext_register_operand" "Q")
744               (const_int 8)
745               (const_int 8)) 0)
746           (subreg:QI
747             (zero_extract:SI
748               (match_operand 1 "ext_register_operand" "Q")
749               (const_int 8)
750               (const_int 8)) 0)))]
751   "ix86_match_ccmode (insn, CCmode)"
752   "cmp{b}\t{%h1, %h0|%h0, %h1}"
753   [(set_attr "type" "icmp")
754    (set_attr "mode" "QI")])
755
756 ;; These implement float point compares.
757 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
758 ;; which would allow mix and match FP modes on the compares.  Which is what
759 ;; the old patterns did, but with many more of them.
760
761 (define_expand "cmpxf"
762   [(set (reg:CC FLAGS_REG)
763         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
764                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
765   "TARGET_80387"
766 {
767   ix86_compare_op0 = operands[0];
768   ix86_compare_op1 = operands[1];
769   DONE;
770 })
771
772 (define_expand "cmpdf"
773   [(set (reg:CC FLAGS_REG)
774         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
775                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
776   "TARGET_80387 || TARGET_SSE2"
777 {
778   ix86_compare_op0 = operands[0];
779   ix86_compare_op1 = operands[1];
780   DONE;
781 })
782
783 (define_expand "cmpsf"
784   [(set (reg:CC FLAGS_REG)
785         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
786                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
787   "TARGET_80387 || TARGET_SSE"
788 {
789   ix86_compare_op0 = operands[0];
790   ix86_compare_op1 = operands[1];
791   DONE;
792 })
793
794 ;; FP compares, step 1:
795 ;; Set the FP condition codes.
796 ;;
797 ;; CCFPmode     compare with exceptions
798 ;; CCFPUmode    compare with no exceptions
799
800 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
801 ;; used to manage the reg stack popping would not be preserved.
802
803 (define_insn "*cmpfp_0_sf"
804   [(set (match_operand:HI 0 "register_operand" "=a")
805         (unspec:HI
806           [(compare:CCFP
807              (match_operand:SF 1 "register_operand" "f")
808              (match_operand:SF 2 "const0_operand" "X"))]
809         UNSPEC_FNSTSW))]
810   "TARGET_80387"
811   "* return output_fp_compare (insn, operands, 0, 0);"
812   [(set_attr "type" "multi")
813    (set_attr "mode" "SF")])
814
815 (define_insn "*cmpfp_0_df"
816   [(set (match_operand:HI 0 "register_operand" "=a")
817         (unspec:HI
818           [(compare:CCFP
819              (match_operand:DF 1 "register_operand" "f")
820              (match_operand:DF 2 "const0_operand" "X"))]
821         UNSPEC_FNSTSW))]
822   "TARGET_80387"
823   "* return output_fp_compare (insn, operands, 0, 0);"
824   [(set_attr "type" "multi")
825    (set_attr "mode" "DF")])
826
827 (define_insn "*cmpfp_0_xf"
828   [(set (match_operand:HI 0 "register_operand" "=a")
829         (unspec:HI
830           [(compare:CCFP
831              (match_operand:XF 1 "register_operand" "f")
832              (match_operand:XF 2 "const0_operand" "X"))]
833         UNSPEC_FNSTSW))]
834   "TARGET_80387"
835   "* return output_fp_compare (insn, operands, 0, 0);"
836   [(set_attr "type" "multi")
837    (set_attr "mode" "XF")])
838
839 (define_insn "*cmpfp_sf"
840   [(set (match_operand:HI 0 "register_operand" "=a")
841         (unspec:HI
842           [(compare:CCFP
843              (match_operand:SF 1 "register_operand" "f")
844              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
845           UNSPEC_FNSTSW))]
846   "TARGET_80387"
847   "* return output_fp_compare (insn, operands, 0, 0);"
848   [(set_attr "type" "multi")
849    (set_attr "mode" "SF")])
850
851 (define_insn "*cmpfp_df"
852   [(set (match_operand:HI 0 "register_operand" "=a")
853         (unspec:HI
854           [(compare:CCFP
855              (match_operand:DF 1 "register_operand" "f")
856              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
857           UNSPEC_FNSTSW))]
858   "TARGET_80387"
859   "* return output_fp_compare (insn, operands, 0, 0);"
860   [(set_attr "type" "multi")
861    (set_attr "mode" "DF")])
862
863 (define_insn "*cmpfp_xf"
864   [(set (match_operand:HI 0 "register_operand" "=a")
865         (unspec:HI
866           [(compare:CCFP
867              (match_operand:XF 1 "register_operand" "f")
868              (match_operand:XF 2 "register_operand" "f"))]
869           UNSPEC_FNSTSW))]
870   "TARGET_80387"
871   "* return output_fp_compare (insn, operands, 0, 0);"
872   [(set_attr "type" "multi")
873    (set_attr "mode" "XF")])
874
875 (define_insn "*cmpfp_u"
876   [(set (match_operand:HI 0 "register_operand" "=a")
877         (unspec:HI
878           [(compare:CCFPU
879              (match_operand 1 "register_operand" "f")
880              (match_operand 2 "register_operand" "f"))]
881           UNSPEC_FNSTSW))]
882   "TARGET_80387
883    && FLOAT_MODE_P (GET_MODE (operands[1]))
884    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
885   "* return output_fp_compare (insn, operands, 0, 1);"
886   [(set_attr "type" "multi")
887    (set (attr "mode")
888      (cond [(match_operand:SF 1 "" "")
889               (const_string "SF")
890             (match_operand:DF 1 "" "")
891               (const_string "DF")
892            ]
893            (const_string "XF")))])
894
895 (define_insn "*cmpfp_si"
896   [(set (match_operand:HI 0 "register_operand" "=a")
897         (unspec:HI
898           [(compare:CCFP
899              (match_operand 1 "register_operand" "f")
900              (match_operator 3 "float_operator"
901                [(match_operand:SI 2 "memory_operand" "m")]))]
902           UNSPEC_FNSTSW))]
903   "TARGET_80387 && TARGET_USE_FIOP
904    && FLOAT_MODE_P (GET_MODE (operands[1]))
905    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
906   "* return output_fp_compare (insn, operands, 0, 0);"
907   [(set_attr "type" "multi")
908    (set_attr "fp_int_src" "true")
909    (set_attr "mode" "SI")])
910
911 ;; FP compares, step 2
912 ;; Move the fpsw to ax.
913
914 (define_insn "x86_fnstsw_1"
915   [(set (match_operand:HI 0 "register_operand" "=a")
916         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
917   "TARGET_80387"
918   "fnstsw\t%0"
919   [(set_attr "length" "2")
920    (set_attr "mode" "SI")
921    (set_attr "unit" "i387")])
922
923 ;; FP compares, step 3
924 ;; Get ax into flags, general case.
925
926 (define_insn "x86_sahf_1"
927   [(set (reg:CC FLAGS_REG)
928         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
929   "!TARGET_64BIT"
930   "sahf"
931   [(set_attr "length" "1")
932    (set_attr "athlon_decode" "vector")
933    (set_attr "mode" "SI")])
934
935 ;; Pentium Pro can do steps 1 through 3 in one go.
936
937 (define_insn "*cmpfp_i"
938   [(set (reg:CCFP FLAGS_REG)
939         (compare:CCFP (match_operand 0 "register_operand" "f")
940                       (match_operand 1 "register_operand" "f")))]
941   "TARGET_80387 && TARGET_CMOVE
942    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
943    && FLOAT_MODE_P (GET_MODE (operands[0]))
944    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
945   "* return output_fp_compare (insn, operands, 1, 0);"
946   [(set_attr "type" "fcmp")
947    (set (attr "mode")
948      (cond [(match_operand:SF 1 "" "")
949               (const_string "SF")
950             (match_operand:DF 1 "" "")
951               (const_string "DF")
952            ]
953            (const_string "XF")))
954    (set_attr "athlon_decode" "vector")])
955
956 (define_insn "*cmpfp_i_sse"
957   [(set (reg:CCFP FLAGS_REG)
958         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
959                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
960   "TARGET_80387
961    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
962    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
963   "* return output_fp_compare (insn, operands, 1, 0);"
964   [(set_attr "type" "fcmp,ssecomi")
965    (set (attr "mode")
966      (if_then_else (match_operand:SF 1 "" "")
967         (const_string "SF")
968         (const_string "DF")))
969    (set_attr "athlon_decode" "vector")])
970
971 (define_insn "*cmpfp_i_sse_only"
972   [(set (reg:CCFP FLAGS_REG)
973         (compare:CCFP (match_operand 0 "register_operand" "x")
974                       (match_operand 1 "nonimmediate_operand" "xm")))]
975   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
976    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
977   "* return output_fp_compare (insn, operands, 1, 0);"
978   [(set_attr "type" "ssecomi")
979    (set (attr "mode")
980      (if_then_else (match_operand:SF 1 "" "")
981         (const_string "SF")
982         (const_string "DF")))
983    (set_attr "athlon_decode" "vector")])
984
985 (define_insn "*cmpfp_iu"
986   [(set (reg:CCFPU FLAGS_REG)
987         (compare:CCFPU (match_operand 0 "register_operand" "f")
988                        (match_operand 1 "register_operand" "f")))]
989   "TARGET_80387 && TARGET_CMOVE
990    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
991    && FLOAT_MODE_P (GET_MODE (operands[0]))
992    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
993   "* return output_fp_compare (insn, operands, 1, 1);"
994   [(set_attr "type" "fcmp")
995    (set (attr "mode")
996      (cond [(match_operand:SF 1 "" "")
997               (const_string "SF")
998             (match_operand:DF 1 "" "")
999               (const_string "DF")
1000            ]
1001            (const_string "XF")))
1002    (set_attr "athlon_decode" "vector")])
1003
1004 (define_insn "*cmpfp_iu_sse"
1005   [(set (reg:CCFPU FLAGS_REG)
1006         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1007                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1008   "TARGET_80387
1009    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1010    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1011   "* return output_fp_compare (insn, operands, 1, 1);"
1012   [(set_attr "type" "fcmp,ssecomi")
1013    (set (attr "mode")
1014      (if_then_else (match_operand:SF 1 "" "")
1015         (const_string "SF")
1016         (const_string "DF")))
1017    (set_attr "athlon_decode" "vector")])
1018
1019 (define_insn "*cmpfp_iu_sse_only"
1020   [(set (reg:CCFPU FLAGS_REG)
1021         (compare:CCFPU (match_operand 0 "register_operand" "x")
1022                        (match_operand 1 "nonimmediate_operand" "xm")))]
1023   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1024    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025   "* return output_fp_compare (insn, operands, 1, 1);"
1026   [(set_attr "type" "ssecomi")
1027    (set (attr "mode")
1028      (if_then_else (match_operand:SF 1 "" "")
1029         (const_string "SF")
1030         (const_string "DF")))
1031    (set_attr "athlon_decode" "vector")])
1032 \f
1033 ;; Move instructions.
1034
1035 ;; General case of fullword move.
1036
1037 (define_expand "movsi"
1038   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1039         (match_operand:SI 1 "general_operand" ""))]
1040   ""
1041   "ix86_expand_move (SImode, operands); DONE;")
1042
1043 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1044 ;; general_operand.
1045 ;;
1046 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1047 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1048 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1049 ;; targets without our curiosities, and it is just as easy to represent
1050 ;; this differently.
1051
1052 (define_insn "*pushsi2"
1053   [(set (match_operand:SI 0 "push_operand" "=<")
1054         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1055   "!TARGET_64BIT"
1056   "push{l}\t%1"
1057   [(set_attr "type" "push")
1058    (set_attr "mode" "SI")])
1059
1060 ;; For 64BIT abi we always round up to 8 bytes.
1061 (define_insn "*pushsi2_rex64"
1062   [(set (match_operand:SI 0 "push_operand" "=X")
1063         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1064   "TARGET_64BIT"
1065   "push{q}\t%q1"
1066   [(set_attr "type" "push")
1067    (set_attr "mode" "SI")])
1068
1069 (define_insn "*pushsi2_prologue"
1070   [(set (match_operand:SI 0 "push_operand" "=<")
1071         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1072    (clobber (mem:BLK (scratch)))]
1073   "!TARGET_64BIT"
1074   "push{l}\t%1"
1075   [(set_attr "type" "push")
1076    (set_attr "mode" "SI")])
1077
1078 (define_insn "*popsi1_epilogue"
1079   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1080         (mem:SI (reg:SI SP_REG)))
1081    (set (reg:SI SP_REG)
1082         (plus:SI (reg:SI SP_REG) (const_int 4)))
1083    (clobber (mem:BLK (scratch)))]
1084   "!TARGET_64BIT"
1085   "pop{l}\t%0"
1086   [(set_attr "type" "pop")
1087    (set_attr "mode" "SI")])
1088
1089 (define_insn "popsi1"
1090   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1091         (mem:SI (reg:SI SP_REG)))
1092    (set (reg:SI SP_REG)
1093         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1094   "!TARGET_64BIT"
1095   "pop{l}\t%0"
1096   [(set_attr "type" "pop")
1097    (set_attr "mode" "SI")])
1098
1099 (define_insn "*movsi_xor"
1100   [(set (match_operand:SI 0 "register_operand" "=r")
1101         (match_operand:SI 1 "const0_operand" "i"))
1102    (clobber (reg:CC FLAGS_REG))]
1103   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1104   "xor{l}\t{%0, %0|%0, %0}"
1105   [(set_attr "type" "alu1")
1106    (set_attr "mode" "SI")
1107    (set_attr "length_immediate" "0")])
1108  
1109 (define_insn "*movsi_or"
1110   [(set (match_operand:SI 0 "register_operand" "=r")
1111         (match_operand:SI 1 "immediate_operand" "i"))
1112    (clobber (reg:CC FLAGS_REG))]
1113   "reload_completed
1114    && operands[1] == constm1_rtx
1115    && (TARGET_PENTIUM || optimize_size)"
1116 {
1117   operands[1] = constm1_rtx;
1118   return "or{l}\t{%1, %0|%0, %1}";
1119 }
1120   [(set_attr "type" "alu1")
1121    (set_attr "mode" "SI")
1122    (set_attr "length_immediate" "1")])
1123
1124 (define_insn "*movsi_1"
1125   [(set (match_operand:SI 0 "nonimmediate_operand"
1126                         "=r  ,m  ,!*y,!rm,!*y,!*x,!rm,!*x")
1127         (match_operand:SI 1 "general_operand"
1128                         "rinm,rin,*y ,*y ,rm ,*x ,*x ,rm"))]
1129   "(TARGET_INTER_UNIT_MOVES || optimize_size)
1130    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1131 {
1132   switch (get_attr_type (insn))
1133     {
1134     case TYPE_SSEMOV:
1135       if (get_attr_mode (insn) == MODE_TI)
1136         return "movdqa\t{%1, %0|%0, %1}";
1137       return "movd\t{%1, %0|%0, %1}";
1138
1139     case TYPE_MMXMOV:
1140       if (get_attr_mode (insn) == MODE_DI)
1141         return "movq\t{%1, %0|%0, %1}";
1142       return "movd\t{%1, %0|%0, %1}";
1143
1144     case TYPE_LEA:
1145       return "lea{l}\t{%1, %0|%0, %1}";
1146
1147     default:
1148       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1149         abort();
1150       return "mov{l}\t{%1, %0|%0, %1}";
1151     }
1152 }
1153   [(set (attr "type")
1154      (cond [(eq_attr "alternative" "2,3,4")
1155               (const_string "mmxmov")
1156             (eq_attr "alternative" "5,6,7")
1157               (const_string "ssemov")
1158             (and (ne (symbol_ref "flag_pic") (const_int 0))
1159                  (match_operand:SI 1 "symbolic_operand" ""))
1160               (const_string "lea")
1161            ]
1162            (const_string "imov")))
1163    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1164
1165 (define_insn "*movsi_1_nointernunit"
1166   [(set (match_operand:SI 0 "nonimmediate_operand"
1167                         "=r  ,m  ,!*y,!m,!*y,!*x,!m,!*x")
1168         (match_operand:SI 1 "general_operand"
1169                         "rinm,rin,*y ,*y,m  ,*x ,*x,m"))]
1170   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1171    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1172 {
1173   switch (get_attr_type (insn))
1174     {
1175     case TYPE_SSEMOV:
1176       if (get_attr_mode (insn) == MODE_TI)
1177         return "movdqa\t{%1, %0|%0, %1}";
1178       return "movd\t{%1, %0|%0, %1}";
1179
1180     case TYPE_MMXMOV:
1181       if (get_attr_mode (insn) == MODE_DI)
1182         return "movq\t{%1, %0|%0, %1}";
1183       return "movd\t{%1, %0|%0, %1}";
1184
1185     case TYPE_LEA:
1186       return "lea{l}\t{%1, %0|%0, %1}";
1187
1188     default:
1189       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1190         abort();
1191       return "mov{l}\t{%1, %0|%0, %1}";
1192     }
1193 }
1194   [(set (attr "type")
1195      (cond [(eq_attr "alternative" "2,3,4")
1196               (const_string "mmxmov")
1197             (eq_attr "alternative" "5,6,7")
1198               (const_string "ssemov")
1199             (and (ne (symbol_ref "flag_pic") (const_int 0))
1200                  (match_operand:SI 1 "symbolic_operand" ""))
1201               (const_string "lea")
1202            ]
1203            (const_string "imov")))
1204    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1205
1206 ;; Stores and loads of ax to arbitrary constant address.
1207 ;; We fake an second form of instruction to force reload to load address
1208 ;; into register when rax is not available
1209 (define_insn "*movabssi_1_rex64"
1210   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1211         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1212   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1213   "@
1214    movabs{l}\t{%1, %P0|%P0, %1}
1215    mov{l}\t{%1, %a0|%a0, %1}"
1216   [(set_attr "type" "imov")
1217    (set_attr "modrm" "0,*")
1218    (set_attr "length_address" "8,0")
1219    (set_attr "length_immediate" "0,*")
1220    (set_attr "memory" "store")
1221    (set_attr "mode" "SI")])
1222
1223 (define_insn "*movabssi_2_rex64"
1224   [(set (match_operand:SI 0 "register_operand" "=a,r")
1225         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1226   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1227   "@
1228    movabs{l}\t{%P1, %0|%0, %P1}
1229    mov{l}\t{%a1, %0|%0, %a1}"
1230   [(set_attr "type" "imov")
1231    (set_attr "modrm" "0,*")
1232    (set_attr "length_address" "8,0")
1233    (set_attr "length_immediate" "0")
1234    (set_attr "memory" "load")
1235    (set_attr "mode" "SI")])
1236
1237 (define_insn "*swapsi"
1238   [(set (match_operand:SI 0 "register_operand" "+r")
1239         (match_operand:SI 1 "register_operand" "+r"))
1240    (set (match_dup 1)
1241         (match_dup 0))]
1242   ""
1243   "xchg{l}\t%1, %0"
1244   [(set_attr "type" "imov")
1245    (set_attr "mode" "SI")
1246    (set_attr "pent_pair" "np")
1247    (set_attr "athlon_decode" "vector")])
1248
1249 (define_expand "movhi"
1250   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1251         (match_operand:HI 1 "general_operand" ""))]
1252   ""
1253   "ix86_expand_move (HImode, operands); DONE;")
1254
1255 (define_insn "*pushhi2"
1256   [(set (match_operand:HI 0 "push_operand" "=<,<")
1257         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1258   "!TARGET_64BIT"
1259   "@
1260    push{w}\t{|WORD PTR }%1
1261    push{w}\t%1"
1262   [(set_attr "type" "push")
1263    (set_attr "mode" "HI")])
1264
1265 ;; For 64BIT abi we always round up to 8 bytes.
1266 (define_insn "*pushhi2_rex64"
1267   [(set (match_operand:HI 0 "push_operand" "=X")
1268         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1269   "TARGET_64BIT"
1270   "push{q}\t%q1"
1271   [(set_attr "type" "push")
1272    (set_attr "mode" "QI")])
1273
1274 (define_insn "*movhi_1"
1275   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1276         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1277   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1278 {
1279   switch (get_attr_type (insn))
1280     {
1281     case TYPE_IMOVX:
1282       /* movzwl is faster than movw on p2 due to partial word stalls,
1283          though not as fast as an aligned movl.  */
1284       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1285     default:
1286       if (get_attr_mode (insn) == MODE_SI)
1287         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1288       else
1289         return "mov{w}\t{%1, %0|%0, %1}";
1290     }
1291 }
1292   [(set (attr "type")
1293      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1294               (const_string "imov")
1295             (and (eq_attr "alternative" "0")
1296                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1297                           (const_int 0))
1298                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1299                           (const_int 0))))
1300               (const_string "imov")
1301             (and (eq_attr "alternative" "1,2")
1302                  (match_operand:HI 1 "aligned_operand" ""))
1303               (const_string "imov")
1304             (and (ne (symbol_ref "TARGET_MOVX")
1305                      (const_int 0))
1306                  (eq_attr "alternative" "0,2"))
1307               (const_string "imovx")
1308            ]
1309            (const_string "imov")))
1310     (set (attr "mode")
1311       (cond [(eq_attr "type" "imovx")
1312                (const_string "SI")
1313              (and (eq_attr "alternative" "1,2")
1314                   (match_operand:HI 1 "aligned_operand" ""))
1315                (const_string "SI")
1316              (and (eq_attr "alternative" "0")
1317                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1318                            (const_int 0))
1319                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1320                            (const_int 0))))
1321                (const_string "SI")
1322             ]
1323             (const_string "HI")))])
1324
1325 ;; Stores and loads of ax to arbitrary constant address.
1326 ;; We fake an second form of instruction to force reload to load address
1327 ;; into register when rax is not available
1328 (define_insn "*movabshi_1_rex64"
1329   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1330         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1331   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1332   "@
1333    movabs{w}\t{%1, %P0|%P0, %1}
1334    mov{w}\t{%1, %a0|%a0, %1}"
1335   [(set_attr "type" "imov")
1336    (set_attr "modrm" "0,*")
1337    (set_attr "length_address" "8,0")
1338    (set_attr "length_immediate" "0,*")
1339    (set_attr "memory" "store")
1340    (set_attr "mode" "HI")])
1341
1342 (define_insn "*movabshi_2_rex64"
1343   [(set (match_operand:HI 0 "register_operand" "=a,r")
1344         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1345   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1346   "@
1347    movabs{w}\t{%P1, %0|%0, %P1}
1348    mov{w}\t{%a1, %0|%0, %a1}"
1349   [(set_attr "type" "imov")
1350    (set_attr "modrm" "0,*")
1351    (set_attr "length_address" "8,0")
1352    (set_attr "length_immediate" "0")
1353    (set_attr "memory" "load")
1354    (set_attr "mode" "HI")])
1355
1356 (define_insn "*swaphi_1"
1357   [(set (match_operand:HI 0 "register_operand" "+r")
1358         (match_operand:HI 1 "register_operand" "+r"))
1359    (set (match_dup 1)
1360         (match_dup 0))]
1361   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1362   "xchg{l}\t%k1, %k0"
1363   [(set_attr "type" "imov")
1364    (set_attr "mode" "SI")
1365    (set_attr "pent_pair" "np")
1366    (set_attr "athlon_decode" "vector")])
1367
1368 (define_insn "*swaphi_2"
1369   [(set (match_operand:HI 0 "register_operand" "+r")
1370         (match_operand:HI 1 "register_operand" "+r"))
1371    (set (match_dup 1)
1372         (match_dup 0))]
1373   "TARGET_PARTIAL_REG_STALL"
1374   "xchg{w}\t%1, %0"
1375   [(set_attr "type" "imov")
1376    (set_attr "mode" "HI")
1377    (set_attr "pent_pair" "np")
1378    (set_attr "athlon_decode" "vector")])
1379
1380 (define_expand "movstricthi"
1381   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1382         (match_operand:HI 1 "general_operand" ""))]
1383   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1384 {
1385   /* Don't generate memory->memory moves, go through a register */
1386   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1387     operands[1] = force_reg (HImode, operands[1]);
1388 })
1389
1390 (define_insn "*movstricthi_1"
1391   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1392         (match_operand:HI 1 "general_operand" "rn,m"))]
1393   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1394    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1395   "mov{w}\t{%1, %0|%0, %1}"
1396   [(set_attr "type" "imov")
1397    (set_attr "mode" "HI")])
1398
1399 (define_insn "*movstricthi_xor"
1400   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1401         (match_operand:HI 1 "const0_operand" "i"))
1402    (clobber (reg:CC FLAGS_REG))]
1403   "reload_completed
1404    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1405   "xor{w}\t{%0, %0|%0, %0}"
1406   [(set_attr "type" "alu1")
1407    (set_attr "mode" "HI")
1408    (set_attr "length_immediate" "0")])
1409
1410 (define_expand "movqi"
1411   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1412         (match_operand:QI 1 "general_operand" ""))]
1413   ""
1414   "ix86_expand_move (QImode, operands); DONE;")
1415
1416 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1417 ;; "push a byte".  But actually we use pushw, which has the effect
1418 ;; of rounding the amount pushed up to a halfword.
1419
1420 (define_insn "*pushqi2"
1421   [(set (match_operand:QI 0 "push_operand" "=X,X")
1422         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1423   "!TARGET_64BIT"
1424   "@
1425    push{w}\t{|word ptr }%1
1426    push{w}\t%w1"
1427   [(set_attr "type" "push")
1428    (set_attr "mode" "HI")])
1429
1430 ;; For 64BIT abi we always round up to 8 bytes.
1431 (define_insn "*pushqi2_rex64"
1432   [(set (match_operand:QI 0 "push_operand" "=X")
1433         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1434   "TARGET_64BIT"
1435   "push{q}\t%q1"
1436   [(set_attr "type" "push")
1437    (set_attr "mode" "QI")])
1438
1439 ;; Situation is quite tricky about when to choose full sized (SImode) move
1440 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1441 ;; partial register dependency machines (such as AMD Athlon), where QImode
1442 ;; moves issue extra dependency and for partial register stalls machines
1443 ;; that don't use QImode patterns (and QImode move cause stall on the next
1444 ;; instruction).
1445 ;;
1446 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1447 ;; register stall machines with, where we use QImode instructions, since
1448 ;; partial register stall can be caused there.  Then we use movzx.
1449 (define_insn "*movqi_1"
1450   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1451         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1452   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1453 {
1454   switch (get_attr_type (insn))
1455     {
1456     case TYPE_IMOVX:
1457       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1458         abort ();
1459       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1460     default:
1461       if (get_attr_mode (insn) == MODE_SI)
1462         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1463       else
1464         return "mov{b}\t{%1, %0|%0, %1}";
1465     }
1466 }
1467   [(set (attr "type")
1468      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1469               (const_string "imov")
1470             (and (eq_attr "alternative" "3")
1471                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1472                           (const_int 0))
1473                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1474                           (const_int 0))))
1475               (const_string "imov")
1476             (eq_attr "alternative" "3,5")
1477               (const_string "imovx")
1478             (and (ne (symbol_ref "TARGET_MOVX")
1479                      (const_int 0))
1480                  (eq_attr "alternative" "2"))
1481               (const_string "imovx")
1482            ]
1483            (const_string "imov")))
1484    (set (attr "mode")
1485       (cond [(eq_attr "alternative" "3,4,5")
1486                (const_string "SI")
1487              (eq_attr "alternative" "6")
1488                (const_string "QI")
1489              (eq_attr "type" "imovx")
1490                (const_string "SI")
1491              (and (eq_attr "type" "imov")
1492                   (and (eq_attr "alternative" "0,1,2")
1493                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1494                            (const_int 0))))
1495                (const_string "SI")
1496              ;; Avoid partial register stalls when not using QImode arithmetic
1497              (and (eq_attr "type" "imov")
1498                   (and (eq_attr "alternative" "0,1,2")
1499                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1500                                 (const_int 0))
1501                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1502                                 (const_int 0)))))
1503                (const_string "SI")
1504            ]
1505            (const_string "QI")))])
1506
1507 (define_expand "reload_outqi"
1508   [(parallel [(match_operand:QI 0 "" "=m")
1509               (match_operand:QI 1 "register_operand" "r")
1510               (match_operand:QI 2 "register_operand" "=&q")])]
1511   ""
1512 {
1513   rtx op0, op1, op2;
1514   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1515
1516   if (reg_overlap_mentioned_p (op2, op0))
1517     abort ();
1518   if (! q_regs_operand (op1, QImode))
1519     {
1520       emit_insn (gen_movqi (op2, op1));
1521       op1 = op2;
1522     }
1523   emit_insn (gen_movqi (op0, op1));
1524   DONE;
1525 })
1526
1527 (define_insn "*swapqi_1"
1528   [(set (match_operand:QI 0 "register_operand" "+r")
1529         (match_operand:QI 1 "register_operand" "+r"))
1530    (set (match_dup 1)
1531         (match_dup 0))]
1532   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1533   "xchg{l}\t%k1, %k0"
1534   [(set_attr "type" "imov")
1535    (set_attr "mode" "SI")
1536    (set_attr "pent_pair" "np")
1537    (set_attr "athlon_decode" "vector")])
1538
1539 (define_insn "*swapqi_2"
1540   [(set (match_operand:QI 0 "register_operand" "+q")
1541         (match_operand:QI 1 "register_operand" "+q"))
1542    (set (match_dup 1)
1543         (match_dup 0))]
1544   "TARGET_PARTIAL_REG_STALL"
1545   "xchg{b}\t%1, %0"
1546   [(set_attr "type" "imov")
1547    (set_attr "mode" "QI")
1548    (set_attr "pent_pair" "np")
1549    (set_attr "athlon_decode" "vector")])
1550
1551 (define_expand "movstrictqi"
1552   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1553         (match_operand:QI 1 "general_operand" ""))]
1554   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1555 {
1556   /* Don't generate memory->memory moves, go through a register.  */
1557   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1558     operands[1] = force_reg (QImode, operands[1]);
1559 })
1560
1561 (define_insn "*movstrictqi_1"
1562   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1563         (match_operand:QI 1 "general_operand" "*qn,m"))]
1564   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1565    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1566   "mov{b}\t{%1, %0|%0, %1}"
1567   [(set_attr "type" "imov")
1568    (set_attr "mode" "QI")])
1569
1570 (define_insn "*movstrictqi_xor"
1571   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1572         (match_operand:QI 1 "const0_operand" "i"))
1573    (clobber (reg:CC FLAGS_REG))]
1574   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1575   "xor{b}\t{%0, %0|%0, %0}"
1576   [(set_attr "type" "alu1")
1577    (set_attr "mode" "QI")
1578    (set_attr "length_immediate" "0")])
1579
1580 (define_insn "*movsi_extv_1"
1581   [(set (match_operand:SI 0 "register_operand" "=R")
1582         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1583                          (const_int 8)
1584                          (const_int 8)))]
1585   ""
1586   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1587   [(set_attr "type" "imovx")
1588    (set_attr "mode" "SI")])
1589
1590 (define_insn "*movhi_extv_1"
1591   [(set (match_operand:HI 0 "register_operand" "=R")
1592         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1593                          (const_int 8)
1594                          (const_int 8)))]
1595   ""
1596   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1597   [(set_attr "type" "imovx")
1598    (set_attr "mode" "SI")])
1599
1600 (define_insn "*movqi_extv_1"
1601   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1602         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1603                          (const_int 8)
1604                          (const_int 8)))]
1605   "!TARGET_64BIT"
1606 {
1607   switch (get_attr_type (insn))
1608     {
1609     case TYPE_IMOVX:
1610       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1611     default:
1612       return "mov{b}\t{%h1, %0|%0, %h1}";
1613     }
1614 }
1615   [(set (attr "type")
1616      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1617                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1618                              (ne (symbol_ref "TARGET_MOVX")
1619                                  (const_int 0))))
1620         (const_string "imovx")
1621         (const_string "imov")))
1622    (set (attr "mode")
1623      (if_then_else (eq_attr "type" "imovx")
1624         (const_string "SI")
1625         (const_string "QI")))])
1626
1627 (define_insn "*movqi_extv_1_rex64"
1628   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1629         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1630                          (const_int 8)
1631                          (const_int 8)))]
1632   "TARGET_64BIT"
1633 {
1634   switch (get_attr_type (insn))
1635     {
1636     case TYPE_IMOVX:
1637       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1638     default:
1639       return "mov{b}\t{%h1, %0|%0, %h1}";
1640     }
1641 }
1642   [(set (attr "type")
1643      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1644                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1645                              (ne (symbol_ref "TARGET_MOVX")
1646                                  (const_int 0))))
1647         (const_string "imovx")
1648         (const_string "imov")))
1649    (set (attr "mode")
1650      (if_then_else (eq_attr "type" "imovx")
1651         (const_string "SI")
1652         (const_string "QI")))])
1653
1654 ;; Stores and loads of ax to arbitrary constant address.
1655 ;; We fake an second form of instruction to force reload to load address
1656 ;; into register when rax is not available
1657 (define_insn "*movabsqi_1_rex64"
1658   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1659         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1660   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1661   "@
1662    movabs{b}\t{%1, %P0|%P0, %1}
1663    mov{b}\t{%1, %a0|%a0, %1}"
1664   [(set_attr "type" "imov")
1665    (set_attr "modrm" "0,*")
1666    (set_attr "length_address" "8,0")
1667    (set_attr "length_immediate" "0,*")
1668    (set_attr "memory" "store")
1669    (set_attr "mode" "QI")])
1670
1671 (define_insn "*movabsqi_2_rex64"
1672   [(set (match_operand:QI 0 "register_operand" "=a,r")
1673         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1674   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1675   "@
1676    movabs{b}\t{%P1, %0|%0, %P1}
1677    mov{b}\t{%a1, %0|%0, %a1}"
1678   [(set_attr "type" "imov")
1679    (set_attr "modrm" "0,*")
1680    (set_attr "length_address" "8,0")
1681    (set_attr "length_immediate" "0")
1682    (set_attr "memory" "load")
1683    (set_attr "mode" "QI")])
1684
1685 (define_insn "*movsi_extzv_1"
1686   [(set (match_operand:SI 0 "register_operand" "=R")
1687         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1688                          (const_int 8)
1689                          (const_int 8)))]
1690   ""
1691   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1692   [(set_attr "type" "imovx")
1693    (set_attr "mode" "SI")])
1694
1695 (define_insn "*movqi_extzv_2"
1696   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1697         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1698                                     (const_int 8)
1699                                     (const_int 8)) 0))]
1700   "!TARGET_64BIT"
1701 {
1702   switch (get_attr_type (insn))
1703     {
1704     case TYPE_IMOVX:
1705       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1706     default:
1707       return "mov{b}\t{%h1, %0|%0, %h1}";
1708     }
1709 }
1710   [(set (attr "type")
1711      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1712                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1713                              (ne (symbol_ref "TARGET_MOVX")
1714                                  (const_int 0))))
1715         (const_string "imovx")
1716         (const_string "imov")))
1717    (set (attr "mode")
1718      (if_then_else (eq_attr "type" "imovx")
1719         (const_string "SI")
1720         (const_string "QI")))])
1721
1722 (define_insn "*movqi_extzv_2_rex64"
1723   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1724         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1725                                     (const_int 8)
1726                                     (const_int 8)) 0))]
1727   "TARGET_64BIT"
1728 {
1729   switch (get_attr_type (insn))
1730     {
1731     case TYPE_IMOVX:
1732       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1733     default:
1734       return "mov{b}\t{%h1, %0|%0, %h1}";
1735     }
1736 }
1737   [(set (attr "type")
1738      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1739                         (ne (symbol_ref "TARGET_MOVX")
1740                             (const_int 0)))
1741         (const_string "imovx")
1742         (const_string "imov")))
1743    (set (attr "mode")
1744      (if_then_else (eq_attr "type" "imovx")
1745         (const_string "SI")
1746         (const_string "QI")))])
1747
1748 (define_insn "movsi_insv_1"
1749   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1750                          (const_int 8)
1751                          (const_int 8))
1752         (match_operand:SI 1 "general_operand" "Qmn"))]
1753   "!TARGET_64BIT"
1754   "mov{b}\t{%b1, %h0|%h0, %b1}"
1755   [(set_attr "type" "imov")
1756    (set_attr "mode" "QI")])
1757
1758 (define_insn "movdi_insv_1_rex64"
1759   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1760                          (const_int 8)
1761                          (const_int 8))
1762         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1763   "TARGET_64BIT"
1764   "mov{b}\t{%b1, %h0|%h0, %b1}"
1765   [(set_attr "type" "imov")
1766    (set_attr "mode" "QI")])
1767
1768 (define_insn "*movqi_insv_2"
1769   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1770                          (const_int 8)
1771                          (const_int 8))
1772         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1773                      (const_int 8)))]
1774   ""
1775   "mov{b}\t{%h1, %h0|%h0, %h1}"
1776   [(set_attr "type" "imov")
1777    (set_attr "mode" "QI")])
1778
1779 (define_expand "movdi"
1780   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1781         (match_operand:DI 1 "general_operand" ""))]
1782   ""
1783   "ix86_expand_move (DImode, operands); DONE;")
1784
1785 (define_insn "*pushdi"
1786   [(set (match_operand:DI 0 "push_operand" "=<")
1787         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1788   "!TARGET_64BIT"
1789   "#")
1790
1791 (define_insn "*pushdi2_rex64"
1792   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1793         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1794   "TARGET_64BIT"
1795   "@
1796    push{q}\t%1
1797    #"
1798   [(set_attr "type" "push,multi")
1799    (set_attr "mode" "DI")])
1800
1801 ;; Convert impossible pushes of immediate to existing instructions.
1802 ;; First try to get scratch register and go through it.  In case this
1803 ;; fails, push sign extended lower part first and then overwrite
1804 ;; upper part by 32bit move.
1805 (define_peephole2
1806   [(match_scratch:DI 2 "r")
1807    (set (match_operand:DI 0 "push_operand" "")
1808         (match_operand:DI 1 "immediate_operand" ""))]
1809   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1810    && !x86_64_immediate_operand (operands[1], DImode)"
1811   [(set (match_dup 2) (match_dup 1))
1812    (set (match_dup 0) (match_dup 2))]
1813   "")
1814
1815 ;; We need to define this as both peepholer and splitter for case
1816 ;; peephole2 pass is not run.
1817 ;; "&& 1" is needed to keep it from matching the previous pattern.
1818 (define_peephole2
1819   [(set (match_operand:DI 0 "push_operand" "")
1820         (match_operand:DI 1 "immediate_operand" ""))]
1821   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1822    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1823   [(set (match_dup 0) (match_dup 1))
1824    (set (match_dup 2) (match_dup 3))]
1825   "split_di (operands + 1, 1, operands + 2, operands + 3);
1826    operands[1] = gen_lowpart (DImode, operands[2]);
1827    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1828                                                     GEN_INT (4)));
1829   ")
1830
1831 (define_split
1832   [(set (match_operand:DI 0 "push_operand" "")
1833         (match_operand:DI 1 "immediate_operand" ""))]
1834   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1835    && !symbolic_operand (operands[1], DImode)
1836    && !x86_64_immediate_operand (operands[1], DImode)"
1837   [(set (match_dup 0) (match_dup 1))
1838    (set (match_dup 2) (match_dup 3))]
1839   "split_di (operands + 1, 1, operands + 2, operands + 3);
1840    operands[1] = gen_lowpart (DImode, operands[2]);
1841    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1842                                                     GEN_INT (4)));
1843   ")
1844
1845 (define_insn "*pushdi2_prologue_rex64"
1846   [(set (match_operand:DI 0 "push_operand" "=<")
1847         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1848    (clobber (mem:BLK (scratch)))]
1849   "TARGET_64BIT"
1850   "push{q}\t%1"
1851   [(set_attr "type" "push")
1852    (set_attr "mode" "DI")])
1853
1854 (define_insn "*popdi1_epilogue_rex64"
1855   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1856         (mem:DI (reg:DI SP_REG)))
1857    (set (reg:DI SP_REG)
1858         (plus:DI (reg:DI SP_REG) (const_int 8)))
1859    (clobber (mem:BLK (scratch)))]
1860   "TARGET_64BIT"
1861   "pop{q}\t%0"
1862   [(set_attr "type" "pop")
1863    (set_attr "mode" "DI")])
1864
1865 (define_insn "popdi1"
1866   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1867         (mem:DI (reg:DI SP_REG)))
1868    (set (reg:DI SP_REG)
1869         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1870   "TARGET_64BIT"
1871   "pop{q}\t%0"
1872   [(set_attr "type" "pop")
1873    (set_attr "mode" "DI")])
1874
1875 (define_insn "*movdi_xor_rex64"
1876   [(set (match_operand:DI 0 "register_operand" "=r")
1877         (match_operand:DI 1 "const0_operand" "i"))
1878    (clobber (reg:CC FLAGS_REG))]
1879   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1880    && reload_completed"
1881   "xor{l}\t{%k0, %k0|%k0, %k0}"
1882   [(set_attr "type" "alu1")
1883    (set_attr "mode" "SI")
1884    (set_attr "length_immediate" "0")])
1885
1886 (define_insn "*movdi_or_rex64"
1887   [(set (match_operand:DI 0 "register_operand" "=r")
1888         (match_operand:DI 1 "const_int_operand" "i"))
1889    (clobber (reg:CC FLAGS_REG))]
1890   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1891    && reload_completed
1892    && operands[1] == constm1_rtx"
1893 {
1894   operands[1] = constm1_rtx;
1895   return "or{q}\t{%1, %0|%0, %1}";
1896 }
1897   [(set_attr "type" "alu1")
1898    (set_attr "mode" "DI")
1899    (set_attr "length_immediate" "1")])
1900
1901 (define_insn "*movdi_2"
1902   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*x,!*x")
1903         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*x,*x,m"))]
1904   "!TARGET_64BIT
1905    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1906   "@
1907    #
1908    #
1909    movq\t{%1, %0|%0, %1}
1910    movq\t{%1, %0|%0, %1}
1911    movq\t{%1, %0|%0, %1}
1912    movdqa\t{%1, %0|%0, %1}
1913    movq\t{%1, %0|%0, %1}"
1914   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1915    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1916
1917 (define_split
1918   [(set (match_operand:DI 0 "push_operand" "")
1919         (match_operand:DI 1 "general_operand" ""))]
1920   "!TARGET_64BIT && reload_completed
1921    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1922   [(const_int 0)]
1923   "ix86_split_long_move (operands); DONE;")
1924
1925 ;; %%% This multiword shite has got to go.
1926 (define_split
1927   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1928         (match_operand:DI 1 "general_operand" ""))]
1929   "!TARGET_64BIT && reload_completed
1930    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1931    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1932   [(const_int 0)]
1933   "ix86_split_long_move (operands); DONE;")
1934
1935 (define_insn "*movdi_1_rex64"
1936   [(set (match_operand:DI 0 "nonimmediate_operand"
1937                 "=r,r  ,r,mr,!mr,!*y,!rm,!*y,!*x,!rm,!*x,!*x,!*y")
1938         (match_operand:DI 1 "general_operand"
1939                 "Z ,rem,i,re,n  ,*y ,*y ,rm ,*x ,*x ,rm ,*y ,*x"))]
1940   "TARGET_64BIT
1941    && (TARGET_INTER_UNIT_MOVES || optimize_size)
1942    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1943 {
1944   switch (get_attr_type (insn))
1945     {
1946     case TYPE_SSECVT:
1947       if (which_alternative == 11)
1948         return "movq2dq\t{%1, %0|%0, %1}";
1949       else
1950         return "movdq2q\t{%1, %0|%0, %1}";
1951     case TYPE_SSEMOV:
1952       if (get_attr_mode (insn) == MODE_TI)
1953           return "movdqa\t{%1, %0|%0, %1}";
1954       /* FALLTHRU */
1955     case TYPE_MMXMOV:
1956       /* Moves from and into integer register is done using movd opcode with
1957          REX prefix.  */
1958       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1959           return "movd\t{%1, %0|%0, %1}";
1960       return "movq\t{%1, %0|%0, %1}";
1961     case TYPE_MULTI:
1962       return "#";
1963     case TYPE_LEA:
1964       return "lea{q}\t{%a1, %0|%0, %a1}";
1965     default:
1966       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1967         abort ();
1968       if (get_attr_mode (insn) == MODE_SI)
1969         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1970       else if (which_alternative == 2)
1971         return "movabs{q}\t{%1, %0|%0, %1}";
1972       else
1973         return "mov{q}\t{%1, %0|%0, %1}";
1974     }
1975 }
1976   [(set (attr "type")
1977      (cond [(eq_attr "alternative" "5,6,7")
1978               (const_string "mmxmov")
1979             (eq_attr "alternative" "8,9,10")
1980               (const_string "ssemov")
1981             (eq_attr "alternative" "11,12")
1982               (const_string "ssecvt")
1983             (eq_attr "alternative" "4")
1984               (const_string "multi")
1985             (and (ne (symbol_ref "flag_pic") (const_int 0))
1986                  (match_operand:DI 1 "symbolic_operand" ""))
1987               (const_string "lea")
1988            ]
1989            (const_string "imov")))
1990    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
1991    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
1992    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
1993
1994 (define_insn "*movdi_1_rex64_nointerunit"
1995   [(set (match_operand:DI 0 "nonimmediate_operand"
1996                 "=r,r ,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
1997         (match_operand:DI 1 "general_operand"
1998                 "Z,rem,i,re,n  ,*y ,*y,m  ,*Y ,*Y,m"))]
1999   "TARGET_64BIT
2000    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2001    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2002 {
2003   switch (get_attr_type (insn))
2004     {
2005     case TYPE_SSEMOV:
2006       if (get_attr_mode (insn) == MODE_TI)
2007           return "movdqa\t{%1, %0|%0, %1}";
2008       /* FALLTHRU */
2009     case TYPE_MMXMOV:
2010       return "movq\t{%1, %0|%0, %1}";
2011     case TYPE_MULTI:
2012       return "#";
2013     case TYPE_LEA:
2014       return "lea{q}\t{%a1, %0|%0, %a1}";
2015     default:
2016       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2017         abort ();
2018       if (get_attr_mode (insn) == MODE_SI)
2019         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2020       else if (which_alternative == 2)
2021         return "movabs{q}\t{%1, %0|%0, %1}";
2022       else
2023         return "mov{q}\t{%1, %0|%0, %1}";
2024     }
2025 }
2026   [(set (attr "type")
2027      (cond [(eq_attr "alternative" "5,6,7")
2028               (const_string "mmxmov")
2029             (eq_attr "alternative" "8,9,10")
2030               (const_string "ssemov")
2031             (eq_attr "alternative" "4")
2032               (const_string "multi")
2033             (and (ne (symbol_ref "flag_pic") (const_int 0))
2034                  (match_operand:DI 1 "symbolic_operand" ""))
2035               (const_string "lea")
2036            ]
2037            (const_string "imov")))
2038    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2039    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2040    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2041
2042 ;; Stores and loads of ax to arbitrary constant address.
2043 ;; We fake an second form of instruction to force reload to load address
2044 ;; into register when rax is not available
2045 (define_insn "*movabsdi_1_rex64"
2046   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2047         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2048   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2049   "@
2050    movabs{q}\t{%1, %P0|%P0, %1}
2051    mov{q}\t{%1, %a0|%a0, %1}"
2052   [(set_attr "type" "imov")
2053    (set_attr "modrm" "0,*")
2054    (set_attr "length_address" "8,0")
2055    (set_attr "length_immediate" "0,*")
2056    (set_attr "memory" "store")
2057    (set_attr "mode" "DI")])
2058
2059 (define_insn "*movabsdi_2_rex64"
2060   [(set (match_operand:DI 0 "register_operand" "=a,r")
2061         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2062   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2063   "@
2064    movabs{q}\t{%P1, %0|%0, %P1}
2065    mov{q}\t{%a1, %0|%0, %a1}"
2066   [(set_attr "type" "imov")
2067    (set_attr "modrm" "0,*")
2068    (set_attr "length_address" "8,0")
2069    (set_attr "length_immediate" "0")
2070    (set_attr "memory" "load")
2071    (set_attr "mode" "DI")])
2072
2073 ;; Convert impossible stores of immediate to existing instructions.
2074 ;; First try to get scratch register and go through it.  In case this
2075 ;; fails, move by 32bit parts.
2076 (define_peephole2
2077   [(match_scratch:DI 2 "r")
2078    (set (match_operand:DI 0 "memory_operand" "")
2079         (match_operand:DI 1 "immediate_operand" ""))]
2080   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2081    && !x86_64_immediate_operand (operands[1], DImode)"
2082   [(set (match_dup 2) (match_dup 1))
2083    (set (match_dup 0) (match_dup 2))]
2084   "")
2085
2086 ;; We need to define this as both peepholer and splitter for case
2087 ;; peephole2 pass is not run.
2088 ;; "&& 1" is needed to keep it from matching the previous pattern.
2089 (define_peephole2
2090   [(set (match_operand:DI 0 "memory_operand" "")
2091         (match_operand:DI 1 "immediate_operand" ""))]
2092   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2093    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2094   [(set (match_dup 2) (match_dup 3))
2095    (set (match_dup 4) (match_dup 5))]
2096   "split_di (operands, 2, operands + 2, operands + 4);")
2097
2098 (define_split
2099   [(set (match_operand:DI 0 "memory_operand" "")
2100         (match_operand:DI 1 "immediate_operand" ""))]
2101   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2102    && !symbolic_operand (operands[1], DImode)
2103    && !x86_64_immediate_operand (operands[1], DImode)"
2104   [(set (match_dup 2) (match_dup 3))
2105    (set (match_dup 4) (match_dup 5))]
2106   "split_di (operands, 2, operands + 2, operands + 4);")
2107
2108 (define_insn "*swapdi_rex64"
2109   [(set (match_operand:DI 0 "register_operand" "+r")
2110         (match_operand:DI 1 "register_operand" "+r"))
2111    (set (match_dup 1)
2112         (match_dup 0))]
2113   "TARGET_64BIT"
2114   "xchg{q}\t%1, %0"
2115   [(set_attr "type" "imov")
2116    (set_attr "mode" "DI")
2117    (set_attr "pent_pair" "np")
2118    (set_attr "athlon_decode" "vector")])
2119
2120 (define_expand "movsf"
2121   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2122         (match_operand:SF 1 "general_operand" ""))]
2123   ""
2124   "ix86_expand_move (SFmode, operands); DONE;")
2125
2126 (define_insn "*pushsf"
2127   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2128         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2129   "!TARGET_64BIT"
2130 {
2131   switch (which_alternative)
2132     {
2133     case 1:
2134       return "push{l}\t%1";
2135
2136     default:
2137       /* This insn should be already split before reg-stack.  */
2138       abort ();
2139     }
2140 }
2141   [(set_attr "type" "multi,push,multi")
2142    (set_attr "mode" "SF,SI,SF")])
2143
2144 (define_insn "*pushsf_rex64"
2145   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2146         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2147   "TARGET_64BIT"
2148 {
2149   switch (which_alternative)
2150     {
2151     case 1:
2152       return "push{q}\t%q1";
2153
2154     default:
2155       /* This insn should be already split before reg-stack.  */
2156       abort ();
2157     }
2158 }
2159   [(set_attr "type" "multi,push,multi")
2160    (set_attr "mode" "SF,DI,SF")])
2161
2162 (define_split
2163   [(set (match_operand:SF 0 "push_operand" "")
2164         (match_operand:SF 1 "memory_operand" ""))]
2165   "reload_completed
2166    && GET_CODE (operands[1]) == MEM
2167    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2168    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2169   [(set (match_dup 0)
2170         (match_dup 1))]
2171   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2172
2173
2174 ;; %%% Kill this when call knows how to work this out.
2175 (define_split
2176   [(set (match_operand:SF 0 "push_operand" "")
2177         (match_operand:SF 1 "any_fp_register_operand" ""))]
2178   "!TARGET_64BIT"
2179   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2180    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2181
2182 (define_split
2183   [(set (match_operand:SF 0 "push_operand" "")
2184         (match_operand:SF 1 "any_fp_register_operand" ""))]
2185   "TARGET_64BIT"
2186   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2187    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2188
2189 (define_insn "*movsf_1"
2190   [(set (match_operand:SF 0 "nonimmediate_operand"
2191           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2192         (match_operand:SF 1 "general_operand"
2193           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2194   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2195    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2196    && (reload_in_progress || reload_completed
2197        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2198        || GET_CODE (operands[1]) != CONST_DOUBLE
2199        || memory_operand (operands[0], SFmode))" 
2200 {
2201   switch (which_alternative)
2202     {
2203     case 0:
2204       return output_387_reg_move (insn, operands);
2205
2206     case 1:
2207       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2208         return "fstp%z0\t%y0";
2209       else
2210         return "fst%z0\t%y0";
2211
2212     case 2:
2213       return standard_80387_constant_opcode (operands[1]);
2214
2215     case 3:
2216     case 4:
2217       return "mov{l}\t{%1, %0|%0, %1}";
2218     case 5:
2219       if (get_attr_mode (insn) == MODE_TI)
2220         return "pxor\t%0, %0";
2221       else
2222         return "xorps\t%0, %0";
2223     case 6:
2224       if (get_attr_mode (insn) == MODE_V4SF)
2225         return "movaps\t{%1, %0|%0, %1}";
2226       else
2227         return "movss\t{%1, %0|%0, %1}";
2228     case 7:
2229     case 8:
2230       return "movss\t{%1, %0|%0, %1}";
2231
2232     case 9:
2233     case 10:
2234       return "movd\t{%1, %0|%0, %1}";
2235
2236     case 11:
2237       return "movq\t{%1, %0|%0, %1}";
2238
2239     default:
2240       abort();
2241     }
2242 }
2243   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2244    (set (attr "mode")
2245         (cond [(eq_attr "alternative" "3,4,9,10")
2246                  (const_string "SI")
2247                (eq_attr "alternative" "5")
2248                  (if_then_else
2249                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2250                                  (const_int 0))
2251                              (ne (symbol_ref "TARGET_SSE2")
2252                                  (const_int 0)))
2253                         (eq (symbol_ref "optimize_size")
2254                             (const_int 0)))
2255                    (const_string "TI")
2256                    (const_string "V4SF"))
2257                /* For architectures resolving dependencies on
2258                   whole SSE registers use APS move to break dependency
2259                   chains, otherwise use short move to avoid extra work. 
2260
2261                   Do the same for architectures resolving dependencies on
2262                   the parts.  While in DF mode it is better to always handle
2263                   just register parts, the SF mode is different due to lack
2264                   of instructions to load just part of the register.  It is
2265                   better to maintain the whole registers in single format
2266                   to avoid problems on using packed logical operations.  */
2267                (eq_attr "alternative" "6")
2268                  (if_then_else
2269                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2270                             (const_int 0))
2271                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2272                             (const_int 0)))
2273                    (const_string "V4SF")
2274                    (const_string "SF"))
2275                (eq_attr "alternative" "11")
2276                  (const_string "DI")]
2277                (const_string "SF")))])
2278
2279 (define_insn "*movsf_1_nointerunit"
2280   [(set (match_operand:SF 0 "nonimmediate_operand"
2281           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!m,!*y")
2282         (match_operand:SF 1 "general_operand"
2283           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,m  ,*y,*y"))]
2284   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2285    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2286    && (reload_in_progress || reload_completed
2287        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2288        || GET_CODE (operands[1]) != CONST_DOUBLE
2289        || memory_operand (operands[0], SFmode))" 
2290 {
2291   switch (which_alternative)
2292     {
2293     case 0:
2294       return output_387_reg_move (insn, operands);
2295
2296     case 1:
2297       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2298         return "fstp%z0\t%y0";
2299       else
2300         return "fst%z0\t%y0";
2301
2302     case 2:
2303       return standard_80387_constant_opcode (operands[1]);
2304
2305     case 3:
2306     case 4:
2307       return "mov{l}\t{%1, %0|%0, %1}";
2308     case 5:
2309       if (get_attr_mode (insn) == MODE_TI)
2310         return "pxor\t%0, %0";
2311       else
2312         return "xorps\t%0, %0";
2313     case 6:
2314       if (get_attr_mode (insn) == MODE_V4SF)
2315         return "movaps\t{%1, %0|%0, %1}";
2316       else
2317         return "movss\t{%1, %0|%0, %1}";
2318     case 7:
2319     case 8:
2320       return "movss\t{%1, %0|%0, %1}";
2321
2322     case 9:
2323     case 10:
2324       return "movd\t{%1, %0|%0, %1}";
2325
2326     case 11:
2327       return "movq\t{%1, %0|%0, %1}";
2328
2329     default:
2330       abort();
2331     }
2332 }
2333   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2334    (set (attr "mode")
2335         (cond [(eq_attr "alternative" "3,4,9,10")
2336                  (const_string "SI")
2337                (eq_attr "alternative" "5")
2338                  (if_then_else
2339                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2340                                  (const_int 0))
2341                              (ne (symbol_ref "TARGET_SSE2")
2342                                  (const_int 0)))
2343                         (eq (symbol_ref "optimize_size")
2344                             (const_int 0)))
2345                    (const_string "TI")
2346                    (const_string "V4SF"))
2347                /* For architectures resolving dependencies on
2348                   whole SSE registers use APS move to break dependency
2349                   chains, otherwise use short move to avoid extra work. 
2350
2351                   Do the same for architectures resolving dependencies on
2352                   the parts.  While in DF mode it is better to always handle
2353                   just register parts, the SF mode is different due to lack
2354                   of instructions to load just part of the register.  It is
2355                   better to maintain the whole registers in single format
2356                   to avoid problems on using packed logical operations.  */
2357                (eq_attr "alternative" "6")
2358                  (if_then_else
2359                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2360                             (const_int 0))
2361                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2362                             (const_int 0)))
2363                    (const_string "V4SF")
2364                    (const_string "SF"))
2365                (eq_attr "alternative" "11")
2366                  (const_string "DI")]
2367                (const_string "SF")))])
2368
2369 (define_insn "*swapsf"
2370   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2371         (match_operand:SF 1 "fp_register_operand" "+f"))
2372    (set (match_dup 1)
2373         (match_dup 0))]
2374   "reload_completed || TARGET_80387"
2375 {
2376   if (STACK_TOP_P (operands[0]))
2377     return "fxch\t%1";
2378   else
2379     return "fxch\t%0";
2380 }
2381   [(set_attr "type" "fxch")
2382    (set_attr "mode" "SF")])
2383
2384 (define_expand "movdf"
2385   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2386         (match_operand:DF 1 "general_operand" ""))]
2387   ""
2388   "ix86_expand_move (DFmode, operands); DONE;")
2389
2390 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2391 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2392 ;; On the average, pushdf using integers can be still shorter.  Allow this
2393 ;; pattern for optimize_size too.
2394
2395 (define_insn "*pushdf_nointeger"
2396   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2397         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2398   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2399 {
2400   /* This insn should be already split before reg-stack.  */
2401   abort ();
2402 }
2403   [(set_attr "type" "multi")
2404    (set_attr "mode" "DF,SI,SI,DF")])
2405
2406 (define_insn "*pushdf_integer"
2407   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2408         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2409   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2410 {
2411   /* This insn should be already split before reg-stack.  */
2412   abort ();
2413 }
2414   [(set_attr "type" "multi")
2415    (set_attr "mode" "DF,SI,DF")])
2416
2417 ;; %%% Kill this when call knows how to work this out.
2418 (define_split
2419   [(set (match_operand:DF 0 "push_operand" "")
2420         (match_operand:DF 1 "any_fp_register_operand" ""))]
2421   "!TARGET_64BIT && reload_completed"
2422   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2423    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2424   "")
2425
2426 (define_split
2427   [(set (match_operand:DF 0 "push_operand" "")
2428         (match_operand:DF 1 "any_fp_register_operand" ""))]
2429   "TARGET_64BIT && reload_completed"
2430   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2431    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2432   "")
2433
2434 (define_split
2435   [(set (match_operand:DF 0 "push_operand" "")
2436         (match_operand:DF 1 "general_operand" ""))]
2437   "reload_completed"
2438   [(const_int 0)]
2439   "ix86_split_long_move (operands); DONE;")
2440
2441 ;; Moving is usually shorter when only FP registers are used. This separate
2442 ;; movdf pattern avoids the use of integer registers for FP operations
2443 ;; when optimizing for size.
2444
2445 (define_insn "*movdf_nointeger"
2446   [(set (match_operand:DF 0 "nonimmediate_operand"
2447                                 "=f#x,m  ,f#x,*r  ,o  ,x#f,x#f,x#f  ,m")
2448         (match_operand:DF 1 "general_operand"
2449                                 "fm#x,f#x,G  ,*roF,F*r,C  ,x#f,xHm#f,x#f"))]
2450   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2451    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2452    && (reload_in_progress || reload_completed
2453        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2454        || GET_CODE (operands[1]) != CONST_DOUBLE
2455        || memory_operand (operands[0], DFmode))" 
2456 {
2457   switch (which_alternative)
2458     {
2459     case 0:
2460       return output_387_reg_move (insn, operands);
2461
2462     case 1:
2463       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2464         return "fstp%z0\t%y0";
2465       else
2466         return "fst%z0\t%y0";
2467
2468     case 2:
2469       return standard_80387_constant_opcode (operands[1]);
2470
2471     case 3:
2472     case 4:
2473       return "#";
2474     case 5:
2475       switch (get_attr_mode (insn))
2476         {
2477         case MODE_V4SF:
2478           return "xorps\t%0, %0";
2479         case MODE_V2DF:
2480           return "xorpd\t%0, %0";
2481         case MODE_TI:
2482           return "pxor\t%0, %0";
2483         default:
2484           abort ();
2485         }
2486     case 6:
2487     case 7:
2488     case 8:
2489       switch (get_attr_mode (insn))
2490         {
2491         case MODE_V4SF:
2492           return "movaps\t{%1, %0|%0, %1}";
2493         case MODE_V2DF:
2494           return "movapd\t{%1, %0|%0, %1}";
2495         case MODE_TI:
2496           return "movdqa\t{%1, %0|%0, %1}";
2497         case MODE_DI:
2498           return "movq\t{%1, %0|%0, %1}";
2499         case MODE_DF:
2500           return "movsd\t{%1, %0|%0, %1}";
2501         case MODE_V1DF:
2502           return "movlpd\t{%1, %0|%0, %1}";
2503         default:
2504           abort ();
2505         }
2506
2507     default:
2508       abort();
2509     }
2510 }
2511   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2512    (set (attr "mode")
2513         (cond [(eq_attr "alternative" "3,4")
2514                  (const_string "SI")
2515
2516                /* For SSE1, we have many fewer alternatives.  */
2517                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2518                  (cond [(eq_attr "alternative" "5,6")
2519                           (if_then_else
2520                             (ne (symbol_ref "optimize_size") (const_int 0))
2521                             (const_string "V4SF")
2522                             (const_string "TI"))
2523                        ]
2524                    (const_string "DI"))
2525
2526                /* xorps is one byte shorter.  */
2527                (eq_attr "alternative" "5")
2528                  (cond [(ne (symbol_ref "optimize_size")
2529                             (const_int 0))
2530                           (const_string "V4SF")
2531                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2532                             (const_int 0))
2533                           (const_string "TI")
2534                        ]
2535                        (const_string "V2DF"))
2536
2537                /* For architectures resolving dependencies on
2538                   whole SSE registers use APD move to break dependency
2539                   chains, otherwise use short move to avoid extra work.
2540
2541                   movaps encodes one byte shorter.  */
2542                (eq_attr "alternative" "6")
2543                  (cond
2544                    [(ne (symbol_ref "optimize_size")
2545                         (const_int 0))
2546                       (const_string "V4SF")
2547                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2548                         (const_int 0))
2549                       (const_string "V2DF")
2550                    ]
2551                    (const_string "DF"))
2552                /* For architectures resolving dependencies on register
2553                   parts we may avoid extra work to zero out upper part
2554                   of register.  */
2555                (eq_attr "alternative" "7")
2556                  (if_then_else
2557                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2558                        (const_int 0))
2559                    (const_string "V1DF")
2560                    (const_string "DF"))
2561               ]
2562               (const_string "DF")))])
2563
2564 (define_insn "*movdf_integer"
2565   [(set (match_operand:DF 0 "nonimmediate_operand"
2566                         "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y#rf,Y#rf,Y#rf ,m")
2567         (match_operand:DF 1 "general_operand"
2568                         "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C   ,Y#rf,Ym#rf,Y#rf"))]
2569   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2570    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2571    && (reload_in_progress || reload_completed
2572        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2573        || GET_CODE (operands[1]) != CONST_DOUBLE
2574        || memory_operand (operands[0], DFmode))" 
2575 {
2576   switch (which_alternative)
2577     {
2578     case 0:
2579       return output_387_reg_move (insn, operands);
2580
2581     case 1:
2582       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2583         return "fstp%z0\t%y0";
2584       else
2585         return "fst%z0\t%y0";
2586
2587     case 2:
2588       return standard_80387_constant_opcode (operands[1]);
2589
2590     case 3:
2591     case 4:
2592       return "#";
2593
2594     case 5:
2595       switch (get_attr_mode (insn))
2596         {
2597         case MODE_V4SF:
2598           return "xorps\t%0, %0";
2599         case MODE_V2DF:
2600           return "xorpd\t%0, %0";
2601         case MODE_TI:
2602           return "pxor\t%0, %0";
2603         default:
2604           abort ();
2605         }
2606     case 6:
2607     case 7:
2608     case 8:
2609       switch (get_attr_mode (insn))
2610         {
2611         case MODE_V4SF:
2612           return "movaps\t{%1, %0|%0, %1}";
2613         case MODE_V2DF:
2614           return "movapd\t{%1, %0|%0, %1}";
2615         case MODE_TI:
2616           return "movdqa\t{%1, %0|%0, %1}";
2617         case MODE_DI:
2618           return "movq\t{%1, %0|%0, %1}";
2619         case MODE_DF:
2620           return "movsd\t{%1, %0|%0, %1}";
2621         case MODE_V1DF:
2622           return "movlpd\t{%1, %0|%0, %1}";
2623         default:
2624           abort ();
2625         }
2626
2627     default:
2628       abort();
2629     }
2630 }
2631   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2632    (set (attr "mode")
2633         (cond [(eq_attr "alternative" "3,4")
2634                  (const_string "SI")
2635
2636                /* For SSE1, we have many fewer alternatives.  */
2637                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2638                  (cond [(eq_attr "alternative" "5,6")
2639                           (if_then_else
2640                             (ne (symbol_ref "optimize_size") (const_int 0))
2641                             (const_string "V4SF")
2642                             (const_string "TI"))
2643                        ]
2644                    (const_string "DI"))
2645
2646                /* xorps is one byte shorter.  */
2647                (eq_attr "alternative" "5")
2648                  (cond [(ne (symbol_ref "optimize_size")
2649                             (const_int 0))
2650                           (const_string "V4SF")
2651                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2652                             (const_int 0))
2653                           (const_string "TI")
2654                        ]
2655                        (const_string "V2DF"))
2656
2657                /* For architectures resolving dependencies on
2658                   whole SSE registers use APD move to break dependency
2659                   chains, otherwise use short move to avoid extra work.
2660
2661                   movaps encodes one byte shorter.  */
2662                (eq_attr "alternative" "6")
2663                  (cond
2664                    [(ne (symbol_ref "optimize_size")
2665                         (const_int 0))
2666                       (const_string "V4SF")
2667                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2668                         (const_int 0))
2669                       (const_string "V2DF")
2670                    ]
2671                    (const_string "DF"))
2672                /* For architectures resolving dependencies on register
2673                   parts we may avoid extra work to zero out upper part
2674                   of register.  */
2675                (eq_attr "alternative" "7")
2676                  (if_then_else
2677                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2678                        (const_int 0))
2679                    (const_string "V1DF")
2680                    (const_string "DF"))
2681               ]
2682               (const_string "DF")))])
2683
2684 (define_split
2685   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2686         (match_operand:DF 1 "general_operand" ""))]
2687   "reload_completed
2688    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2689    && ! (ANY_FP_REG_P (operands[0]) || 
2690          (GET_CODE (operands[0]) == SUBREG
2691           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2692    && ! (ANY_FP_REG_P (operands[1]) || 
2693          (GET_CODE (operands[1]) == SUBREG
2694           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2695   [(const_int 0)]
2696   "ix86_split_long_move (operands); DONE;")
2697
2698 (define_insn "*swapdf"
2699   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2700         (match_operand:DF 1 "fp_register_operand" "+f"))
2701    (set (match_dup 1)
2702         (match_dup 0))]
2703   "reload_completed || TARGET_80387"
2704 {
2705   if (STACK_TOP_P (operands[0]))
2706     return "fxch\t%1";
2707   else
2708     return "fxch\t%0";
2709 }
2710   [(set_attr "type" "fxch")
2711    (set_attr "mode" "DF")])
2712
2713 (define_expand "movxf"
2714   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2715         (match_operand:XF 1 "general_operand" ""))]
2716   ""
2717   "ix86_expand_move (XFmode, operands); DONE;")
2718
2719 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2720 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2721 ;; Pushing using integer instructions is longer except for constants
2722 ;; and direct memory references.
2723 ;; (assuming that any given constant is pushed only once, but this ought to be
2724 ;;  handled elsewhere).
2725
2726 (define_insn "*pushxf_nointeger"
2727   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2728         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2729   "optimize_size"
2730 {
2731   /* This insn should be already split before reg-stack.  */
2732   abort ();
2733 }
2734   [(set_attr "type" "multi")
2735    (set_attr "mode" "XF,SI,SI")])
2736
2737 (define_insn "*pushxf_integer"
2738   [(set (match_operand:XF 0 "push_operand" "=<,<")
2739         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2740   "!optimize_size"
2741 {
2742   /* This insn should be already split before reg-stack.  */
2743   abort ();
2744 }
2745   [(set_attr "type" "multi")
2746    (set_attr "mode" "XF,SI")])
2747
2748 (define_split
2749   [(set (match_operand 0 "push_operand" "")
2750         (match_operand 1 "general_operand" ""))]
2751   "reload_completed
2752    && (GET_MODE (operands[0]) == XFmode
2753        || GET_MODE (operands[0]) == DFmode)
2754    && !ANY_FP_REG_P (operands[1])"
2755   [(const_int 0)]
2756   "ix86_split_long_move (operands); DONE;")
2757
2758 (define_split
2759   [(set (match_operand:XF 0 "push_operand" "")
2760         (match_operand:XF 1 "any_fp_register_operand" ""))]
2761   "!TARGET_64BIT"
2762   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2763    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2764   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2765
2766 (define_split
2767   [(set (match_operand:XF 0 "push_operand" "")
2768         (match_operand:XF 1 "any_fp_register_operand" ""))]
2769   "TARGET_64BIT"
2770   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2771    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2772   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2773
2774 ;; Do not use integer registers when optimizing for size
2775 (define_insn "*movxf_nointeger"
2776   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2777         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2778   "optimize_size
2779    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2780    && (reload_in_progress || reload_completed
2781        || GET_CODE (operands[1]) != CONST_DOUBLE
2782        || memory_operand (operands[0], XFmode))" 
2783 {
2784   switch (which_alternative)
2785     {
2786     case 0:
2787       return output_387_reg_move (insn, operands);
2788
2789     case 1:
2790       /* There is no non-popping store to memory for XFmode.  So if
2791          we need one, follow the store with a load.  */
2792       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2793         return "fstp%z0\t%y0\;fld%z0\t%y0";
2794       else
2795         return "fstp%z0\t%y0";
2796
2797     case 2:
2798       return standard_80387_constant_opcode (operands[1]);
2799
2800     case 3: case 4:
2801       return "#";
2802     }
2803   abort();
2804 }
2805   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2806    (set_attr "mode" "XF,XF,XF,SI,SI")])
2807
2808 (define_insn "*movxf_integer"
2809   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2810         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2811   "!optimize_size
2812    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2813    && (reload_in_progress || reload_completed
2814        || GET_CODE (operands[1]) != CONST_DOUBLE
2815        || memory_operand (operands[0], XFmode))" 
2816 {
2817   switch (which_alternative)
2818     {
2819     case 0:
2820       return output_387_reg_move (insn, operands);
2821
2822     case 1:
2823       /* There is no non-popping store to memory for XFmode.  So if
2824          we need one, follow the store with a load.  */
2825       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2826         return "fstp%z0\t%y0\;fld%z0\t%y0";
2827       else
2828         return "fstp%z0\t%y0";
2829
2830     case 2:
2831       return standard_80387_constant_opcode (operands[1]);
2832
2833     case 3: case 4:
2834       return "#";
2835     }
2836   abort();
2837 }
2838   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2839    (set_attr "mode" "XF,XF,XF,SI,SI")])
2840
2841 (define_split
2842   [(set (match_operand 0 "nonimmediate_operand" "")
2843         (match_operand 1 "general_operand" ""))]
2844   "reload_completed
2845    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2846    && GET_MODE (operands[0]) == XFmode
2847    && ! (ANY_FP_REG_P (operands[0]) || 
2848          (GET_CODE (operands[0]) == SUBREG
2849           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2850    && ! (ANY_FP_REG_P (operands[1]) || 
2851          (GET_CODE (operands[1]) == SUBREG
2852           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2853   [(const_int 0)]
2854   "ix86_split_long_move (operands); DONE;")
2855
2856 (define_split
2857   [(set (match_operand 0 "register_operand" "")
2858         (match_operand 1 "memory_operand" ""))]
2859   "reload_completed
2860    && GET_CODE (operands[1]) == MEM
2861    && (GET_MODE (operands[0]) == XFmode
2862        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2863    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2864    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2865   [(set (match_dup 0) (match_dup 1))]
2866 {
2867   rtx c = get_pool_constant (XEXP (operands[1], 0));
2868   rtx r = operands[0];
2869
2870   if (GET_CODE (r) == SUBREG)
2871     r = SUBREG_REG (r);
2872
2873   if (SSE_REG_P (r))
2874     {
2875       if (!standard_sse_constant_p (c))
2876         FAIL;
2877     }
2878   else if (FP_REG_P (r))
2879     {
2880       if (!standard_80387_constant_p (c))
2881         FAIL;
2882     }
2883   else if (MMX_REG_P (r))
2884     FAIL;
2885
2886   operands[1] = c;
2887 })
2888
2889 (define_insn "swapxf"
2890   [(set (match_operand:XF 0 "register_operand" "+f")
2891         (match_operand:XF 1 "register_operand" "+f"))
2892    (set (match_dup 1)
2893         (match_dup 0))]
2894   "TARGET_80387"
2895 {
2896   if (STACK_TOP_P (operands[0]))
2897     return "fxch\t%1";
2898   else
2899     return "fxch\t%0";
2900 }
2901   [(set_attr "type" "fxch")
2902    (set_attr "mode" "XF")])
2903 \f
2904 ;; Zero extension instructions
2905
2906 (define_expand "zero_extendhisi2"
2907   [(set (match_operand:SI 0 "register_operand" "")
2908      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2909   ""
2910 {
2911   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2912     {
2913       operands[1] = force_reg (HImode, operands[1]);
2914       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2915       DONE;
2916     }
2917 })
2918
2919 (define_insn "zero_extendhisi2_and"
2920   [(set (match_operand:SI 0 "register_operand" "=r")
2921      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2922    (clobber (reg:CC FLAGS_REG))]
2923   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2924   "#"
2925   [(set_attr "type" "alu1")
2926    (set_attr "mode" "SI")])
2927
2928 (define_split
2929   [(set (match_operand:SI 0 "register_operand" "")
2930         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2931    (clobber (reg:CC FLAGS_REG))]
2932   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2933   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2934               (clobber (reg:CC FLAGS_REG))])]
2935   "")
2936
2937 (define_insn "*zero_extendhisi2_movzwl"
2938   [(set (match_operand:SI 0 "register_operand" "=r")
2939      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2940   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2941   "movz{wl|x}\t{%1, %0|%0, %1}"
2942   [(set_attr "type" "imovx")
2943    (set_attr "mode" "SI")])
2944
2945 (define_expand "zero_extendqihi2"
2946   [(parallel
2947     [(set (match_operand:HI 0 "register_operand" "")
2948        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2949      (clobber (reg:CC FLAGS_REG))])]
2950   ""
2951   "")
2952
2953 (define_insn "*zero_extendqihi2_and"
2954   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2955      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2956    (clobber (reg:CC FLAGS_REG))]
2957   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2958   "#"
2959   [(set_attr "type" "alu1")
2960    (set_attr "mode" "HI")])
2961
2962 (define_insn "*zero_extendqihi2_movzbw_and"
2963   [(set (match_operand:HI 0 "register_operand" "=r,r")
2964      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2965    (clobber (reg:CC FLAGS_REG))]
2966   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2967   "#"
2968   [(set_attr "type" "imovx,alu1")
2969    (set_attr "mode" "HI")])
2970
2971 (define_insn "*zero_extendqihi2_movzbw"
2972   [(set (match_operand:HI 0 "register_operand" "=r")
2973      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2974   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2975   "movz{bw|x}\t{%1, %0|%0, %1}"
2976   [(set_attr "type" "imovx")
2977    (set_attr "mode" "HI")])
2978
2979 ;; For the movzbw case strip only the clobber
2980 (define_split
2981   [(set (match_operand:HI 0 "register_operand" "")
2982         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2983    (clobber (reg:CC FLAGS_REG))]
2984   "reload_completed 
2985    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2986    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2987   [(set (match_operand:HI 0 "register_operand" "")
2988         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2989
2990 ;; When source and destination does not overlap, clear destination
2991 ;; first and then do the movb
2992 (define_split
2993   [(set (match_operand:HI 0 "register_operand" "")
2994         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2995    (clobber (reg:CC FLAGS_REG))]
2996   "reload_completed
2997    && ANY_QI_REG_P (operands[0])
2998    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2999    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3000   [(set (match_dup 0) (const_int 0))
3001    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3002   "operands[2] = gen_lowpart (QImode, operands[0]);")
3003
3004 ;; Rest is handled by single and.
3005 (define_split
3006   [(set (match_operand:HI 0 "register_operand" "")
3007         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3008    (clobber (reg:CC FLAGS_REG))]
3009   "reload_completed
3010    && true_regnum (operands[0]) == true_regnum (operands[1])"
3011   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3012               (clobber (reg:CC FLAGS_REG))])]
3013   "")
3014
3015 (define_expand "zero_extendqisi2"
3016   [(parallel
3017     [(set (match_operand:SI 0 "register_operand" "")
3018        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3019      (clobber (reg:CC FLAGS_REG))])]
3020   ""
3021   "")
3022
3023 (define_insn "*zero_extendqisi2_and"
3024   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3025      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3026    (clobber (reg:CC FLAGS_REG))]
3027   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3028   "#"
3029   [(set_attr "type" "alu1")
3030    (set_attr "mode" "SI")])
3031
3032 (define_insn "*zero_extendqisi2_movzbw_and"
3033   [(set (match_operand:SI 0 "register_operand" "=r,r")
3034      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3035    (clobber (reg:CC FLAGS_REG))]
3036   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3037   "#"
3038   [(set_attr "type" "imovx,alu1")
3039    (set_attr "mode" "SI")])
3040
3041 (define_insn "*zero_extendqisi2_movzbw"
3042   [(set (match_operand:SI 0 "register_operand" "=r")
3043      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3044   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3045   "movz{bl|x}\t{%1, %0|%0, %1}"
3046   [(set_attr "type" "imovx")
3047    (set_attr "mode" "SI")])
3048
3049 ;; For the movzbl case strip only the clobber
3050 (define_split
3051   [(set (match_operand:SI 0 "register_operand" "")
3052         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3053    (clobber (reg:CC FLAGS_REG))]
3054   "reload_completed 
3055    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3056    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3057   [(set (match_dup 0)
3058         (zero_extend:SI (match_dup 1)))])
3059
3060 ;; When source and destination does not overlap, clear destination
3061 ;; first and then do the movb
3062 (define_split
3063   [(set (match_operand:SI 0 "register_operand" "")
3064         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3065    (clobber (reg:CC FLAGS_REG))]
3066   "reload_completed
3067    && ANY_QI_REG_P (operands[0])
3068    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3069    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3070    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3071   [(set (match_dup 0) (const_int 0))
3072    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3073   "operands[2] = gen_lowpart (QImode, operands[0]);")
3074
3075 ;; Rest is handled by single and.
3076 (define_split
3077   [(set (match_operand:SI 0 "register_operand" "")
3078         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3079    (clobber (reg:CC FLAGS_REG))]
3080   "reload_completed
3081    && true_regnum (operands[0]) == true_regnum (operands[1])"
3082   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3083               (clobber (reg:CC FLAGS_REG))])]
3084   "")
3085
3086 ;; %%% Kill me once multi-word ops are sane.
3087 (define_expand "zero_extendsidi2"
3088   [(set (match_operand:DI 0 "register_operand" "=r")
3089      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3090   ""
3091   "if (!TARGET_64BIT)
3092      {
3093        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3094        DONE;
3095      }
3096   ")
3097
3098 (define_insn "zero_extendsidi2_32"
3099   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3100         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3101    (clobber (reg:CC FLAGS_REG))]
3102   "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3103   "@
3104    #
3105    #
3106    #
3107    movd\t{%1, %0|%0, %1}
3108    movd\t{%1, %0|%0, %1}"
3109   [(set_attr "mode" "SI,SI,SI,DI,TI")
3110    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3111
3112 (define_insn "*zero_extendsidi2_32_1"
3113   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3114         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3115    (clobber (reg:CC FLAGS_REG))]
3116   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3117   "@
3118    #
3119    #
3120    #
3121    movd\t{%1, %0|%0, %1}
3122    movd\t{%1, %0|%0, %1}"
3123   [(set_attr "mode" "SI,SI,SI,DI,TI")
3124    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3125
3126 (define_insn "zero_extendsidi2_rex64"
3127   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3128      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3129   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3130   "@
3131    mov\t{%k1, %k0|%k0, %k1}
3132    #
3133    movd\t{%1, %0|%0, %1}
3134    movd\t{%1, %0|%0, %1}"
3135   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3136    (set_attr "mode" "SI,DI,DI,TI")])
3137
3138 (define_insn "*zero_extendsidi2_rex64_1"
3139   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3140      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3141   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3142   "@
3143    mov\t{%k1, %k0|%k0, %k1}
3144    #
3145    movd\t{%1, %0|%0, %1}
3146    movd\t{%1, %0|%0, %1}"
3147   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3148    (set_attr "mode" "SI,DI,SI,SI")])
3149
3150 (define_split
3151   [(set (match_operand:DI 0 "memory_operand" "")
3152      (zero_extend:DI (match_dup 0)))]
3153   "TARGET_64BIT"
3154   [(set (match_dup 4) (const_int 0))]
3155   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3156
3157 (define_split 
3158   [(set (match_operand:DI 0 "register_operand" "")
3159         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3160    (clobber (reg:CC FLAGS_REG))]
3161   "!TARGET_64BIT && reload_completed
3162    && true_regnum (operands[0]) == true_regnum (operands[1])"
3163   [(set (match_dup 4) (const_int 0))]
3164   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3165
3166 (define_split 
3167   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3168         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3169    (clobber (reg:CC FLAGS_REG))]
3170   "!TARGET_64BIT && reload_completed
3171    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3172   [(set (match_dup 3) (match_dup 1))
3173    (set (match_dup 4) (const_int 0))]
3174   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3175
3176 (define_insn "zero_extendhidi2"
3177   [(set (match_operand:DI 0 "register_operand" "=r,r")
3178      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3179   "TARGET_64BIT"
3180   "@
3181    movz{wl|x}\t{%1, %k0|%k0, %1}
3182    movz{wq|x}\t{%1, %0|%0, %1}"
3183   [(set_attr "type" "imovx")
3184    (set_attr "mode" "SI,DI")])
3185
3186 (define_insn "zero_extendqidi2"
3187   [(set (match_operand:DI 0 "register_operand" "=r,r")
3188      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3189   "TARGET_64BIT"
3190   "@
3191    movz{bl|x}\t{%1, %k0|%k0, %1}
3192    movz{bq|x}\t{%1, %0|%0, %1}"
3193   [(set_attr "type" "imovx")
3194    (set_attr "mode" "SI,DI")])
3195 \f
3196 ;; Sign extension instructions
3197
3198 (define_expand "extendsidi2"
3199   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3200                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3201               (clobber (reg:CC FLAGS_REG))
3202               (clobber (match_scratch:SI 2 ""))])]
3203   ""
3204 {
3205   if (TARGET_64BIT)
3206     {
3207       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3208       DONE;
3209     }
3210 })
3211
3212 (define_insn "*extendsidi2_1"
3213   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3214         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3215    (clobber (reg:CC FLAGS_REG))
3216    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3217   "!TARGET_64BIT"
3218   "#")
3219
3220 (define_insn "extendsidi2_rex64"
3221   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3222         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3223   "TARGET_64BIT"
3224   "@
3225    {cltq|cdqe}
3226    movs{lq|x}\t{%1,%0|%0, %1}"
3227   [(set_attr "type" "imovx")
3228    (set_attr "mode" "DI")
3229    (set_attr "prefix_0f" "0")
3230    (set_attr "modrm" "0,1")])
3231
3232 (define_insn "extendhidi2"
3233   [(set (match_operand:DI 0 "register_operand" "=r")
3234         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3235   "TARGET_64BIT"
3236   "movs{wq|x}\t{%1,%0|%0, %1}"
3237   [(set_attr "type" "imovx")
3238    (set_attr "mode" "DI")])
3239
3240 (define_insn "extendqidi2"
3241   [(set (match_operand:DI 0 "register_operand" "=r")
3242         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3243   "TARGET_64BIT"
3244   "movs{bq|x}\t{%1,%0|%0, %1}"
3245    [(set_attr "type" "imovx")
3246     (set_attr "mode" "DI")])
3247
3248 ;; Extend to memory case when source register does die.
3249 (define_split 
3250   [(set (match_operand:DI 0 "memory_operand" "")
3251         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3252    (clobber (reg:CC FLAGS_REG))
3253    (clobber (match_operand:SI 2 "register_operand" ""))]
3254   "(reload_completed
3255     && dead_or_set_p (insn, operands[1])
3256     && !reg_mentioned_p (operands[1], operands[0]))"
3257   [(set (match_dup 3) (match_dup 1))
3258    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3259               (clobber (reg:CC FLAGS_REG))])
3260    (set (match_dup 4) (match_dup 1))]
3261   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3262
3263 ;; Extend to memory case when source register does not die.
3264 (define_split 
3265   [(set (match_operand:DI 0 "memory_operand" "")
3266         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3267    (clobber (reg:CC FLAGS_REG))
3268    (clobber (match_operand:SI 2 "register_operand" ""))]
3269   "reload_completed"
3270   [(const_int 0)]
3271 {
3272   split_di (&operands[0], 1, &operands[3], &operands[4]);
3273
3274   emit_move_insn (operands[3], operands[1]);
3275
3276   /* Generate a cltd if possible and doing so it profitable.  */
3277   if (true_regnum (operands[1]) == 0
3278       && true_regnum (operands[2]) == 1
3279       && (optimize_size || TARGET_USE_CLTD))
3280     {
3281       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3282     }
3283   else
3284     {
3285       emit_move_insn (operands[2], operands[1]);
3286       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3287     }
3288   emit_move_insn (operands[4], operands[2]);
3289   DONE;
3290 })
3291
3292 ;; Extend to register case.  Optimize case where source and destination
3293 ;; registers match and cases where we can use cltd.
3294 (define_split 
3295   [(set (match_operand:DI 0 "register_operand" "")
3296         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3297    (clobber (reg:CC FLAGS_REG))
3298    (clobber (match_scratch:SI 2 ""))]
3299   "reload_completed"
3300   [(const_int 0)]
3301 {
3302   split_di (&operands[0], 1, &operands[3], &operands[4]);
3303
3304   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3305     emit_move_insn (operands[3], operands[1]);
3306
3307   /* Generate a cltd if possible and doing so it profitable.  */
3308   if (true_regnum (operands[3]) == 0
3309       && (optimize_size || TARGET_USE_CLTD))
3310     {
3311       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3312       DONE;
3313     }
3314
3315   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3316     emit_move_insn (operands[4], operands[1]);
3317
3318   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3319   DONE;
3320 })
3321
3322 (define_insn "extendhisi2"
3323   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3324         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3325   ""
3326 {
3327   switch (get_attr_prefix_0f (insn))
3328     {
3329     case 0:
3330       return "{cwtl|cwde}";
3331     default:
3332       return "movs{wl|x}\t{%1,%0|%0, %1}";
3333     }
3334 }
3335   [(set_attr "type" "imovx")
3336    (set_attr "mode" "SI")
3337    (set (attr "prefix_0f")
3338      ;; movsx is short decodable while cwtl is vector decoded.
3339      (if_then_else (and (eq_attr "cpu" "!k6")
3340                         (eq_attr "alternative" "0"))
3341         (const_string "0")
3342         (const_string "1")))
3343    (set (attr "modrm")
3344      (if_then_else (eq_attr "prefix_0f" "0")
3345         (const_string "0")
3346         (const_string "1")))])
3347
3348 (define_insn "*extendhisi2_zext"
3349   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3350         (zero_extend:DI
3351           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3352   "TARGET_64BIT"
3353 {
3354   switch (get_attr_prefix_0f (insn))
3355     {
3356     case 0:
3357       return "{cwtl|cwde}";
3358     default:
3359       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3360     }
3361 }
3362   [(set_attr "type" "imovx")
3363    (set_attr "mode" "SI")
3364    (set (attr "prefix_0f")
3365      ;; movsx is short decodable while cwtl is vector decoded.
3366      (if_then_else (and (eq_attr "cpu" "!k6")
3367                         (eq_attr "alternative" "0"))
3368         (const_string "0")
3369         (const_string "1")))
3370    (set (attr "modrm")
3371      (if_then_else (eq_attr "prefix_0f" "0")
3372         (const_string "0")
3373         (const_string "1")))])
3374
3375 (define_insn "extendqihi2"
3376   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3377         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3378   ""
3379 {
3380   switch (get_attr_prefix_0f (insn))
3381     {
3382     case 0:
3383       return "{cbtw|cbw}";
3384     default:
3385       return "movs{bw|x}\t{%1,%0|%0, %1}";
3386     }
3387 }
3388   [(set_attr "type" "imovx")
3389    (set_attr "mode" "HI")
3390    (set (attr "prefix_0f")
3391      ;; movsx is short decodable while cwtl is vector decoded.
3392      (if_then_else (and (eq_attr "cpu" "!k6")
3393                         (eq_attr "alternative" "0"))
3394         (const_string "0")
3395         (const_string "1")))
3396    (set (attr "modrm")
3397      (if_then_else (eq_attr "prefix_0f" "0")
3398         (const_string "0")
3399         (const_string "1")))])
3400
3401 (define_insn "extendqisi2"
3402   [(set (match_operand:SI 0 "register_operand" "=r")
3403         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3404   ""
3405   "movs{bl|x}\t{%1,%0|%0, %1}"
3406    [(set_attr "type" "imovx")
3407     (set_attr "mode" "SI")])
3408
3409 (define_insn "*extendqisi2_zext"
3410   [(set (match_operand:DI 0 "register_operand" "=r")
3411         (zero_extend:DI
3412           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3413   "TARGET_64BIT"
3414   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3415    [(set_attr "type" "imovx")
3416     (set_attr "mode" "SI")])
3417 \f
3418 ;; Conversions between float and double.
3419
3420 ;; These are all no-ops in the model used for the 80387.  So just
3421 ;; emit moves.
3422
3423 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3424 (define_insn "*dummy_extendsfdf2"
3425   [(set (match_operand:DF 0 "push_operand" "=<")
3426         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3427   "0"
3428   "#")
3429
3430 (define_split
3431   [(set (match_operand:DF 0 "push_operand" "")
3432         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3433   "!TARGET_64BIT"
3434   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3435    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3436
3437 (define_split
3438   [(set (match_operand:DF 0 "push_operand" "")
3439         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3440   "TARGET_64BIT"
3441   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3442    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3443
3444 (define_insn "*dummy_extendsfxf2"
3445   [(set (match_operand:XF 0 "push_operand" "=<")
3446         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3447   "0"
3448   "#")
3449
3450 (define_split
3451   [(set (match_operand:XF 0 "push_operand" "")
3452         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3453   ""
3454   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3455    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3456   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3457
3458 (define_split
3459   [(set (match_operand:XF 0 "push_operand" "")
3460         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3461   "TARGET_64BIT"
3462   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3463    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3464   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3465
3466 (define_split
3467   [(set (match_operand:XF 0 "push_operand" "")
3468         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3469   ""
3470   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3471    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3472   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3473
3474 (define_split
3475   [(set (match_operand:XF 0 "push_operand" "")
3476         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3477   "TARGET_64BIT"
3478   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3479    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3480   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3481
3482 (define_expand "extendsfdf2"
3483   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3484         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3485   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3486 {
3487   /* ??? Needed for compress_float_constant since all fp constants
3488      are LEGITIMATE_CONSTANT_P.  */
3489   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3490     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3491   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3492     operands[1] = force_reg (SFmode, operands[1]);
3493 })
3494
3495 (define_insn "*extendsfdf2_mixed"
3496   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3497         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3498   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3499    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3500 {
3501   switch (which_alternative)
3502     {
3503     case 0:
3504       return output_387_reg_move (insn, operands);
3505
3506     case 1:
3507       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3508         return "fstp%z0\t%y0";
3509       else
3510         return "fst%z0\t%y0";
3511
3512     case 2:
3513       return "cvtss2sd\t{%1, %0|%0, %1}";
3514
3515     default:
3516       abort ();
3517     }
3518 }
3519   [(set_attr "type" "fmov,fmov,ssecvt")
3520    (set_attr "mode" "SF,XF,DF")])
3521
3522 (define_insn "*extendsfdf2_sse"
3523   [(set (match_operand:DF 0 "register_operand" "=Y")
3524         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3525   "TARGET_SSE2 && TARGET_SSE_MATH
3526    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3527   "cvtss2sd\t{%1, %0|%0, %1}"
3528   [(set_attr "type" "ssecvt")
3529    (set_attr "mode" "DF")])
3530
3531 (define_insn "*extendsfdf2_i387"
3532   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3533         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3534   "TARGET_80387
3535    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3536 {
3537   switch (which_alternative)
3538     {
3539     case 0:
3540       return output_387_reg_move (insn, operands);
3541
3542     case 1:
3543       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3544         return "fstp%z0\t%y0";
3545       else
3546         return "fst%z0\t%y0";
3547
3548     default:
3549       abort ();
3550     }
3551 }
3552   [(set_attr "type" "fmov")
3553    (set_attr "mode" "SF,XF")])
3554
3555 (define_expand "extendsfxf2"
3556   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3557         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3558   "TARGET_80387"
3559 {
3560   /* ??? Needed for compress_float_constant since all fp constants
3561      are LEGITIMATE_CONSTANT_P.  */
3562   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3563     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3564   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3565     operands[1] = force_reg (SFmode, operands[1]);
3566 })
3567
3568 (define_insn "*extendsfxf2_i387"
3569   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3570         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3571   "TARGET_80387
3572    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3573 {
3574   switch (which_alternative)
3575     {
3576     case 0:
3577       return output_387_reg_move (insn, operands);
3578
3579     case 1:
3580       /* There is no non-popping store to memory for XFmode.  So if
3581          we need one, follow the store with a load.  */
3582       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3583         return "fstp%z0\t%y0";
3584       else
3585         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3586
3587     default:
3588       abort ();
3589     }
3590 }
3591   [(set_attr "type" "fmov")
3592    (set_attr "mode" "SF,XF")])
3593
3594 (define_expand "extenddfxf2"
3595   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3596         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3597   "TARGET_80387"
3598 {
3599   /* ??? Needed for compress_float_constant since all fp constants
3600      are LEGITIMATE_CONSTANT_P.  */
3601   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3602     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3603   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3604     operands[1] = force_reg (DFmode, operands[1]);
3605 })
3606
3607 (define_insn "*extenddfxf2_i387"
3608   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3609         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3610   "TARGET_80387
3611    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3612 {
3613   switch (which_alternative)
3614     {
3615     case 0:
3616       return output_387_reg_move (insn, operands);
3617
3618     case 1:
3619       /* There is no non-popping store to memory for XFmode.  So if
3620          we need one, follow the store with a load.  */
3621       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3622         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3623       else
3624         return "fstp%z0\t%y0";
3625
3626     default:
3627       abort ();
3628     }
3629 }
3630   [(set_attr "type" "fmov")
3631    (set_attr "mode" "DF,XF")])
3632
3633 ;; %%% This seems bad bad news.
3634 ;; This cannot output into an f-reg because there is no way to be sure
3635 ;; of truncating in that case.  Otherwise this is just like a simple move
3636 ;; insn.  So we pretend we can output to a reg in order to get better
3637 ;; register preferencing, but we really use a stack slot.
3638
3639 ;; Conversion from DFmode to SFmode.
3640
3641 (define_expand "truncdfsf2"
3642   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3643         (float_truncate:SF
3644           (match_operand:DF 1 "nonimmediate_operand" "")))]
3645   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3646 {
3647   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3648     operands[1] = force_reg (DFmode, operands[1]);
3649
3650   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3651     ;
3652   else if (flag_unsafe_math_optimizations)
3653     ;
3654   else
3655     {
3656       rtx temp = assign_386_stack_local (SFmode, 0);
3657       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3658       DONE;
3659     }
3660 })
3661
3662 (define_expand "truncdfsf2_with_temp"
3663   [(parallel [(set (match_operand:SF 0 "" "")
3664                    (float_truncate:SF (match_operand:DF 1 "" "")))
3665               (clobber (match_operand:SF 2 "" ""))])]
3666   "")
3667
3668 (define_insn "*truncdfsf_fast_mixed"
3669   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3670         (float_truncate:SF
3671           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3672   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3673 {
3674   switch (which_alternative)
3675     {
3676     case 0:
3677       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3678         return "fstp%z0\t%y0";
3679       else
3680         return "fst%z0\t%y0";
3681     case 1:
3682       return output_387_reg_move (insn, operands);
3683     case 2:
3684       return "cvtsd2ss\t{%1, %0|%0, %1}";
3685     default:
3686       abort ();
3687     }
3688 }
3689   [(set_attr "type" "fmov,fmov,ssecvt")
3690    (set_attr "mode" "SF")])
3691
3692 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3693 ;; because nothing we do here is unsafe.
3694 (define_insn "*truncdfsf_fast_sse"
3695   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3696         (float_truncate:SF
3697           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3698   "TARGET_SSE2 && TARGET_SSE_MATH"
3699   "cvtsd2ss\t{%1, %0|%0, %1}"
3700   [(set_attr "type" "ssecvt")
3701    (set_attr "mode" "SF")])
3702
3703 (define_insn "*truncdfsf_fast_i387"
3704   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3705         (float_truncate:SF
3706           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3707   "TARGET_80387 && flag_unsafe_math_optimizations"
3708   "* return output_387_reg_move (insn, operands);"
3709   [(set_attr "type" "fmov")
3710    (set_attr "mode" "SF")])
3711
3712 (define_insn "*truncdfsf_mixed"
3713   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3714         (float_truncate:SF
3715           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3716    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3717   "TARGET_MIX_SSE_I387"
3718 {
3719   switch (which_alternative)
3720     {
3721     case 0:
3722       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3723         return "fstp%z0\t%y0";
3724       else
3725         return "fst%z0\t%y0";
3726     case 1:
3727       return "#";
3728     case 2:
3729       return "cvtsd2ss\t{%1, %0|%0, %1}";
3730     default:
3731       abort ();
3732     }
3733 }
3734   [(set_attr "type" "fmov,multi,ssecvt")
3735    (set_attr "mode" "SF")])
3736
3737 (define_insn "*truncdfsf_i387"
3738   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3739         (float_truncate:SF
3740           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3741    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3742   "TARGET_80387"
3743 {
3744   switch (which_alternative)
3745     {
3746     case 0:
3747       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3748         return "fstp%z0\t%y0";
3749       else
3750         return "fst%z0\t%y0";
3751     case 1:
3752       return "#";
3753     default:
3754       abort ();
3755     }
3756 }
3757   [(set_attr "type" "fmov,multi")
3758    (set_attr "mode" "SF")])
3759
3760 (define_split
3761   [(set (match_operand:SF 0 "register_operand" "")
3762         (float_truncate:SF
3763          (match_operand:DF 1 "fp_register_operand" "")))
3764    (clobber (match_operand 2 "" ""))]
3765   "reload_completed"
3766   [(set (match_dup 2) (match_dup 1))
3767    (set (match_dup 0) (match_dup 2))]
3768 {
3769   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3770 })
3771
3772 ;; Conversion from XFmode to SFmode.
3773
3774 (define_expand "truncxfsf2"
3775   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3776                    (float_truncate:SF
3777                     (match_operand:XF 1 "register_operand" "")))
3778               (clobber (match_dup 2))])]
3779   "TARGET_80387"
3780 {
3781   if (flag_unsafe_math_optimizations)
3782     {
3783       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3784       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3785       if (reg != operands[0])
3786         emit_move_insn (operands[0], reg);
3787       DONE;
3788     }
3789   else
3790     operands[2] = assign_386_stack_local (SFmode, 0);
3791 })
3792
3793 (define_insn "*truncxfsf2_mixed"
3794   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3795         (float_truncate:SF
3796          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3797    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3798   "TARGET_MIX_SSE_I387"
3799 {
3800   switch (which_alternative)
3801     {
3802     case 0:
3803       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3804         return "fstp%z0\t%y0";
3805       else
3806         return "fst%z0\t%y0";
3807     default:
3808       abort();
3809     }
3810 }
3811   [(set_attr "type" "fmov,multi,multi,multi")
3812    (set_attr "mode" "SF")])
3813
3814 (define_insn "truncxfsf2_i387_noop"
3815   [(set (match_operand:SF 0 "register_operand" "=f")
3816         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3817   "TARGET_80387 && flag_unsafe_math_optimizations"
3818 {
3819   return output_387_reg_move (insn, operands);
3820 }
3821   [(set_attr "type" "fmov")
3822    (set_attr "mode" "SF")])
3823
3824 (define_insn "*truncxfsf2_i387"
3825   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3826         (float_truncate:SF
3827          (match_operand:XF 1 "register_operand" "f,f,f")))
3828    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3829   "TARGET_80387"
3830 {
3831   switch (which_alternative)
3832     {
3833     case 0:
3834       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3835         return "fstp%z0\t%y0";
3836       else
3837         return "fst%z0\t%y0";
3838     default:
3839       abort ();
3840     }
3841 }
3842   [(set_attr "type" "fmov,multi,multi")
3843    (set_attr "mode" "SF")])
3844
3845 (define_insn "*truncxfsf2_i387_1"
3846   [(set (match_operand:SF 0 "memory_operand" "=m")
3847         (float_truncate:SF
3848          (match_operand:XF 1 "register_operand" "f")))]
3849   "TARGET_80387"
3850 {
3851   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3852     return "fstp%z0\t%y0";
3853   else
3854     return "fst%z0\t%y0";
3855 }
3856   [(set_attr "type" "fmov")
3857    (set_attr "mode" "SF")])
3858
3859 (define_split
3860   [(set (match_operand:SF 0 "register_operand" "")
3861         (float_truncate:SF
3862          (match_operand:XF 1 "register_operand" "")))
3863    (clobber (match_operand:SF 2 "memory_operand" ""))]
3864   "TARGET_80387 && reload_completed"
3865   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3866    (set (match_dup 0) (match_dup 2))]
3867   "")
3868
3869 (define_split
3870   [(set (match_operand:SF 0 "memory_operand" "")
3871         (float_truncate:SF
3872          (match_operand:XF 1 "register_operand" "")))
3873    (clobber (match_operand:SF 2 "memory_operand" ""))]
3874   "TARGET_80387"
3875   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3876   "")
3877
3878 ;; Conversion from XFmode to DFmode.
3879
3880 (define_expand "truncxfdf2"
3881   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3882                    (float_truncate:DF
3883                     (match_operand:XF 1 "register_operand" "")))
3884               (clobber (match_dup 2))])]
3885   "TARGET_80387"
3886 {
3887   if (flag_unsafe_math_optimizations)
3888     {
3889       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3890       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3891       if (reg != operands[0])
3892         emit_move_insn (operands[0], reg);
3893       DONE;
3894     }
3895   else
3896     operands[2] = assign_386_stack_local (DFmode, 0);
3897 })
3898
3899 (define_insn "*truncxfdf2_mixed"
3900   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3901         (float_truncate:DF
3902          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3903    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3904   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3905 {
3906   switch (which_alternative)
3907     {
3908     case 0:
3909       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3910         return "fstp%z0\t%y0";
3911       else
3912         return "fst%z0\t%y0";
3913     default:
3914       abort();
3915     }
3916   abort ();
3917 }
3918   [(set_attr "type" "fmov,multi,multi,multi")
3919    (set_attr "mode" "DF")])
3920
3921 (define_insn "truncxfdf2_i387_noop"
3922   [(set (match_operand:DF 0 "register_operand" "=f")
3923         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3924   "TARGET_80387 && flag_unsafe_math_optimizations"
3925 {
3926   return output_387_reg_move (insn, operands);
3927 }
3928   [(set_attr "type" "fmov")
3929    (set_attr "mode" "DF")])
3930
3931 (define_insn "*truncxfdf2_i387"
3932   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3933         (float_truncate:DF
3934          (match_operand:XF 1 "register_operand" "f,f,f")))
3935    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3936   "TARGET_80387"
3937 {
3938   switch (which_alternative)
3939     {
3940     case 0:
3941       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3942         return "fstp%z0\t%y0";
3943       else
3944         return "fst%z0\t%y0";
3945     default:
3946       abort ();
3947     }
3948 }
3949   [(set_attr "type" "fmov,multi,multi")
3950    (set_attr "mode" "DF")])
3951
3952 (define_insn "*truncxfdf2_i387_1"
3953   [(set (match_operand:DF 0 "memory_operand" "=m")
3954         (float_truncate:DF
3955           (match_operand:XF 1 "register_operand" "f")))]
3956   "TARGET_80387"
3957 {
3958   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3959     return "fstp%z0\t%y0";
3960   else
3961     return "fst%z0\t%y0";
3962 }
3963   [(set_attr "type" "fmov")
3964    (set_attr "mode" "DF")])
3965
3966 (define_split
3967   [(set (match_operand:DF 0 "register_operand" "")
3968         (float_truncate:DF
3969          (match_operand:XF 1 "register_operand" "")))
3970    (clobber (match_operand:DF 2 "memory_operand" ""))]
3971   "TARGET_80387 && reload_completed"
3972   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3973    (set (match_dup 0) (match_dup 2))]
3974   "")
3975
3976 (define_split
3977   [(set (match_operand:DF 0 "memory_operand" "")
3978         (float_truncate:DF
3979          (match_operand:XF 1 "register_operand" "")))
3980    (clobber (match_operand:DF 2 "memory_operand" ""))]
3981   "TARGET_80387"
3982   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3983   "")
3984 \f
3985 ;; %%% Break up all these bad boys.
3986
3987 ;; Signed conversion to DImode.
3988
3989 (define_expand "fix_truncxfdi2"
3990   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3991                    (fix:DI (match_operand:XF 1 "register_operand" "")))
3992               (clobber (reg:CC FLAGS_REG))])]
3993   "TARGET_80387"
3994   "")
3995
3996 (define_expand "fix_truncdfdi2"
3997   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3998                    (fix:DI (match_operand:DF 1 "register_operand" "")))
3999               (clobber (reg:CC FLAGS_REG))])]
4000   "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4001 {
4002   if (TARGET_64BIT && TARGET_SSE2)
4003    {
4004      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4005      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4006      if (out != operands[0])
4007         emit_move_insn (operands[0], out);
4008      DONE;
4009    }
4010 })
4011
4012 (define_expand "fix_truncsfdi2"
4013   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4014                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4015               (clobber (reg:CC FLAGS_REG))])] 
4016   "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4017 {
4018   if (TARGET_SSE && TARGET_64BIT)
4019    {
4020      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4021      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4022      if (out != operands[0])
4023         emit_move_insn (operands[0], out);
4024      DONE;
4025    }
4026 })
4027
4028 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4029 ;; of the machinery.
4030 (define_insn_and_split "*fix_truncdi_1"
4031   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4032         (fix:DI (match_operand 1 "register_operand" "f,f")))
4033    (clobber (reg:CC FLAGS_REG))]
4034   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4035    && !reload_completed && !reload_in_progress
4036    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4037   "#"
4038   "&& 1"
4039   [(const_int 0)]
4040 {
4041   ix86_optimize_mode_switching = 1;
4042   operands[2] = assign_386_stack_local (HImode, 1);
4043   operands[3] = assign_386_stack_local (HImode, 2);
4044   if (memory_operand (operands[0], VOIDmode))
4045     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4046                                        operands[2], operands[3]));
4047   else
4048     {
4049       operands[4] = assign_386_stack_local (DImode, 0);
4050       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4051                                            operands[2], operands[3],
4052                                            operands[4]));
4053     }
4054   DONE;
4055 }
4056   [(set_attr "type" "fistp")
4057    (set_attr "i387_cw" "trunc")
4058    (set_attr "mode" "DI")])
4059
4060 (define_insn "fix_truncdi_nomemory"
4061   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4062         (fix:DI (match_operand 1 "register_operand" "f,f")))
4063    (use (match_operand:HI 2 "memory_operand" "m,m"))
4064    (use (match_operand:HI 3 "memory_operand" "m,m"))
4065    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4066    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4067   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4068    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4069   "#"
4070   [(set_attr "type" "fistp")
4071    (set_attr "i387_cw" "trunc")
4072    (set_attr "mode" "DI")])
4073
4074 (define_insn "fix_truncdi_memory"
4075   [(set (match_operand:DI 0 "memory_operand" "=m")
4076         (fix:DI (match_operand 1 "register_operand" "f")))
4077    (use (match_operand:HI 2 "memory_operand" "m"))
4078    (use (match_operand:HI 3 "memory_operand" "m"))
4079    (clobber (match_scratch:DF 4 "=&1f"))]
4080   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4081    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4082   "* return output_fix_trunc (insn, operands);"
4083   [(set_attr "type" "fistp")
4084    (set_attr "i387_cw" "trunc")
4085    (set_attr "mode" "DI")])
4086
4087 (define_split 
4088   [(set (match_operand:DI 0 "register_operand" "")
4089         (fix:DI (match_operand 1 "register_operand" "")))
4090    (use (match_operand:HI 2 "memory_operand" ""))
4091    (use (match_operand:HI 3 "memory_operand" ""))
4092    (clobber (match_operand:DI 4 "memory_operand" ""))
4093    (clobber (match_scratch 5 ""))]
4094   "reload_completed"
4095   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4096               (use (match_dup 2))
4097               (use (match_dup 3))
4098               (clobber (match_dup 5))])
4099    (set (match_dup 0) (match_dup 4))]
4100   "")
4101
4102 (define_split 
4103   [(set (match_operand:DI 0 "memory_operand" "")
4104         (fix:DI (match_operand 1 "register_operand" "")))
4105    (use (match_operand:HI 2 "memory_operand" ""))
4106    (use (match_operand:HI 3 "memory_operand" ""))
4107    (clobber (match_operand:DI 4 "memory_operand" ""))
4108    (clobber (match_scratch 5 ""))]
4109   "reload_completed"
4110   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4111               (use (match_dup 2))
4112               (use (match_dup 3))
4113               (clobber (match_dup 5))])]
4114   "")
4115
4116 ;; When SSE available, it is always faster to use it!
4117 (define_insn "fix_truncsfdi_sse"
4118   [(set (match_operand:DI 0 "register_operand" "=r,r")
4119         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4120   "TARGET_64BIT && TARGET_SSE"
4121   "cvttss2si{q}\t{%1, %0|%0, %1}"
4122   [(set_attr "type" "sseicvt")
4123    (set_attr "mode" "SF")
4124    (set_attr "athlon_decode" "double,vector")])
4125
4126 ;; Avoid vector decoded form of the instruction.
4127 (define_peephole2
4128   [(match_scratch:SF 2 "x")
4129    (set (match_operand:DI 0 "register_operand" "")
4130         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4131   "TARGET_K8 && !optimize_size"
4132   [(set (match_dup 2) (match_dup 1))
4133    (set (match_dup 0) (fix:DI (match_dup 2)))]
4134   "")
4135
4136 (define_insn "fix_truncdfdi_sse"
4137   [(set (match_operand:DI 0 "register_operand" "=r,r")
4138         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4139   "TARGET_64BIT && TARGET_SSE2"
4140   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4141   [(set_attr "type" "sseicvt,sseicvt")
4142    (set_attr "mode" "DF")
4143    (set_attr "athlon_decode" "double,vector")])
4144
4145 ;; Avoid vector decoded form of the instruction.
4146 (define_peephole2
4147   [(match_scratch:DF 2 "Y")
4148    (set (match_operand:DI 0 "register_operand" "")
4149         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4150   "TARGET_K8 && !optimize_size"
4151   [(set (match_dup 2) (match_dup 1))
4152    (set (match_dup 0) (fix:DI (match_dup 2)))]
4153   "")
4154
4155 ;; Signed conversion to SImode.
4156
4157 (define_expand "fix_truncxfsi2"
4158   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4159                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4160               (clobber (reg:CC FLAGS_REG))])]
4161   "TARGET_80387"
4162   "")
4163
4164 (define_expand "fix_truncdfsi2"
4165   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4166                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4167               (clobber (reg:CC FLAGS_REG))])]
4168   "TARGET_80387 || TARGET_SSE2"
4169 {
4170   if (TARGET_SSE2)
4171    {
4172      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4173      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4174      if (out != operands[0])
4175         emit_move_insn (operands[0], out);
4176      DONE;
4177    }
4178 })
4179
4180 (define_expand "fix_truncsfsi2"
4181   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4182                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4183               (clobber (reg:CC FLAGS_REG))])] 
4184   "TARGET_80387 || TARGET_SSE"
4185 {
4186   if (TARGET_SSE)
4187    {
4188      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4189      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4190      if (out != operands[0])
4191         emit_move_insn (operands[0], out);
4192      DONE;
4193    }
4194 })
4195
4196 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4197 ;; of the machinery.
4198 (define_insn_and_split "*fix_truncsi_1"
4199   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4200         (fix:SI (match_operand 1 "register_operand" "f,f")))
4201    (clobber (reg:CC FLAGS_REG))]
4202   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4203    && !reload_completed && !reload_in_progress
4204    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4205   "#"
4206   "&& 1"
4207   [(const_int 0)]
4208 {
4209   ix86_optimize_mode_switching = 1;
4210   operands[2] = assign_386_stack_local (HImode, 1);
4211   operands[3] = assign_386_stack_local (HImode, 2);
4212   if (memory_operand (operands[0], VOIDmode))
4213     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4214                                        operands[2], operands[3]));
4215   else
4216     {
4217       operands[4] = assign_386_stack_local (SImode, 0);
4218       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4219                                            operands[2], operands[3],
4220                                            operands[4]));
4221     }
4222   DONE;
4223 }
4224   [(set_attr "type" "fistp")
4225    (set_attr "i387_cw" "trunc")
4226    (set_attr "mode" "SI")])
4227
4228 (define_insn "fix_truncsi_nomemory"
4229   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4230         (fix:SI (match_operand 1 "register_operand" "f,f")))
4231    (use (match_operand:HI 2 "memory_operand" "m,m"))
4232    (use (match_operand:HI 3 "memory_operand" "m,m"))
4233    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4234   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4235    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4236   "#"
4237   [(set_attr "type" "fistp")
4238    (set_attr "i387_cw" "trunc")
4239    (set_attr "mode" "SI")])
4240
4241 (define_insn "fix_truncsi_memory"
4242   [(set (match_operand:SI 0 "memory_operand" "=m")
4243         (fix:SI (match_operand 1 "register_operand" "f")))
4244    (use (match_operand:HI 2 "memory_operand" "m"))
4245    (use (match_operand:HI 3 "memory_operand" "m"))]
4246   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4247    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4248   "* return output_fix_trunc (insn, operands);"
4249   [(set_attr "type" "fistp")
4250    (set_attr "i387_cw" "trunc")
4251    (set_attr "mode" "SI")])
4252
4253 ;; When SSE available, it is always faster to use it!
4254 (define_insn "fix_truncsfsi_sse"
4255   [(set (match_operand:SI 0 "register_operand" "=r,r")
4256         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4257   "TARGET_SSE"
4258   "cvttss2si\t{%1, %0|%0, %1}"
4259   [(set_attr "type" "sseicvt")
4260    (set_attr "mode" "DF")
4261    (set_attr "athlon_decode" "double,vector")])
4262
4263 ;; Avoid vector decoded form of the instruction.
4264 (define_peephole2
4265   [(match_scratch:SF 2 "x")
4266    (set (match_operand:SI 0 "register_operand" "")
4267         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4268   "TARGET_K8 && !optimize_size"
4269   [(set (match_dup 2) (match_dup 1))
4270    (set (match_dup 0) (fix:SI (match_dup 2)))]
4271   "")
4272
4273 (define_insn "fix_truncdfsi_sse"
4274   [(set (match_operand:SI 0 "register_operand" "=r,r")
4275         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4276   "TARGET_SSE2"
4277   "cvttsd2si\t{%1, %0|%0, %1}"
4278   [(set_attr "type" "sseicvt")
4279    (set_attr "mode" "DF")
4280    (set_attr "athlon_decode" "double,vector")])
4281
4282 ;; Avoid vector decoded form of the instruction.
4283 (define_peephole2
4284   [(match_scratch:DF 2 "Y")
4285    (set (match_operand:SI 0 "register_operand" "")
4286         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4287   "TARGET_K8 && !optimize_size"
4288   [(set (match_dup 2) (match_dup 1))
4289    (set (match_dup 0) (fix:SI (match_dup 2)))]
4290   "")
4291
4292 (define_split 
4293   [(set (match_operand:SI 0 "register_operand" "")
4294         (fix:SI (match_operand 1 "register_operand" "")))
4295    (use (match_operand:HI 2 "memory_operand" ""))
4296    (use (match_operand:HI 3 "memory_operand" ""))
4297    (clobber (match_operand:SI 4 "memory_operand" ""))]
4298   "reload_completed"
4299   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4300               (use (match_dup 2))
4301               (use (match_dup 3))])
4302    (set (match_dup 0) (match_dup 4))]
4303   "")
4304
4305 (define_split 
4306   [(set (match_operand:SI 0 "memory_operand" "")
4307         (fix:SI (match_operand 1 "register_operand" "")))
4308    (use (match_operand:HI 2 "memory_operand" ""))
4309    (use (match_operand:HI 3 "memory_operand" ""))
4310    (clobber (match_operand:SI 4 "memory_operand" ""))]
4311   "reload_completed"
4312   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4313               (use (match_dup 2))
4314               (use (match_dup 3))])]
4315   "")
4316
4317 ;; Signed conversion to HImode.
4318
4319 (define_expand "fix_truncxfhi2"
4320   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4321                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4322               (clobber (reg:CC FLAGS_REG))])] 
4323   "TARGET_80387"
4324   "")
4325
4326 (define_expand "fix_truncdfhi2"
4327   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4328                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4329               (clobber (reg:CC FLAGS_REG))])]
4330   "TARGET_80387 && !TARGET_SSE2"
4331   "")
4332
4333 (define_expand "fix_truncsfhi2"
4334   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4335                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4336                (clobber (reg:CC FLAGS_REG))])]
4337   "TARGET_80387 && !TARGET_SSE"
4338   "")
4339
4340 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4341 ;; of the machinery.
4342 (define_insn_and_split "*fix_trunchi_1"
4343   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4344         (fix:HI (match_operand 1 "register_operand" "f,f")))
4345    (clobber (reg:CC FLAGS_REG))]
4346   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4347    && !reload_completed && !reload_in_progress
4348    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4349   "#"
4350   "&& 1"
4351   [(const_int 0)]
4352 {
4353   ix86_optimize_mode_switching = 1;
4354   operands[2] = assign_386_stack_local (HImode, 1);
4355   operands[3] = assign_386_stack_local (HImode, 2);
4356   if (memory_operand (operands[0], VOIDmode))
4357     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4358                                        operands[2], operands[3]));
4359   else
4360     {
4361       operands[4] = assign_386_stack_local (HImode, 0);
4362       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4363                                            operands[2], operands[3],
4364                                            operands[4]));
4365     }
4366   DONE;
4367 }
4368   [(set_attr "type" "fistp")
4369    (set_attr "i387_cw" "trunc")
4370    (set_attr "mode" "HI")])
4371
4372 (define_insn "fix_trunchi_nomemory"
4373   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4374         (fix:HI (match_operand 1 "register_operand" "f,f")))
4375    (use (match_operand:HI 2 "memory_operand" "m,m"))
4376    (use (match_operand:HI 3 "memory_operand" "m,m"))
4377    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4378   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4379    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4380   "#"
4381   [(set_attr "type" "fistp")
4382    (set_attr "i387_cw" "trunc")
4383    (set_attr "mode" "HI")])
4384
4385 (define_insn "fix_trunchi_memory"
4386   [(set (match_operand:HI 0 "memory_operand" "=m")
4387         (fix:HI (match_operand 1 "register_operand" "f")))
4388    (use (match_operand:HI 2 "memory_operand" "m"))
4389    (use (match_operand:HI 3 "memory_operand" "m"))]
4390   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4391    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4392   "* return output_fix_trunc (insn, operands);"
4393   [(set_attr "type" "fistp")
4394    (set_attr "i387_cw" "trunc")
4395    (set_attr "mode" "HI")])
4396
4397 (define_split 
4398   [(set (match_operand:HI 0 "memory_operand" "")
4399         (fix:HI (match_operand 1 "register_operand" "")))
4400    (use (match_operand:HI 2 "memory_operand" ""))
4401    (use (match_operand:HI 3 "memory_operand" ""))
4402    (clobber (match_operand:HI 4 "memory_operand" ""))]
4403   "reload_completed"
4404   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4405               (use (match_dup 2))
4406               (use (match_dup 3))])]
4407   "")
4408
4409 (define_split 
4410   [(set (match_operand:HI 0 "register_operand" "")
4411         (fix:HI (match_operand 1 "register_operand" "")))
4412    (use (match_operand:HI 2 "memory_operand" ""))
4413    (use (match_operand:HI 3 "memory_operand" ""))
4414    (clobber (match_operand:HI 4 "memory_operand" ""))]
4415   "reload_completed"
4416   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4417               (use (match_dup 2))
4418               (use (match_dup 3))
4419               (clobber (match_dup 4))])
4420    (set (match_dup 0) (match_dup 4))]
4421   "")
4422
4423 (define_insn "x86_fnstcw_1"
4424   [(set (match_operand:HI 0 "memory_operand" "=m")
4425         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4426   "TARGET_80387"
4427   "fnstcw\t%0"
4428   [(set_attr "length" "2")
4429    (set_attr "mode" "HI")
4430    (set_attr "unit" "i387")])
4431
4432 (define_insn "x86_fldcw_1"
4433   [(set (reg:HI FPSR_REG)
4434         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4435   "TARGET_80387"
4436   "fldcw\t%0"
4437   [(set_attr "length" "2")
4438    (set_attr "mode" "HI")
4439    (set_attr "unit" "i387")
4440    (set_attr "athlon_decode" "vector")])
4441 \f
4442 ;; Conversion between fixed point and floating point.
4443
4444 ;; Even though we only accept memory inputs, the backend _really_
4445 ;; wants to be able to do this between registers.
4446
4447 (define_expand "floathisf2"
4448   [(set (match_operand:SF 0 "register_operand" "")
4449         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4450   "TARGET_80387 || TARGET_SSE_MATH"
4451 {
4452   if (TARGET_SSE_MATH)
4453     {
4454       emit_insn (gen_floatsisf2 (operands[0],
4455                                  convert_to_mode (SImode, operands[1], 0)));
4456       DONE;
4457     }
4458 })
4459
4460 (define_insn "*floathisf2_i387"
4461   [(set (match_operand:SF 0 "register_operand" "=f,f")
4462         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4463   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4464   "@
4465    fild%z1\t%1
4466    #"
4467   [(set_attr "type" "fmov,multi")
4468    (set_attr "mode" "SF")
4469    (set_attr "fp_int_src" "true")])
4470
4471 (define_expand "floatsisf2"
4472   [(set (match_operand:SF 0 "register_operand" "")
4473         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4474   "TARGET_80387 || TARGET_SSE_MATH"
4475   "")
4476
4477 (define_insn "*floatsisf2_mixed"
4478   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4479         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4480   "TARGET_MIX_SSE_I387"
4481   "@
4482    fild%z1\t%1
4483    #
4484    cvtsi2ss\t{%1, %0|%0, %1}
4485    cvtsi2ss\t{%1, %0|%0, %1}"
4486   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4487    (set_attr "mode" "SF")
4488    (set_attr "athlon_decode" "*,*,vector,double")
4489    (set_attr "fp_int_src" "true")])
4490
4491 (define_insn "*floatsisf2_sse"
4492   [(set (match_operand:SF 0 "register_operand" "=x,x")
4493         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4494   "TARGET_SSE_MATH"
4495   "cvtsi2ss\t{%1, %0|%0, %1}"
4496   [(set_attr "type" "sseicvt")
4497    (set_attr "mode" "SF")
4498    (set_attr "athlon_decode" "vector,double")
4499    (set_attr "fp_int_src" "true")])
4500
4501 (define_insn "*floatsisf2_i387"
4502   [(set (match_operand:SF 0 "register_operand" "=f,f")
4503         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4504   "TARGET_80387"
4505   "@
4506    fild%z1\t%1
4507    #"
4508   [(set_attr "type" "fmov,multi")
4509    (set_attr "mode" "SF")
4510    (set_attr "fp_int_src" "true")])
4511
4512 (define_expand "floatdisf2"
4513   [(set (match_operand:SF 0 "register_operand" "")
4514         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4515   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4516   "")
4517
4518 (define_insn "*floatdisf2_mixed"
4519   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4520         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4521   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4522   "@
4523    fild%z1\t%1
4524    #
4525    cvtsi2ss{q}\t{%1, %0|%0, %1}
4526    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4527   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4528    (set_attr "mode" "SF")
4529    (set_attr "athlon_decode" "*,*,vector,double")
4530    (set_attr "fp_int_src" "true")])
4531
4532 (define_insn "*floatdisf2_sse"
4533   [(set (match_operand:SF 0 "register_operand" "=x,x")
4534         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4535   "TARGET_64BIT && TARGET_SSE_MATH"
4536   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4537   [(set_attr "type" "sseicvt")
4538    (set_attr "mode" "SF")
4539    (set_attr "athlon_decode" "vector,double")
4540    (set_attr "fp_int_src" "true")])
4541
4542 (define_insn "*floatdisf2_i387"
4543   [(set (match_operand:SF 0 "register_operand" "=f,f")
4544         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4545   "TARGET_80387"
4546   "@
4547    fild%z1\t%1
4548    #"
4549   [(set_attr "type" "fmov,multi")
4550    (set_attr "mode" "SF")
4551    (set_attr "fp_int_src" "true")])
4552
4553 (define_expand "floathidf2"
4554   [(set (match_operand:DF 0 "register_operand" "")
4555         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4556   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4557 {
4558   if (TARGET_SSE2 && TARGET_SSE_MATH)
4559     {
4560       emit_insn (gen_floatsidf2 (operands[0],
4561                                  convert_to_mode (SImode, operands[1], 0)));
4562       DONE;
4563     }
4564 })
4565
4566 (define_insn "*floathidf2_i387"
4567   [(set (match_operand:DF 0 "register_operand" "=f,f")
4568         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4569   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4570   "@
4571    fild%z1\t%1
4572    #"
4573   [(set_attr "type" "fmov,multi")
4574    (set_attr "mode" "DF")
4575    (set_attr "fp_int_src" "true")])
4576
4577 (define_expand "floatsidf2"
4578   [(set (match_operand:DF 0 "register_operand" "")
4579         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4580   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4581   "")
4582
4583 (define_insn "*floatsidf2_mixed"
4584   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4585         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4586   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4587   "@
4588    fild%z1\t%1
4589    #
4590    cvtsi2sd\t{%1, %0|%0, %1}
4591    cvtsi2sd\t{%1, %0|%0, %1}"
4592   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4593    (set_attr "mode" "DF")
4594    (set_attr "athlon_decode" "*,*,double,direct")
4595    (set_attr "fp_int_src" "true")])
4596
4597 (define_insn "*floatsidf2_sse"
4598   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4599         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4600   "TARGET_SSE2 && TARGET_SSE_MATH"
4601   "cvtsi2sd\t{%1, %0|%0, %1}"
4602   [(set_attr "type" "sseicvt")
4603    (set_attr "mode" "DF")
4604    (set_attr "athlon_decode" "double,direct")
4605    (set_attr "fp_int_src" "true")])
4606
4607 (define_insn "*floatsidf2_i387"
4608   [(set (match_operand:DF 0 "register_operand" "=f,f")
4609         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4610   "TARGET_80387"
4611   "@
4612    fild%z1\t%1
4613    #"
4614   [(set_attr "type" "fmov,multi")
4615    (set_attr "mode" "DF")
4616    (set_attr "fp_int_src" "true")])
4617
4618 (define_expand "floatdidf2"
4619   [(set (match_operand:DF 0 "register_operand" "")
4620         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4621   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4622   "")
4623
4624 (define_insn "*floatdidf2_mixed"
4625   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4626         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4627   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4628   "@
4629    fild%z1\t%1
4630    #
4631    cvtsi2sd{q}\t{%1, %0|%0, %1}
4632    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4633   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4634    (set_attr "mode" "DF")
4635    (set_attr "athlon_decode" "*,*,double,direct")
4636    (set_attr "fp_int_src" "true")])
4637
4638 (define_insn "*floatdidf2_sse"
4639   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4640         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4641   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4642   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4643   [(set_attr "type" "sseicvt")
4644    (set_attr "mode" "DF")
4645    (set_attr "athlon_decode" "double,direct")
4646    (set_attr "fp_int_src" "true")])
4647
4648 (define_insn "*floatdidf2_i387"
4649   [(set (match_operand:DF 0 "register_operand" "=f,f")
4650         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4651   "TARGET_80387"
4652   "@
4653    fild%z1\t%1
4654    #"
4655   [(set_attr "type" "fmov,multi")
4656    (set_attr "mode" "DF")
4657    (set_attr "fp_int_src" "true")])
4658
4659 (define_insn "floathixf2"
4660   [(set (match_operand:XF 0 "register_operand" "=f,f")
4661         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4662   "TARGET_80387"
4663   "@
4664    fild%z1\t%1
4665    #"
4666   [(set_attr "type" "fmov,multi")
4667    (set_attr "mode" "XF")
4668    (set_attr "fp_int_src" "true")])
4669
4670 (define_insn "floatsixf2"
4671   [(set (match_operand:XF 0 "register_operand" "=f,f")
4672         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4673   "TARGET_80387"
4674   "@
4675    fild%z1\t%1
4676    #"
4677   [(set_attr "type" "fmov,multi")
4678    (set_attr "mode" "XF")
4679    (set_attr "fp_int_src" "true")])
4680
4681 (define_insn "floatdixf2"
4682   [(set (match_operand:XF 0 "register_operand" "=f,f")
4683         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4684   "TARGET_80387"
4685   "@
4686    fild%z1\t%1
4687    #"
4688   [(set_attr "type" "fmov,multi")
4689    (set_attr "mode" "XF")
4690    (set_attr "fp_int_src" "true")])
4691
4692 ;; %%% Kill these when reload knows how to do it.
4693 (define_split
4694   [(set (match_operand 0 "fp_register_operand" "")
4695         (float (match_operand 1 "register_operand" "")))]
4696   "reload_completed
4697    && TARGET_80387
4698    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4699   [(const_int 0)]
4700 {
4701   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4702   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4703   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4704   ix86_free_from_memory (GET_MODE (operands[1]));
4705   DONE;
4706 })
4707
4708 (define_expand "floatunssisf2"
4709   [(use (match_operand:SF 0 "register_operand" ""))
4710    (use (match_operand:SI 1 "register_operand" ""))]
4711   "!TARGET_64BIT && TARGET_SSE_MATH"
4712   "x86_emit_floatuns (operands); DONE;")
4713
4714 (define_expand "floatunsdisf2"
4715   [(use (match_operand:SF 0 "register_operand" ""))
4716    (use (match_operand:DI 1 "register_operand" ""))]
4717   "TARGET_64BIT && TARGET_SSE_MATH"
4718   "x86_emit_floatuns (operands); DONE;")
4719
4720 (define_expand "floatunsdidf2"
4721   [(use (match_operand:DF 0 "register_operand" ""))
4722    (use (match_operand:DI 1 "register_operand" ""))]
4723   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4724   "x86_emit_floatuns (operands); DONE;")
4725 \f
4726 ;; SSE extract/set expanders
4727
4728 (define_expand "vec_setv2df"
4729   [(match_operand:V2DF 0 "register_operand" "")
4730    (match_operand:DF 1 "register_operand" "")
4731    (match_operand 2 "const_int_operand" "")]
4732   "TARGET_SSE2"
4733 {
4734   switch (INTVAL (operands[2]))
4735     {
4736     case 0:
4737       emit_insn (gen_sse2_movsd (operands[0], operands[0],
4738                                  simplify_gen_subreg (V2DFmode, operands[1],
4739                                                       DFmode, 0)));
4740       break;
4741     case 1:
4742       {
4743         rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4744
4745         emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4746       }
4747       break;
4748     default:
4749       abort ();
4750     }
4751   DONE;
4752 })
4753
4754 (define_expand "vec_extractv2df"
4755   [(match_operand:DF 0 "register_operand" "")
4756    (match_operand:V2DF 1 "register_operand" "")
4757    (match_operand 2 "const_int_operand" "")]
4758   "TARGET_SSE2"
4759 {
4760   switch (INTVAL (operands[2]))
4761     {
4762     case 0:
4763       emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4764       break;
4765     case 1:
4766       {
4767         rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4768
4769         emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4770       }
4771       break;
4772     default:
4773       abort ();
4774     }
4775   DONE;
4776 })
4777
4778 (define_expand "vec_initv2df"
4779   [(match_operand:V2DF 0 "register_operand" "")
4780    (match_operand 1 "" "")]
4781   "TARGET_SSE2"
4782 {
4783   ix86_expand_vector_init (operands[0], operands[1]);
4784   DONE;
4785 })
4786
4787 (define_expand "vec_setv4sf"
4788   [(match_operand:V4SF 0 "register_operand" "")
4789    (match_operand:SF 1 "register_operand" "")
4790    (match_operand 2 "const_int_operand" "")]
4791   "TARGET_SSE"
4792 {
4793   switch (INTVAL (operands[2]))
4794     {
4795     case 0:
4796       emit_insn (gen_sse_movss (operands[0], operands[0],
4797                                 simplify_gen_subreg (V4SFmode, operands[1],
4798                                                      SFmode, 0)));
4799       break;
4800     case 1:
4801       {
4802         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4803         rtx tmp = gen_reg_rtx (V4SFmode);
4804  
4805         emit_move_insn (tmp, operands[0]);
4806         emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4807         emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4808         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4809                                    GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4810       }
4811       break;
4812     case 2:
4813       {
4814         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4815         rtx tmp = gen_reg_rtx (V4SFmode);
4816
4817         emit_move_insn (tmp, operands[0]);
4818         emit_insn (gen_sse_movss (tmp, tmp, op1));
4819         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4820                                    GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4821       }
4822       break;
4823     case 3:
4824       {
4825         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4826         rtx tmp = gen_reg_rtx (V4SFmode);
4827
4828         emit_move_insn (tmp, operands[0]);
4829         emit_insn (gen_sse_movss (tmp, tmp, op1));
4830         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4831                                    GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4832       }
4833       break;
4834     default:
4835       abort ();
4836     }
4837   DONE;
4838 })
4839
4840 (define_expand "vec_extractv4sf"
4841   [(match_operand:SF 0 "register_operand" "")
4842    (match_operand:V4SF 1 "register_operand" "")
4843    (match_operand 2 "const_int_operand" "")]
4844   "TARGET_SSE"
4845 {
4846   switch (INTVAL (operands[2]))
4847     {
4848     case 0:
4849       emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4850       break;
4851     case 1:
4852       {
4853         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4854         rtx tmp = gen_reg_rtx (V4SFmode);
4855  
4856         emit_move_insn (tmp, operands[1]);
4857         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4858                                    const1_rtx));
4859       }
4860       break;
4861     case 2:
4862       {
4863         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4864         rtx tmp = gen_reg_rtx (V4SFmode);
4865  
4866         emit_move_insn (tmp, operands[1]);
4867         emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4868       }
4869       break;
4870     case 3:
4871       {
4872         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4873         rtx tmp = gen_reg_rtx (V4SFmode);
4874  
4875         emit_move_insn (tmp, operands[1]);
4876         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4877                                    GEN_INT (3)));
4878       }
4879       break;
4880     default:
4881       abort ();
4882     }
4883   DONE;
4884 })
4885
4886 (define_expand "vec_initv4sf"
4887   [(match_operand:V4SF 0 "register_operand" "")
4888    (match_operand 1 "" "")]
4889   "TARGET_SSE"
4890 {
4891   ix86_expand_vector_init (operands[0], operands[1]);
4892   DONE;
4893 })
4894 \f
4895 ;; Add instructions
4896
4897 ;; %%% splits for addsidi3
4898 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4899 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4900 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4901
4902 (define_expand "adddi3"
4903   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4904         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4905                  (match_operand:DI 2 "x86_64_general_operand" "")))
4906    (clobber (reg:CC FLAGS_REG))]
4907   ""
4908   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4909
4910 (define_insn "*adddi3_1"
4911   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4912         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4913                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4914    (clobber (reg:CC FLAGS_REG))]
4915   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4916   "#")
4917
4918 (define_split
4919   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4920         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4921                  (match_operand:DI 2 "general_operand" "")))
4922    (clobber (reg:CC FLAGS_REG))]
4923   "!TARGET_64BIT && reload_completed"
4924   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4925                                           UNSPEC_ADD_CARRY))
4926               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4927    (parallel [(set (match_dup 3)
4928                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4929                                      (match_dup 4))
4930                             (match_dup 5)))
4931               (clobber (reg:CC FLAGS_REG))])]
4932   "split_di (operands+0, 1, operands+0, operands+3);
4933    split_di (operands+1, 1, operands+1, operands+4);
4934    split_di (operands+2, 1, operands+2, operands+5);")
4935
4936 (define_insn "adddi3_carry_rex64"
4937   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4938           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4939                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4940                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4941    (clobber (reg:CC FLAGS_REG))]
4942   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4943   "adc{q}\t{%2, %0|%0, %2}"
4944   [(set_attr "type" "alu")
4945    (set_attr "pent_pair" "pu")
4946    (set_attr "mode" "DI")])
4947
4948 (define_insn "*adddi3_cc_rex64"
4949   [(set (reg:CC FLAGS_REG)
4950         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4951                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4952                    UNSPEC_ADD_CARRY))
4953    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4954         (plus:DI (match_dup 1) (match_dup 2)))]
4955   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4956   "add{q}\t{%2, %0|%0, %2}"
4957   [(set_attr "type" "alu")
4958    (set_attr "mode" "DI")])
4959
4960 (define_insn "addqi3_carry"
4961   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4962           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4963                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4964                    (match_operand:QI 2 "general_operand" "qi,qm")))
4965    (clobber (reg:CC FLAGS_REG))]
4966   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4967   "adc{b}\t{%2, %0|%0, %2}"
4968   [(set_attr "type" "alu")
4969    (set_attr "pent_pair" "pu")
4970    (set_attr "mode" "QI")])
4971
4972 (define_insn "addhi3_carry"
4973   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4974           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4975                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4976                    (match_operand:HI 2 "general_operand" "ri,rm")))
4977    (clobber (reg:CC FLAGS_REG))]
4978   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4979   "adc{w}\t{%2, %0|%0, %2}"
4980   [(set_attr "type" "alu")
4981    (set_attr "pent_pair" "pu")
4982    (set_attr "mode" "HI")])
4983
4984 (define_insn "addsi3_carry"
4985   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4986           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4987                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4988                    (match_operand:SI 2 "general_operand" "ri,rm")))
4989    (clobber (reg:CC FLAGS_REG))]
4990   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4991   "adc{l}\t{%2, %0|%0, %2}"
4992   [(set_attr "type" "alu")
4993    (set_attr "pent_pair" "pu")
4994    (set_attr "mode" "SI")])
4995
4996 (define_insn "*addsi3_carry_zext"
4997   [(set (match_operand:DI 0 "register_operand" "=r")
4998           (zero_extend:DI 
4999             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5000                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5001                      (match_operand:SI 2 "general_operand" "rim"))))
5002    (clobber (reg:CC FLAGS_REG))]
5003   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5004   "adc{l}\t{%2, %k0|%k0, %2}"
5005   [(set_attr "type" "alu")
5006    (set_attr "pent_pair" "pu")
5007    (set_attr "mode" "SI")])
5008
5009 (define_insn "*addsi3_cc"
5010   [(set (reg:CC FLAGS_REG)
5011         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5012                     (match_operand:SI 2 "general_operand" "ri,rm")]
5013                    UNSPEC_ADD_CARRY))
5014    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5015         (plus:SI (match_dup 1) (match_dup 2)))]
5016   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5017   "add{l}\t{%2, %0|%0, %2}"
5018   [(set_attr "type" "alu")
5019    (set_attr "mode" "SI")])
5020
5021 (define_insn "addqi3_cc"
5022   [(set (reg:CC FLAGS_REG)
5023         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5024                     (match_operand:QI 2 "general_operand" "qi,qm")]
5025                    UNSPEC_ADD_CARRY))
5026    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5027         (plus:QI (match_dup 1) (match_dup 2)))]
5028   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5029   "add{b}\t{%2, %0|%0, %2}"
5030   [(set_attr "type" "alu")
5031    (set_attr "mode" "QI")])
5032
5033 (define_expand "addsi3"
5034   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5035                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5036                             (match_operand:SI 2 "general_operand" "")))
5037               (clobber (reg:CC FLAGS_REG))])]
5038   ""
5039   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5040
5041 (define_insn "*lea_1"
5042   [(set (match_operand:SI 0 "register_operand" "=r")
5043         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5044   "!TARGET_64BIT"
5045   "lea{l}\t{%a1, %0|%0, %a1}"
5046   [(set_attr "type" "lea")
5047    (set_attr "mode" "SI")])
5048
5049 (define_insn "*lea_1_rex64"
5050   [(set (match_operand:SI 0 "register_operand" "=r")
5051         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5052   "TARGET_64BIT"
5053   "lea{l}\t{%a1, %0|%0, %a1}"
5054   [(set_attr "type" "lea")
5055    (set_attr "mode" "SI")])
5056
5057 (define_insn "*lea_1_zext"
5058   [(set (match_operand:DI 0 "register_operand" "=r")
5059         (zero_extend:DI
5060          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5061   "TARGET_64BIT"
5062   "lea{l}\t{%a1, %k0|%k0, %a1}"
5063   [(set_attr "type" "lea")
5064    (set_attr "mode" "SI")])
5065
5066 (define_insn "*lea_2_rex64"
5067   [(set (match_operand:DI 0 "register_operand" "=r")
5068         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5069   "TARGET_64BIT"
5070   "lea{q}\t{%a1, %0|%0, %a1}"
5071   [(set_attr "type" "lea")
5072    (set_attr "mode" "DI")])
5073
5074 ;; The lea patterns for non-Pmodes needs to be matched by several
5075 ;; insns converted to real lea by splitters.
5076
5077 (define_insn_and_split "*lea_general_1"
5078   [(set (match_operand 0 "register_operand" "=r")
5079         (plus (plus (match_operand 1 "index_register_operand" "l")
5080                     (match_operand 2 "register_operand" "r"))
5081               (match_operand 3 "immediate_operand" "i")))]
5082   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5083     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5084    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5085    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5086    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5087    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5088        || GET_MODE (operands[3]) == VOIDmode)"
5089   "#"
5090   "&& reload_completed"
5091   [(const_int 0)]
5092 {
5093   rtx pat;
5094   operands[0] = gen_lowpart (SImode, operands[0]);
5095   operands[1] = gen_lowpart (Pmode, operands[1]);
5096   operands[2] = gen_lowpart (Pmode, operands[2]);
5097   operands[3] = gen_lowpart (Pmode, operands[3]);
5098   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5099                       operands[3]);
5100   if (Pmode != SImode)
5101     pat = gen_rtx_SUBREG (SImode, pat, 0);
5102   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5103   DONE;
5104 }
5105   [(set_attr "type" "lea")
5106    (set_attr "mode" "SI")])
5107
5108 (define_insn_and_split "*lea_general_1_zext"
5109   [(set (match_operand:DI 0 "register_operand" "=r")
5110         (zero_extend:DI
5111           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5112                             (match_operand:SI 2 "register_operand" "r"))
5113                    (match_operand:SI 3 "immediate_operand" "i"))))]
5114   "TARGET_64BIT"
5115   "#"
5116   "&& reload_completed"
5117   [(set (match_dup 0)
5118         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5119                                                      (match_dup 2))
5120                                             (match_dup 3)) 0)))]
5121 {
5122   operands[1] = gen_lowpart (Pmode, operands[1]);
5123   operands[2] = gen_lowpart (Pmode, operands[2]);
5124   operands[3] = gen_lowpart (Pmode, operands[3]);
5125 }
5126   [(set_attr "type" "lea")
5127    (set_attr "mode" "SI")])
5128
5129 (define_insn_and_split "*lea_general_2"
5130   [(set (match_operand 0 "register_operand" "=r")
5131         (plus (mult (match_operand 1 "index_register_operand" "l")
5132                     (match_operand 2 "const248_operand" "i"))
5133               (match_operand 3 "nonmemory_operand" "ri")))]
5134   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5135     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5136    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5137    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5138    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5139        || GET_MODE (operands[3]) == VOIDmode)"
5140   "#"
5141   "&& reload_completed"
5142   [(const_int 0)]
5143 {
5144   rtx pat;
5145   operands[0] = gen_lowpart (SImode, operands[0]);
5146   operands[1] = gen_lowpart (Pmode, operands[1]);
5147   operands[3] = gen_lowpart (Pmode, operands[3]);
5148   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5149                       operands[3]);
5150   if (Pmode != SImode)
5151     pat = gen_rtx_SUBREG (SImode, pat, 0);
5152   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5153   DONE;
5154 }
5155   [(set_attr "type" "lea")
5156    (set_attr "mode" "SI")])
5157
5158 (define_insn_and_split "*lea_general_2_zext"
5159   [(set (match_operand:DI 0 "register_operand" "=r")
5160         (zero_extend:DI
5161           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5162                             (match_operand:SI 2 "const248_operand" "n"))
5163                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5164   "TARGET_64BIT"
5165   "#"
5166   "&& reload_completed"
5167   [(set (match_dup 0)
5168         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5169                                                      (match_dup 2))
5170                                             (match_dup 3)) 0)))]
5171 {
5172   operands[1] = gen_lowpart (Pmode, operands[1]);
5173   operands[3] = gen_lowpart (Pmode, operands[3]);
5174 }
5175   [(set_attr "type" "lea")
5176    (set_attr "mode" "SI")])
5177
5178 (define_insn_and_split "*lea_general_3"
5179   [(set (match_operand 0 "register_operand" "=r")
5180         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5181                           (match_operand 2 "const248_operand" "i"))
5182                     (match_operand 3 "register_operand" "r"))
5183               (match_operand 4 "immediate_operand" "i")))]
5184   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5185     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5186    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5187    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5188    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5189   "#"
5190   "&& reload_completed"
5191   [(const_int 0)]
5192 {
5193   rtx pat;
5194   operands[0] = gen_lowpart (SImode, operands[0]);
5195   operands[1] = gen_lowpart (Pmode, operands[1]);
5196   operands[3] = gen_lowpart (Pmode, operands[3]);
5197   operands[4] = gen_lowpart (Pmode, operands[4]);
5198   pat = gen_rtx_PLUS (Pmode,
5199                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5200                                                          operands[2]),
5201                                     operands[3]),
5202                       operands[4]);
5203   if (Pmode != SImode)
5204     pat = gen_rtx_SUBREG (SImode, pat, 0);
5205   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5206   DONE;
5207 }
5208   [(set_attr "type" "lea")
5209    (set_attr "mode" "SI")])
5210
5211 (define_insn_and_split "*lea_general_3_zext"
5212   [(set (match_operand:DI 0 "register_operand" "=r")
5213         (zero_extend:DI
5214           (plus:SI (plus:SI (mult:SI
5215                               (match_operand:SI 1 "index_register_operand" "l")
5216                               (match_operand:SI 2 "const248_operand" "n"))
5217                             (match_operand:SI 3 "register_operand" "r"))
5218                    (match_operand:SI 4 "immediate_operand" "i"))))]
5219   "TARGET_64BIT"
5220   "#"
5221   "&& reload_completed"
5222   [(set (match_dup 0)
5223         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5224                                                               (match_dup 2))
5225                                                      (match_dup 3))
5226                                             (match_dup 4)) 0)))]
5227 {
5228   operands[1] = gen_lowpart (Pmode, operands[1]);
5229   operands[3] = gen_lowpart (Pmode, operands[3]);
5230   operands[4] = gen_lowpart (Pmode, operands[4]);
5231 }
5232   [(set_attr "type" "lea")
5233    (set_attr "mode" "SI")])
5234
5235 (define_insn "*adddi_1_rex64"
5236   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5237         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5238                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5239    (clobber (reg:CC FLAGS_REG))]
5240   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5241 {
5242   switch (get_attr_type (insn))
5243     {
5244     case TYPE_LEA:
5245       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5246       return "lea{q}\t{%a2, %0|%0, %a2}";
5247
5248     case TYPE_INCDEC:
5249       if (! rtx_equal_p (operands[0], operands[1]))
5250         abort ();
5251       if (operands[2] == const1_rtx)
5252         return "inc{q}\t%0";
5253       else if (operands[2] == constm1_rtx)
5254         return "dec{q}\t%0";
5255       else
5256         abort ();
5257
5258     default:
5259       if (! rtx_equal_p (operands[0], operands[1]))
5260         abort ();
5261
5262       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5263          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5264       if (GET_CODE (operands[2]) == CONST_INT
5265           /* Avoid overflows.  */
5266           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5267           && (INTVAL (operands[2]) == 128
5268               || (INTVAL (operands[2]) < 0
5269                   && INTVAL (operands[2]) != -128)))
5270         {
5271           operands[2] = GEN_INT (-INTVAL (operands[2]));
5272           return "sub{q}\t{%2, %0|%0, %2}";
5273         }
5274       return "add{q}\t{%2, %0|%0, %2}";
5275     }
5276 }
5277   [(set (attr "type")
5278      (cond [(eq_attr "alternative" "2")
5279               (const_string "lea")
5280             ; Current assemblers are broken and do not allow @GOTOFF in
5281             ; ought but a memory context.
5282             (match_operand:DI 2 "pic_symbolic_operand" "")
5283               (const_string "lea")
5284             (match_operand:DI 2 "incdec_operand" "")
5285               (const_string "incdec")
5286            ]
5287            (const_string "alu")))
5288    (set_attr "mode" "DI")])
5289
5290 ;; Convert lea to the lea pattern to avoid flags dependency.
5291 (define_split
5292   [(set (match_operand:DI 0 "register_operand" "")
5293         (plus:DI (match_operand:DI 1 "register_operand" "")
5294                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5295    (clobber (reg:CC FLAGS_REG))]
5296   "TARGET_64BIT && reload_completed
5297    && true_regnum (operands[0]) != true_regnum (operands[1])"
5298   [(set (match_dup 0)
5299         (plus:DI (match_dup 1)
5300                  (match_dup 2)))]
5301   "")
5302
5303 (define_insn "*adddi_2_rex64"
5304   [(set (reg FLAGS_REG)
5305         (compare
5306           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5307                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5308           (const_int 0)))                       
5309    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5310         (plus:DI (match_dup 1) (match_dup 2)))]
5311   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5312    && ix86_binary_operator_ok (PLUS, DImode, operands)
5313    /* Current assemblers are broken and do not allow @GOTOFF in
5314       ought but a memory context.  */
5315    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5316 {
5317   switch (get_attr_type (insn))
5318     {
5319     case TYPE_INCDEC:
5320       if (! rtx_equal_p (operands[0], operands[1]))
5321         abort ();
5322       if (operands[2] == const1_rtx)
5323         return "inc{q}\t%0";
5324       else if (operands[2] == constm1_rtx)
5325         return "dec{q}\t%0";
5326       else
5327         abort ();
5328
5329     default:
5330       if (! rtx_equal_p (operands[0], operands[1]))
5331         abort ();
5332       /* ???? We ought to handle there the 32bit case too
5333          - do we need new constraint?  */
5334       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5335          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5336       if (GET_CODE (operands[2]) == CONST_INT
5337           /* Avoid overflows.  */
5338           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5339           && (INTVAL (operands[2]) == 128
5340               || (INTVAL (operands[2]) < 0
5341                   && INTVAL (operands[2]) != -128)))
5342         {
5343           operands[2] = GEN_INT (-INTVAL (operands[2]));
5344           return "sub{q}\t{%2, %0|%0, %2}";
5345         }
5346       return "add{q}\t{%2, %0|%0, %2}";
5347     }
5348 }
5349   [(set (attr "type")
5350      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5351         (const_string "incdec")
5352         (const_string "alu")))
5353    (set_attr "mode" "DI")])
5354
5355 (define_insn "*adddi_3_rex64"
5356   [(set (reg FLAGS_REG)
5357         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5358                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5359    (clobber (match_scratch:DI 0 "=r"))]
5360   "TARGET_64BIT
5361    && ix86_match_ccmode (insn, CCZmode)
5362    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5363    /* Current assemblers are broken and do not allow @GOTOFF in
5364       ought but a memory context.  */
5365    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5366 {
5367   switch (get_attr_type (insn))
5368     {
5369     case TYPE_INCDEC:
5370       if (! rtx_equal_p (operands[0], operands[1]))
5371         abort ();
5372       if (operands[2] == const1_rtx)
5373         return "inc{q}\t%0";
5374       else if (operands[2] == constm1_rtx)
5375         return "dec{q}\t%0";
5376       else
5377         abort ();
5378
5379     default:
5380       if (! rtx_equal_p (operands[0], operands[1]))
5381         abort ();
5382       /* ???? We ought to handle there the 32bit case too
5383          - do we need new constraint?  */
5384       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5385          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5386       if (GET_CODE (operands[2]) == CONST_INT
5387           /* Avoid overflows.  */
5388           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5389           && (INTVAL (operands[2]) == 128
5390               || (INTVAL (operands[2]) < 0
5391                   && INTVAL (operands[2]) != -128)))
5392         {
5393           operands[2] = GEN_INT (-INTVAL (operands[2]));
5394           return "sub{q}\t{%2, %0|%0, %2}";
5395         }
5396       return "add{q}\t{%2, %0|%0, %2}";
5397     }
5398 }
5399   [(set (attr "type")
5400      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5401         (const_string "incdec")
5402         (const_string "alu")))
5403    (set_attr "mode" "DI")])
5404
5405 ; For comparisons against 1, -1 and 128, we may generate better code
5406 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5407 ; is matched then.  We can't accept general immediate, because for
5408 ; case of overflows,  the result is messed up.
5409 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5410 ; when negated.
5411 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5412 ; only for comparisons not depending on it.
5413 (define_insn "*adddi_4_rex64"
5414   [(set (reg FLAGS_REG)
5415         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5416                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5417    (clobber (match_scratch:DI 0 "=rm"))]
5418   "TARGET_64BIT
5419    &&  ix86_match_ccmode (insn, CCGCmode)"
5420 {
5421   switch (get_attr_type (insn))
5422     {
5423     case TYPE_INCDEC:
5424       if (operands[2] == constm1_rtx)
5425         return "inc{q}\t%0";
5426       else if (operands[2] == const1_rtx)
5427         return "dec{q}\t%0";
5428       else
5429         abort();
5430
5431     default:
5432       if (! rtx_equal_p (operands[0], operands[1]))
5433         abort ();
5434       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5435          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5436       if ((INTVAL (operands[2]) == -128
5437            || (INTVAL (operands[2]) > 0
5438                && INTVAL (operands[2]) != 128))
5439           /* Avoid overflows.  */
5440           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5441         return "sub{q}\t{%2, %0|%0, %2}";
5442       operands[2] = GEN_INT (-INTVAL (operands[2]));
5443       return "add{q}\t{%2, %0|%0, %2}";
5444     }
5445 }
5446   [(set (attr "type")
5447      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5448         (const_string "incdec")
5449         (const_string "alu")))
5450    (set_attr "mode" "DI")])
5451
5452 (define_insn "*adddi_5_rex64"
5453   [(set (reg FLAGS_REG)
5454         (compare
5455           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5456                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5457           (const_int 0)))                       
5458    (clobber (match_scratch:DI 0 "=r"))]
5459   "TARGET_64BIT
5460    && ix86_match_ccmode (insn, CCGOCmode)
5461    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5462    /* Current assemblers are broken and do not allow @GOTOFF in
5463       ought but a memory context.  */
5464    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5465 {
5466   switch (get_attr_type (insn))
5467     {
5468     case TYPE_INCDEC:
5469       if (! rtx_equal_p (operands[0], operands[1]))
5470         abort ();
5471       if (operands[2] == const1_rtx)
5472         return "inc{q}\t%0";
5473       else if (operands[2] == constm1_rtx)
5474         return "dec{q}\t%0";
5475       else
5476         abort();
5477
5478     default:
5479       if (! rtx_equal_p (operands[0], operands[1]))
5480         abort ();
5481       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5482          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5483       if (GET_CODE (operands[2]) == CONST_INT
5484           /* Avoid overflows.  */
5485           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5486           && (INTVAL (operands[2]) == 128
5487               || (INTVAL (operands[2]) < 0
5488                   && INTVAL (operands[2]) != -128)))
5489         {
5490           operands[2] = GEN_INT (-INTVAL (operands[2]));
5491           return "sub{q}\t{%2, %0|%0, %2}";
5492         }
5493       return "add{q}\t{%2, %0|%0, %2}";
5494     }
5495 }
5496   [(set (attr "type")
5497      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5498         (const_string "incdec")
5499         (const_string "alu")))
5500    (set_attr "mode" "DI")])
5501
5502
5503 (define_insn "*addsi_1"
5504   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5505         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5506                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5507    (clobber (reg:CC FLAGS_REG))]
5508   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5509 {
5510   switch (get_attr_type (insn))
5511     {
5512     case TYPE_LEA:
5513       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5514       return "lea{l}\t{%a2, %0|%0, %a2}";
5515
5516     case TYPE_INCDEC:
5517       if (! rtx_equal_p (operands[0], operands[1]))
5518         abort ();
5519       if (operands[2] == const1_rtx)
5520         return "inc{l}\t%0";
5521       else if (operands[2] == constm1_rtx)
5522         return "dec{l}\t%0";
5523       else
5524         abort();
5525
5526     default:
5527       if (! rtx_equal_p (operands[0], operands[1]))
5528         abort ();
5529
5530       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5531          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5532       if (GET_CODE (operands[2]) == CONST_INT
5533           && (INTVAL (operands[2]) == 128
5534               || (INTVAL (operands[2]) < 0
5535                   && INTVAL (operands[2]) != -128)))
5536         {
5537           operands[2] = GEN_INT (-INTVAL (operands[2]));
5538           return "sub{l}\t{%2, %0|%0, %2}";
5539         }
5540       return "add{l}\t{%2, %0|%0, %2}";
5541     }
5542 }
5543   [(set (attr "type")
5544      (cond [(eq_attr "alternative" "2")
5545               (const_string "lea")
5546             ; Current assemblers are broken and do not allow @GOTOFF in
5547             ; ought but a memory context.
5548             (match_operand:SI 2 "pic_symbolic_operand" "")
5549               (const_string "lea")
5550             (match_operand:SI 2 "incdec_operand" "")
5551               (const_string "incdec")
5552            ]
5553            (const_string "alu")))
5554    (set_attr "mode" "SI")])
5555
5556 ;; Convert lea to the lea pattern to avoid flags dependency.
5557 (define_split
5558   [(set (match_operand 0 "register_operand" "")
5559         (plus (match_operand 1 "register_operand" "")
5560               (match_operand 2 "nonmemory_operand" "")))
5561    (clobber (reg:CC FLAGS_REG))]
5562   "reload_completed
5563    && true_regnum (operands[0]) != true_regnum (operands[1])"
5564   [(const_int 0)]
5565 {
5566   rtx pat;
5567   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5568      may confuse gen_lowpart.  */
5569   if (GET_MODE (operands[0]) != Pmode)
5570     {
5571       operands[1] = gen_lowpart (Pmode, operands[1]);
5572       operands[2] = gen_lowpart (Pmode, operands[2]);
5573     }
5574   operands[0] = gen_lowpart (SImode, operands[0]);
5575   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5576   if (Pmode != SImode)
5577     pat = gen_rtx_SUBREG (SImode, pat, 0);
5578   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5579   DONE;
5580 })
5581
5582 ;; It may seem that nonimmediate operand is proper one for operand 1.
5583 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5584 ;; we take care in ix86_binary_operator_ok to not allow two memory
5585 ;; operands so proper swapping will be done in reload.  This allow
5586 ;; patterns constructed from addsi_1 to match.
5587 (define_insn "addsi_1_zext"
5588   [(set (match_operand:DI 0 "register_operand" "=r,r")
5589         (zero_extend:DI
5590           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5591                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5592    (clobber (reg:CC FLAGS_REG))]
5593   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5594 {
5595   switch (get_attr_type (insn))
5596     {
5597     case TYPE_LEA:
5598       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5599       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5600
5601     case TYPE_INCDEC:
5602       if (operands[2] == const1_rtx)
5603         return "inc{l}\t%k0";
5604       else if (operands[2] == constm1_rtx)
5605         return "dec{l}\t%k0";
5606       else
5607         abort();
5608
5609     default:
5610       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5611          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5612       if (GET_CODE (operands[2]) == CONST_INT
5613           && (INTVAL (operands[2]) == 128
5614               || (INTVAL (operands[2]) < 0
5615                   && INTVAL (operands[2]) != -128)))
5616         {
5617           operands[2] = GEN_INT (-INTVAL (operands[2]));
5618           return "sub{l}\t{%2, %k0|%k0, %2}";
5619         }
5620       return "add{l}\t{%2, %k0|%k0, %2}";
5621     }
5622 }
5623   [(set (attr "type")
5624      (cond [(eq_attr "alternative" "1")
5625               (const_string "lea")
5626             ; Current assemblers are broken and do not allow @GOTOFF in
5627             ; ought but a memory context.
5628             (match_operand:SI 2 "pic_symbolic_operand" "")
5629               (const_string "lea")
5630             (match_operand:SI 2 "incdec_operand" "")
5631               (const_string "incdec")
5632            ]
5633            (const_string "alu")))
5634    (set_attr "mode" "SI")])
5635
5636 ;; Convert lea to the lea pattern to avoid flags dependency.
5637 (define_split
5638   [(set (match_operand:DI 0 "register_operand" "")
5639         (zero_extend:DI
5640           (plus:SI (match_operand:SI 1 "register_operand" "")
5641                    (match_operand:SI 2 "nonmemory_operand" ""))))
5642    (clobber (reg:CC FLAGS_REG))]
5643   "TARGET_64BIT && reload_completed
5644    && true_regnum (operands[0]) != true_regnum (operands[1])"
5645   [(set (match_dup 0)
5646         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5647 {
5648   operands[1] = gen_lowpart (Pmode, operands[1]);
5649   operands[2] = gen_lowpart (Pmode, operands[2]);
5650 })
5651
5652 (define_insn "*addsi_2"
5653   [(set (reg FLAGS_REG)
5654         (compare
5655           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5656                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5657           (const_int 0)))                       
5658    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5659         (plus:SI (match_dup 1) (match_dup 2)))]
5660   "ix86_match_ccmode (insn, CCGOCmode)
5661    && ix86_binary_operator_ok (PLUS, SImode, operands)
5662    /* Current assemblers are broken and do not allow @GOTOFF in
5663       ought but a memory context.  */
5664    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5665 {
5666   switch (get_attr_type (insn))
5667     {
5668     case TYPE_INCDEC:
5669       if (! rtx_equal_p (operands[0], operands[1]))
5670         abort ();
5671       if (operands[2] == const1_rtx)
5672         return "inc{l}\t%0";
5673       else if (operands[2] == constm1_rtx)
5674         return "dec{l}\t%0";
5675       else
5676         abort();
5677
5678     default:
5679       if (! rtx_equal_p (operands[0], operands[1]))
5680         abort ();
5681       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5682          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5683       if (GET_CODE (operands[2]) == CONST_INT
5684           && (INTVAL (operands[2]) == 128
5685               || (INTVAL (operands[2]) < 0
5686                   && INTVAL (operands[2]) != -128)))
5687         {
5688           operands[2] = GEN_INT (-INTVAL (operands[2]));
5689           return "sub{l}\t{%2, %0|%0, %2}";
5690         }
5691       return "add{l}\t{%2, %0|%0, %2}";
5692     }
5693 }
5694   [(set (attr "type")
5695      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5696         (const_string "incdec")
5697         (const_string "alu")))
5698    (set_attr "mode" "SI")])
5699
5700 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5701 (define_insn "*addsi_2_zext"
5702   [(set (reg FLAGS_REG)
5703         (compare
5704           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5705                    (match_operand:SI 2 "general_operand" "rmni"))
5706           (const_int 0)))                       
5707    (set (match_operand:DI 0 "register_operand" "=r")
5708         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5709   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5710    && ix86_binary_operator_ok (PLUS, SImode, operands)
5711    /* Current assemblers are broken and do not allow @GOTOFF in
5712       ought but a memory context.  */
5713    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5714 {
5715   switch (get_attr_type (insn))
5716     {
5717     case TYPE_INCDEC:
5718       if (operands[2] == const1_rtx)
5719         return "inc{l}\t%k0";
5720       else if (operands[2] == constm1_rtx)
5721         return "dec{l}\t%k0";
5722       else
5723         abort();
5724
5725     default:
5726       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5727          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5728       if (GET_CODE (operands[2]) == CONST_INT
5729           && (INTVAL (operands[2]) == 128
5730               || (INTVAL (operands[2]) < 0
5731                   && INTVAL (operands[2]) != -128)))
5732         {
5733           operands[2] = GEN_INT (-INTVAL (operands[2]));
5734           return "sub{l}\t{%2, %k0|%k0, %2}";
5735         }
5736       return "add{l}\t{%2, %k0|%k0, %2}";
5737     }
5738 }
5739   [(set (attr "type")
5740      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5741         (const_string "incdec")
5742         (const_string "alu")))
5743    (set_attr "mode" "SI")])
5744
5745 (define_insn "*addsi_3"
5746   [(set (reg FLAGS_REG)
5747         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5748                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5749    (clobber (match_scratch:SI 0 "=r"))]
5750   "ix86_match_ccmode (insn, CCZmode)
5751    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5752    /* Current assemblers are broken and do not allow @GOTOFF in
5753       ought but a memory context.  */
5754    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5755 {
5756   switch (get_attr_type (insn))
5757     {
5758     case TYPE_INCDEC:
5759       if (! rtx_equal_p (operands[0], operands[1]))
5760         abort ();
5761       if (operands[2] == const1_rtx)
5762         return "inc{l}\t%0";
5763       else if (operands[2] == constm1_rtx)
5764         return "dec{l}\t%0";
5765       else
5766         abort();
5767
5768     default:
5769       if (! rtx_equal_p (operands[0], operands[1]))
5770         abort ();
5771       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5772          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5773       if (GET_CODE (operands[2]) == CONST_INT
5774           && (INTVAL (operands[2]) == 128
5775               || (INTVAL (operands[2]) < 0
5776                   && INTVAL (operands[2]) != -128)))
5777         {
5778           operands[2] = GEN_INT (-INTVAL (operands[2]));
5779           return "sub{l}\t{%2, %0|%0, %2}";
5780         }
5781       return "add{l}\t{%2, %0|%0, %2}";
5782     }
5783 }
5784   [(set (attr "type")
5785      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5786         (const_string "incdec")
5787         (const_string "alu")))
5788    (set_attr "mode" "SI")])
5789
5790 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5791 (define_insn "*addsi_3_zext"
5792   [(set (reg FLAGS_REG)
5793         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5794                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5795    (set (match_operand:DI 0 "register_operand" "=r")
5796         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5797   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5798    && ix86_binary_operator_ok (PLUS, SImode, operands)
5799    /* Current assemblers are broken and do not allow @GOTOFF in
5800       ought but a memory context.  */
5801    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5802 {
5803   switch (get_attr_type (insn))
5804     {
5805     case TYPE_INCDEC:
5806       if (operands[2] == const1_rtx)
5807         return "inc{l}\t%k0";
5808       else if (operands[2] == constm1_rtx)
5809         return "dec{l}\t%k0";
5810       else
5811         abort();
5812
5813     default:
5814       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5815          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5816       if (GET_CODE (operands[2]) == CONST_INT
5817           && (INTVAL (operands[2]) == 128
5818               || (INTVAL (operands[2]) < 0
5819                   && INTVAL (operands[2]) != -128)))
5820         {
5821           operands[2] = GEN_INT (-INTVAL (operands[2]));
5822           return "sub{l}\t{%2, %k0|%k0, %2}";
5823         }
5824       return "add{l}\t{%2, %k0|%k0, %2}";
5825     }
5826 }
5827   [(set (attr "type")
5828      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5829         (const_string "incdec")
5830         (const_string "alu")))
5831    (set_attr "mode" "SI")])
5832
5833 ; For comparisons against 1, -1 and 128, we may generate better code
5834 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5835 ; is matched then.  We can't accept general immediate, because for
5836 ; case of overflows,  the result is messed up.
5837 ; This pattern also don't hold of 0x80000000, since the value overflows
5838 ; when negated.
5839 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5840 ; only for comparisons not depending on it.
5841 (define_insn "*addsi_4"
5842   [(set (reg FLAGS_REG)
5843         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5844                  (match_operand:SI 2 "const_int_operand" "n")))
5845    (clobber (match_scratch:SI 0 "=rm"))]
5846   "ix86_match_ccmode (insn, CCGCmode)
5847    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5848 {
5849   switch (get_attr_type (insn))
5850     {
5851     case TYPE_INCDEC:
5852       if (operands[2] == constm1_rtx)
5853         return "inc{l}\t%0";
5854       else if (operands[2] == const1_rtx)
5855         return "dec{l}\t%0";
5856       else
5857         abort();
5858
5859     default:
5860       if (! rtx_equal_p (operands[0], operands[1]))
5861         abort ();
5862       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5863          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5864       if ((INTVAL (operands[2]) == -128
5865            || (INTVAL (operands[2]) > 0
5866                && INTVAL (operands[2]) != 128)))
5867         return "sub{l}\t{%2, %0|%0, %2}";
5868       operands[2] = GEN_INT (-INTVAL (operands[2]));
5869       return "add{l}\t{%2, %0|%0, %2}";
5870     }
5871 }
5872   [(set (attr "type")
5873      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5874         (const_string "incdec")
5875         (const_string "alu")))
5876    (set_attr "mode" "SI")])
5877
5878 (define_insn "*addsi_5"
5879   [(set (reg FLAGS_REG)
5880         (compare
5881           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5882                    (match_operand:SI 2 "general_operand" "rmni"))
5883           (const_int 0)))                       
5884    (clobber (match_scratch:SI 0 "=r"))]
5885   "ix86_match_ccmode (insn, CCGOCmode)
5886    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5887    /* Current assemblers are broken and do not allow @GOTOFF in
5888       ought but a memory context.  */
5889    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5890 {
5891   switch (get_attr_type (insn))
5892     {
5893     case TYPE_INCDEC:
5894       if (! rtx_equal_p (operands[0], operands[1]))
5895         abort ();
5896       if (operands[2] == const1_rtx)
5897         return "inc{l}\t%0";
5898       else if (operands[2] == constm1_rtx)
5899         return "dec{l}\t%0";
5900       else
5901         abort();
5902
5903     default:
5904       if (! rtx_equal_p (operands[0], operands[1]))
5905         abort ();
5906       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5907          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5908       if (GET_CODE (operands[2]) == CONST_INT
5909           && (INTVAL (operands[2]) == 128
5910               || (INTVAL (operands[2]) < 0
5911                   && INTVAL (operands[2]) != -128)))
5912         {
5913           operands[2] = GEN_INT (-INTVAL (operands[2]));
5914           return "sub{l}\t{%2, %0|%0, %2}";
5915         }
5916       return "add{l}\t{%2, %0|%0, %2}";
5917     }
5918 }
5919   [(set (attr "type")
5920      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5921         (const_string "incdec")
5922         (const_string "alu")))
5923    (set_attr "mode" "SI")])
5924
5925 (define_expand "addhi3"
5926   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5927                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5928                             (match_operand:HI 2 "general_operand" "")))
5929               (clobber (reg:CC FLAGS_REG))])]
5930   "TARGET_HIMODE_MATH"
5931   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5932
5933 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5934 ;; type optimizations enabled by define-splits.  This is not important
5935 ;; for PII, and in fact harmful because of partial register stalls.
5936
5937 (define_insn "*addhi_1_lea"
5938   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5939         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5940                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5941    (clobber (reg:CC FLAGS_REG))]
5942   "!TARGET_PARTIAL_REG_STALL
5943    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5944 {
5945   switch (get_attr_type (insn))
5946     {
5947     case TYPE_LEA:
5948       return "#";
5949     case TYPE_INCDEC:
5950       if (operands[2] == const1_rtx)
5951         return "inc{w}\t%0";
5952       else if (operands[2] == constm1_rtx)
5953         return "dec{w}\t%0";
5954       abort();
5955
5956     default:
5957       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5958          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5959       if (GET_CODE (operands[2]) == CONST_INT
5960           && (INTVAL (operands[2]) == 128
5961               || (INTVAL (operands[2]) < 0
5962                   && INTVAL (operands[2]) != -128)))
5963         {
5964           operands[2] = GEN_INT (-INTVAL (operands[2]));
5965           return "sub{w}\t{%2, %0|%0, %2}";
5966         }
5967       return "add{w}\t{%2, %0|%0, %2}";
5968     }
5969 }
5970   [(set (attr "type")
5971      (if_then_else (eq_attr "alternative" "2")
5972         (const_string "lea")
5973         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5974            (const_string "incdec")
5975            (const_string "alu"))))
5976    (set_attr "mode" "HI,HI,SI")])
5977
5978 (define_insn "*addhi_1"
5979   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5980         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5981                  (match_operand:HI 2 "general_operand" "ri,rm")))
5982    (clobber (reg:CC FLAGS_REG))]
5983   "TARGET_PARTIAL_REG_STALL
5984    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5985 {
5986   switch (get_attr_type (insn))
5987     {
5988     case TYPE_INCDEC:
5989       if (operands[2] == const1_rtx)
5990         return "inc{w}\t%0";
5991       else if (operands[2] == constm1_rtx)
5992         return "dec{w}\t%0";
5993       abort();
5994
5995     default:
5996       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5997          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5998       if (GET_CODE (operands[2]) == CONST_INT
5999           && (INTVAL (operands[2]) == 128
6000               || (INTVAL (operands[2]) < 0
6001                   && INTVAL (operands[2]) != -128)))
6002         {
6003           operands[2] = GEN_INT (-INTVAL (operands[2]));
6004           return "sub{w}\t{%2, %0|%0, %2}";
6005         }
6006       return "add{w}\t{%2, %0|%0, %2}";
6007     }
6008 }
6009   [(set (attr "type")
6010      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6011         (const_string "incdec")
6012         (const_string "alu")))
6013    (set_attr "mode" "HI")])
6014
6015 (define_insn "*addhi_2"
6016   [(set (reg FLAGS_REG)
6017         (compare
6018           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6019                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6020           (const_int 0)))                       
6021    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6022         (plus:HI (match_dup 1) (match_dup 2)))]
6023   "ix86_match_ccmode (insn, CCGOCmode)
6024    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6025 {
6026   switch (get_attr_type (insn))
6027     {
6028     case TYPE_INCDEC:
6029       if (operands[2] == const1_rtx)
6030         return "inc{w}\t%0";
6031       else if (operands[2] == constm1_rtx)
6032         return "dec{w}\t%0";
6033       abort();
6034
6035     default:
6036       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6037          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6038       if (GET_CODE (operands[2]) == CONST_INT
6039           && (INTVAL (operands[2]) == 128
6040               || (INTVAL (operands[2]) < 0
6041                   && INTVAL (operands[2]) != -128)))
6042         {
6043           operands[2] = GEN_INT (-INTVAL (operands[2]));
6044           return "sub{w}\t{%2, %0|%0, %2}";
6045         }
6046       return "add{w}\t{%2, %0|%0, %2}";
6047     }
6048 }
6049   [(set (attr "type")
6050      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6051         (const_string "incdec")
6052         (const_string "alu")))
6053    (set_attr "mode" "HI")])
6054
6055 (define_insn "*addhi_3"
6056   [(set (reg FLAGS_REG)
6057         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6058                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6059    (clobber (match_scratch:HI 0 "=r"))]
6060   "ix86_match_ccmode (insn, CCZmode)
6061    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6062 {
6063   switch (get_attr_type (insn))
6064     {
6065     case TYPE_INCDEC:
6066       if (operands[2] == const1_rtx)
6067         return "inc{w}\t%0";
6068       else if (operands[2] == constm1_rtx)
6069         return "dec{w}\t%0";
6070       abort();
6071
6072     default:
6073       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6074          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6075       if (GET_CODE (operands[2]) == CONST_INT
6076           && (INTVAL (operands[2]) == 128
6077               || (INTVAL (operands[2]) < 0
6078                   && INTVAL (operands[2]) != -128)))
6079         {
6080           operands[2] = GEN_INT (-INTVAL (operands[2]));
6081           return "sub{w}\t{%2, %0|%0, %2}";
6082         }
6083       return "add{w}\t{%2, %0|%0, %2}";
6084     }
6085 }
6086   [(set (attr "type")
6087      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6088         (const_string "incdec")
6089         (const_string "alu")))
6090    (set_attr "mode" "HI")])
6091
6092 ; See comments above addsi_3_imm for details.
6093 (define_insn "*addhi_4"
6094   [(set (reg FLAGS_REG)
6095         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6096                  (match_operand:HI 2 "const_int_operand" "n")))
6097    (clobber (match_scratch:HI 0 "=rm"))]
6098   "ix86_match_ccmode (insn, CCGCmode)
6099    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6100 {
6101   switch (get_attr_type (insn))
6102     {
6103     case TYPE_INCDEC:
6104       if (operands[2] == constm1_rtx)
6105         return "inc{w}\t%0";
6106       else if (operands[2] == const1_rtx)
6107         return "dec{w}\t%0";
6108       else
6109         abort();
6110
6111     default:
6112       if (! rtx_equal_p (operands[0], operands[1]))
6113         abort ();
6114       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6115          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6116       if ((INTVAL (operands[2]) == -128
6117            || (INTVAL (operands[2]) > 0
6118                && INTVAL (operands[2]) != 128)))
6119         return "sub{w}\t{%2, %0|%0, %2}";
6120       operands[2] = GEN_INT (-INTVAL (operands[2]));
6121       return "add{w}\t{%2, %0|%0, %2}";
6122     }
6123 }
6124   [(set (attr "type")
6125      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6126         (const_string "incdec")
6127         (const_string "alu")))
6128    (set_attr "mode" "SI")])
6129
6130
6131 (define_insn "*addhi_5"
6132   [(set (reg FLAGS_REG)
6133         (compare
6134           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6135                    (match_operand:HI 2 "general_operand" "rmni"))
6136           (const_int 0)))                       
6137    (clobber (match_scratch:HI 0 "=r"))]
6138   "ix86_match_ccmode (insn, CCGOCmode)
6139    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6140 {
6141   switch (get_attr_type (insn))
6142     {
6143     case TYPE_INCDEC:
6144       if (operands[2] == const1_rtx)
6145         return "inc{w}\t%0";
6146       else if (operands[2] == constm1_rtx)
6147         return "dec{w}\t%0";
6148       abort();
6149
6150     default:
6151       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6152          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6153       if (GET_CODE (operands[2]) == CONST_INT
6154           && (INTVAL (operands[2]) == 128
6155               || (INTVAL (operands[2]) < 0
6156                   && INTVAL (operands[2]) != -128)))
6157         {
6158           operands[2] = GEN_INT (-INTVAL (operands[2]));
6159           return "sub{w}\t{%2, %0|%0, %2}";
6160         }
6161       return "add{w}\t{%2, %0|%0, %2}";
6162     }
6163 }
6164   [(set (attr "type")
6165      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6166         (const_string "incdec")
6167         (const_string "alu")))
6168    (set_attr "mode" "HI")])
6169
6170 (define_expand "addqi3"
6171   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6172                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6173                             (match_operand:QI 2 "general_operand" "")))
6174               (clobber (reg:CC FLAGS_REG))])]
6175   "TARGET_QIMODE_MATH"
6176   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6177
6178 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6179 (define_insn "*addqi_1_lea"
6180   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6181         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6182                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6183    (clobber (reg:CC FLAGS_REG))]
6184   "!TARGET_PARTIAL_REG_STALL
6185    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6186 {
6187   int widen = (which_alternative == 2);
6188   switch (get_attr_type (insn))
6189     {
6190     case TYPE_LEA:
6191       return "#";
6192     case TYPE_INCDEC:
6193       if (operands[2] == const1_rtx)
6194         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6195       else if (operands[2] == constm1_rtx)
6196         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6197       abort();
6198
6199     default:
6200       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6201          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6202       if (GET_CODE (operands[2]) == CONST_INT
6203           && (INTVAL (operands[2]) == 128
6204               || (INTVAL (operands[2]) < 0
6205                   && INTVAL (operands[2]) != -128)))
6206         {
6207           operands[2] = GEN_INT (-INTVAL (operands[2]));
6208           if (widen)
6209             return "sub{l}\t{%2, %k0|%k0, %2}";
6210           else
6211             return "sub{b}\t{%2, %0|%0, %2}";
6212         }
6213       if (widen)
6214         return "add{l}\t{%k2, %k0|%k0, %k2}";
6215       else
6216         return "add{b}\t{%2, %0|%0, %2}";
6217     }
6218 }
6219   [(set (attr "type")
6220      (if_then_else (eq_attr "alternative" "3")
6221         (const_string "lea")
6222         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6223            (const_string "incdec")
6224            (const_string "alu"))))
6225    (set_attr "mode" "QI,QI,SI,SI")])
6226
6227 (define_insn "*addqi_1"
6228   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6229         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6230                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6231    (clobber (reg:CC FLAGS_REG))]
6232   "TARGET_PARTIAL_REG_STALL
6233    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6234 {
6235   int widen = (which_alternative == 2);
6236   switch (get_attr_type (insn))
6237     {
6238     case TYPE_INCDEC:
6239       if (operands[2] == const1_rtx)
6240         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6241       else if (operands[2] == constm1_rtx)
6242         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6243       abort();
6244
6245     default:
6246       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6247          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6248       if (GET_CODE (operands[2]) == CONST_INT
6249           && (INTVAL (operands[2]) == 128
6250               || (INTVAL (operands[2]) < 0
6251                   && INTVAL (operands[2]) != -128)))
6252         {
6253           operands[2] = GEN_INT (-INTVAL (operands[2]));
6254           if (widen)
6255             return "sub{l}\t{%2, %k0|%k0, %2}";
6256           else
6257             return "sub{b}\t{%2, %0|%0, %2}";
6258         }
6259       if (widen)
6260         return "add{l}\t{%k2, %k0|%k0, %k2}";
6261       else
6262         return "add{b}\t{%2, %0|%0, %2}";
6263     }
6264 }
6265   [(set (attr "type")
6266      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6267         (const_string "incdec")
6268         (const_string "alu")))
6269    (set_attr "mode" "QI,QI,SI")])
6270
6271 (define_insn "*addqi_1_slp"
6272   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6273         (plus:QI (match_dup 0)
6274                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6275    (clobber (reg:CC FLAGS_REG))]
6276   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6277    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6278 {
6279   switch (get_attr_type (insn))
6280     {
6281     case TYPE_INCDEC:
6282       if (operands[1] == const1_rtx)
6283         return "inc{b}\t%0";
6284       else if (operands[1] == constm1_rtx)
6285         return "dec{b}\t%0";
6286       abort();
6287
6288     default:
6289       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6290       if (GET_CODE (operands[1]) == CONST_INT
6291           && INTVAL (operands[1]) < 0)
6292         {
6293           operands[1] = GEN_INT (-INTVAL (operands[1]));
6294           return "sub{b}\t{%1, %0|%0, %1}";
6295         }
6296       return "add{b}\t{%1, %0|%0, %1}";
6297     }
6298 }
6299   [(set (attr "type")
6300      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6301         (const_string "incdec")
6302         (const_string "alu1")))
6303    (set_attr "mode" "QI")])
6304
6305 (define_insn "*addqi_2"
6306   [(set (reg FLAGS_REG)
6307         (compare
6308           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6309                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6310           (const_int 0)))
6311    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6312         (plus:QI (match_dup 1) (match_dup 2)))]
6313   "ix86_match_ccmode (insn, CCGOCmode)
6314    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6315 {
6316   switch (get_attr_type (insn))
6317     {
6318     case TYPE_INCDEC:
6319       if (operands[2] == const1_rtx)
6320         return "inc{b}\t%0";
6321       else if (operands[2] == constm1_rtx
6322                || (GET_CODE (operands[2]) == CONST_INT
6323                    && INTVAL (operands[2]) == 255))
6324         return "dec{b}\t%0";
6325       abort();
6326
6327     default:
6328       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6329       if (GET_CODE (operands[2]) == CONST_INT
6330           && INTVAL (operands[2]) < 0)
6331         {
6332           operands[2] = GEN_INT (-INTVAL (operands[2]));
6333           return "sub{b}\t{%2, %0|%0, %2}";
6334         }
6335       return "add{b}\t{%2, %0|%0, %2}";
6336     }
6337 }
6338   [(set (attr "type")
6339      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6340         (const_string "incdec")
6341         (const_string "alu")))
6342    (set_attr "mode" "QI")])
6343
6344 (define_insn "*addqi_3"
6345   [(set (reg FLAGS_REG)
6346         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6347                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6348    (clobber (match_scratch:QI 0 "=q"))]
6349   "ix86_match_ccmode (insn, CCZmode)
6350    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6351 {
6352   switch (get_attr_type (insn))
6353     {
6354     case TYPE_INCDEC:
6355       if (operands[2] == const1_rtx)
6356         return "inc{b}\t%0";
6357       else if (operands[2] == constm1_rtx
6358                || (GET_CODE (operands[2]) == CONST_INT
6359                    && INTVAL (operands[2]) == 255))
6360         return "dec{b}\t%0";
6361       abort();
6362
6363     default:
6364       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6365       if (GET_CODE (operands[2]) == CONST_INT
6366           && INTVAL (operands[2]) < 0)
6367         {
6368           operands[2] = GEN_INT (-INTVAL (operands[2]));
6369           return "sub{b}\t{%2, %0|%0, %2}";
6370         }
6371       return "add{b}\t{%2, %0|%0, %2}";
6372     }
6373 }
6374   [(set (attr "type")
6375      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6376         (const_string "incdec")
6377         (const_string "alu")))
6378    (set_attr "mode" "QI")])
6379
6380 ; See comments above addsi_3_imm for details.
6381 (define_insn "*addqi_4"
6382   [(set (reg FLAGS_REG)
6383         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6384                  (match_operand:QI 2 "const_int_operand" "n")))
6385    (clobber (match_scratch:QI 0 "=qm"))]
6386   "ix86_match_ccmode (insn, CCGCmode)
6387    && (INTVAL (operands[2]) & 0xff) != 0x80"
6388 {
6389   switch (get_attr_type (insn))
6390     {
6391     case TYPE_INCDEC:
6392       if (operands[2] == constm1_rtx
6393           || (GET_CODE (operands[2]) == CONST_INT
6394               && INTVAL (operands[2]) == 255))
6395         return "inc{b}\t%0";
6396       else if (operands[2] == const1_rtx)
6397         return "dec{b}\t%0";
6398       else
6399         abort();
6400
6401     default:
6402       if (! rtx_equal_p (operands[0], operands[1]))
6403         abort ();
6404       if (INTVAL (operands[2]) < 0)
6405         {
6406           operands[2] = GEN_INT (-INTVAL (operands[2]));
6407           return "add{b}\t{%2, %0|%0, %2}";
6408         }
6409       return "sub{b}\t{%2, %0|%0, %2}";
6410     }
6411 }
6412   [(set (attr "type")
6413      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6414         (const_string "incdec")
6415         (const_string "alu")))
6416    (set_attr "mode" "QI")])
6417
6418
6419 (define_insn "*addqi_5"
6420   [(set (reg FLAGS_REG)
6421         (compare
6422           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6423                    (match_operand:QI 2 "general_operand" "qmni"))
6424           (const_int 0)))
6425    (clobber (match_scratch:QI 0 "=q"))]
6426   "ix86_match_ccmode (insn, CCGOCmode)
6427    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6428 {
6429   switch (get_attr_type (insn))
6430     {
6431     case TYPE_INCDEC:
6432       if (operands[2] == const1_rtx)
6433         return "inc{b}\t%0";
6434       else if (operands[2] == constm1_rtx
6435                || (GET_CODE (operands[2]) == CONST_INT
6436                    && INTVAL (operands[2]) == 255))
6437         return "dec{b}\t%0";
6438       abort();
6439
6440     default:
6441       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6442       if (GET_CODE (operands[2]) == CONST_INT
6443           && INTVAL (operands[2]) < 0)
6444         {
6445           operands[2] = GEN_INT (-INTVAL (operands[2]));
6446           return "sub{b}\t{%2, %0|%0, %2}";
6447         }
6448       return "add{b}\t{%2, %0|%0, %2}";
6449     }
6450 }
6451   [(set (attr "type")
6452      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6453         (const_string "incdec")
6454         (const_string "alu")))
6455    (set_attr "mode" "QI")])
6456
6457
6458 (define_insn "addqi_ext_1"
6459   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6460                          (const_int 8)
6461                          (const_int 8))
6462         (plus:SI
6463           (zero_extract:SI
6464             (match_operand 1 "ext_register_operand" "0")
6465             (const_int 8)
6466             (const_int 8))
6467           (match_operand:QI 2 "general_operand" "Qmn")))
6468    (clobber (reg:CC FLAGS_REG))]
6469   "!TARGET_64BIT"
6470 {
6471   switch (get_attr_type (insn))
6472     {
6473     case TYPE_INCDEC:
6474       if (operands[2] == const1_rtx)
6475         return "inc{b}\t%h0";
6476       else if (operands[2] == constm1_rtx
6477                || (GET_CODE (operands[2]) == CONST_INT
6478                    && INTVAL (operands[2]) == 255))
6479         return "dec{b}\t%h0";
6480       abort();
6481
6482     default:
6483       return "add{b}\t{%2, %h0|%h0, %2}";
6484     }
6485 }
6486   [(set (attr "type")
6487      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6488         (const_string "incdec")
6489         (const_string "alu")))
6490    (set_attr "mode" "QI")])
6491
6492 (define_insn "*addqi_ext_1_rex64"
6493   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6494                          (const_int 8)
6495                          (const_int 8))
6496         (plus:SI
6497           (zero_extract:SI
6498             (match_operand 1 "ext_register_operand" "0")
6499             (const_int 8)
6500             (const_int 8))
6501           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6502    (clobber (reg:CC FLAGS_REG))]
6503   "TARGET_64BIT"
6504 {
6505   switch (get_attr_type (insn))
6506     {
6507     case TYPE_INCDEC:
6508       if (operands[2] == const1_rtx)
6509         return "inc{b}\t%h0";
6510       else if (operands[2] == constm1_rtx
6511                || (GET_CODE (operands[2]) == CONST_INT
6512                    && INTVAL (operands[2]) == 255))
6513         return "dec{b}\t%h0";
6514       abort();
6515
6516     default:
6517       return "add{b}\t{%2, %h0|%h0, %2}";
6518     }
6519 }
6520   [(set (attr "type")
6521      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6522         (const_string "incdec")
6523         (const_string "alu")))
6524    (set_attr "mode" "QI")])
6525
6526 (define_insn "*addqi_ext_2"
6527   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6528                          (const_int 8)
6529                          (const_int 8))
6530         (plus:SI
6531           (zero_extract:SI
6532             (match_operand 1 "ext_register_operand" "%0")
6533             (const_int 8)
6534             (const_int 8))
6535           (zero_extract:SI
6536             (match_operand 2 "ext_register_operand" "Q")
6537             (const_int 8)
6538             (const_int 8))))
6539    (clobber (reg:CC FLAGS_REG))]
6540   ""
6541   "add{b}\t{%h2, %h0|%h0, %h2}"
6542   [(set_attr "type" "alu")
6543    (set_attr "mode" "QI")])
6544
6545 ;; The patterns that match these are at the end of this file.
6546
6547 (define_expand "addxf3"
6548   [(set (match_operand:XF 0 "register_operand" "")
6549         (plus:XF (match_operand:XF 1 "register_operand" "")
6550                  (match_operand:XF 2 "register_operand" "")))]
6551   "TARGET_80387"
6552   "")
6553
6554 (define_expand "adddf3"
6555   [(set (match_operand:DF 0 "register_operand" "")
6556         (plus:DF (match_operand:DF 1 "register_operand" "")
6557                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6558   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6559   "")
6560
6561 (define_expand "addsf3"
6562   [(set (match_operand:SF 0 "register_operand" "")
6563         (plus:SF (match_operand:SF 1 "register_operand" "")
6564                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6565   "TARGET_80387 || TARGET_SSE_MATH"
6566   "")
6567 \f
6568 ;; Subtract instructions
6569
6570 ;; %%% splits for subsidi3
6571
6572 (define_expand "subdi3"
6573   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6574                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6575                              (match_operand:DI 2 "x86_64_general_operand" "")))
6576               (clobber (reg:CC FLAGS_REG))])]
6577   ""
6578   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6579
6580 (define_insn "*subdi3_1"
6581   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6582         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6583                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6584    (clobber (reg:CC FLAGS_REG))]
6585   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6586   "#")
6587
6588 (define_split
6589   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6590         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6591                   (match_operand:DI 2 "general_operand" "")))
6592    (clobber (reg:CC FLAGS_REG))]
6593   "!TARGET_64BIT && reload_completed"
6594   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6595               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6596    (parallel [(set (match_dup 3)
6597                    (minus:SI (match_dup 4)
6598                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6599                                       (match_dup 5))))
6600               (clobber (reg:CC FLAGS_REG))])]
6601   "split_di (operands+0, 1, operands+0, operands+3);
6602    split_di (operands+1, 1, operands+1, operands+4);
6603    split_di (operands+2, 1, operands+2, operands+5);")
6604
6605 (define_insn "subdi3_carry_rex64"
6606   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6607           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6608             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6609                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6610    (clobber (reg:CC FLAGS_REG))]
6611   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6612   "sbb{q}\t{%2, %0|%0, %2}"
6613   [(set_attr "type" "alu")
6614    (set_attr "pent_pair" "pu")
6615    (set_attr "mode" "DI")])
6616
6617 (define_insn "*subdi_1_rex64"
6618   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6619         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6620                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6621    (clobber (reg:CC FLAGS_REG))]
6622   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6623   "sub{q}\t{%2, %0|%0, %2}"
6624   [(set_attr "type" "alu")
6625    (set_attr "mode" "DI")])
6626
6627 (define_insn "*subdi_2_rex64"
6628   [(set (reg FLAGS_REG)
6629         (compare
6630           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6631                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6632           (const_int 0)))
6633    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6634         (minus:DI (match_dup 1) (match_dup 2)))]
6635   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6636    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6637   "sub{q}\t{%2, %0|%0, %2}"
6638   [(set_attr "type" "alu")
6639    (set_attr "mode" "DI")])
6640
6641 (define_insn "*subdi_3_rex63"
6642   [(set (reg FLAGS_REG)
6643         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6644                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6645    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6646         (minus:DI (match_dup 1) (match_dup 2)))]
6647   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6648    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6649   "sub{q}\t{%2, %0|%0, %2}"
6650   [(set_attr "type" "alu")
6651    (set_attr "mode" "DI")])
6652
6653 (define_insn "subqi3_carry"
6654   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6655           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6656             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6657                (match_operand:QI 2 "general_operand" "qi,qm"))))
6658    (clobber (reg:CC FLAGS_REG))]
6659   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6660   "sbb{b}\t{%2, %0|%0, %2}"
6661   [(set_attr "type" "alu")
6662    (set_attr "pent_pair" "pu")
6663    (set_attr "mode" "QI")])
6664
6665 (define_insn "subhi3_carry"
6666   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6667           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6668             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6669                (match_operand:HI 2 "general_operand" "ri,rm"))))
6670    (clobber (reg:CC FLAGS_REG))]
6671   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6672   "sbb{w}\t{%2, %0|%0, %2}"
6673   [(set_attr "type" "alu")
6674    (set_attr "pent_pair" "pu")
6675    (set_attr "mode" "HI")])
6676
6677 (define_insn "subsi3_carry"
6678   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6679           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6680             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6681                (match_operand:SI 2 "general_operand" "ri,rm"))))
6682    (clobber (reg:CC FLAGS_REG))]
6683   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6684   "sbb{l}\t{%2, %0|%0, %2}"
6685   [(set_attr "type" "alu")
6686    (set_attr "pent_pair" "pu")
6687    (set_attr "mode" "SI")])
6688
6689 (define_insn "subsi3_carry_zext"
6690   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6691           (zero_extend:DI
6692             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6693               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6694                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6695    (clobber (reg:CC FLAGS_REG))]
6696   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6697   "sbb{l}\t{%2, %k0|%k0, %2}"
6698   [(set_attr "type" "alu")
6699    (set_attr "pent_pair" "pu")
6700    (set_attr "mode" "SI")])
6701
6702 (define_expand "subsi3"
6703   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6704                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6705                              (match_operand:SI 2 "general_operand" "")))
6706               (clobber (reg:CC FLAGS_REG))])]
6707   ""
6708   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6709
6710 (define_insn "*subsi_1"
6711   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6712         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6713                   (match_operand:SI 2 "general_operand" "ri,rm")))
6714    (clobber (reg:CC FLAGS_REG))]
6715   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6716   "sub{l}\t{%2, %0|%0, %2}"
6717   [(set_attr "type" "alu")
6718    (set_attr "mode" "SI")])
6719
6720 (define_insn "*subsi_1_zext"
6721   [(set (match_operand:DI 0 "register_operand" "=r")
6722         (zero_extend:DI
6723           (minus:SI (match_operand:SI 1 "register_operand" "0")
6724                     (match_operand:SI 2 "general_operand" "rim"))))
6725    (clobber (reg:CC FLAGS_REG))]
6726   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6727   "sub{l}\t{%2, %k0|%k0, %2}"
6728   [(set_attr "type" "alu")
6729    (set_attr "mode" "SI")])
6730
6731 (define_insn "*subsi_2"
6732   [(set (reg FLAGS_REG)
6733         (compare
6734           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6735                     (match_operand:SI 2 "general_operand" "ri,rm"))
6736           (const_int 0)))
6737    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6738         (minus:SI (match_dup 1) (match_dup 2)))]
6739   "ix86_match_ccmode (insn, CCGOCmode)
6740    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6741   "sub{l}\t{%2, %0|%0, %2}"
6742   [(set_attr "type" "alu")
6743    (set_attr "mode" "SI")])
6744
6745 (define_insn "*subsi_2_zext"
6746   [(set (reg FLAGS_REG)
6747         (compare
6748           (minus:SI (match_operand:SI 1 "register_operand" "0")
6749                     (match_operand:SI 2 "general_operand" "rim"))
6750           (const_int 0)))
6751    (set (match_operand:DI 0 "register_operand" "=r")
6752         (zero_extend:DI
6753           (minus:SI (match_dup 1)
6754                     (match_dup 2))))]
6755   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6756    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6757   "sub{l}\t{%2, %k0|%k0, %2}"
6758   [(set_attr "type" "alu")
6759    (set_attr "mode" "SI")])
6760
6761 (define_insn "*subsi_3"
6762   [(set (reg FLAGS_REG)
6763         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6764                  (match_operand:SI 2 "general_operand" "ri,rm")))
6765    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6766         (minus:SI (match_dup 1) (match_dup 2)))]
6767   "ix86_match_ccmode (insn, CCmode)
6768    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6769   "sub{l}\t{%2, %0|%0, %2}"
6770   [(set_attr "type" "alu")
6771    (set_attr "mode" "SI")])
6772
6773 (define_insn "*subsi_3_zext"
6774   [(set (reg FLAGS_REG)
6775         (compare (match_operand:SI 1 "register_operand" "0")
6776                  (match_operand:SI 2 "general_operand" "rim")))
6777    (set (match_operand:DI 0 "register_operand" "=r")
6778         (zero_extend:DI
6779           (minus:SI (match_dup 1)
6780                     (match_dup 2))))]
6781   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6782    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6783   "sub{q}\t{%2, %0|%0, %2}"
6784   [(set_attr "type" "alu")
6785    (set_attr "mode" "DI")])
6786
6787 (define_expand "subhi3"
6788   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6789                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6790                              (match_operand:HI 2 "general_operand" "")))
6791               (clobber (reg:CC FLAGS_REG))])]
6792   "TARGET_HIMODE_MATH"
6793   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6794
6795 (define_insn "*subhi_1"
6796   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6797         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6798                   (match_operand:HI 2 "general_operand" "ri,rm")))
6799    (clobber (reg:CC FLAGS_REG))]
6800   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6801   "sub{w}\t{%2, %0|%0, %2}"
6802   [(set_attr "type" "alu")
6803    (set_attr "mode" "HI")])
6804
6805 (define_insn "*subhi_2"
6806   [(set (reg FLAGS_REG)
6807         (compare
6808           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6809                     (match_operand:HI 2 "general_operand" "ri,rm"))
6810           (const_int 0)))
6811    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6812         (minus:HI (match_dup 1) (match_dup 2)))]
6813   "ix86_match_ccmode (insn, CCGOCmode)
6814    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6815   "sub{w}\t{%2, %0|%0, %2}"
6816   [(set_attr "type" "alu")
6817    (set_attr "mode" "HI")])
6818
6819 (define_insn "*subhi_3"
6820   [(set (reg FLAGS_REG)
6821         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6822                  (match_operand:HI 2 "general_operand" "ri,rm")))
6823    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6824         (minus:HI (match_dup 1) (match_dup 2)))]
6825   "ix86_match_ccmode (insn, CCmode)
6826    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6827   "sub{w}\t{%2, %0|%0, %2}"
6828   [(set_attr "type" "alu")
6829    (set_attr "mode" "HI")])
6830
6831 (define_expand "subqi3"
6832   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6833                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6834                              (match_operand:QI 2 "general_operand" "")))
6835               (clobber (reg:CC FLAGS_REG))])]
6836   "TARGET_QIMODE_MATH"
6837   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6838
6839 (define_insn "*subqi_1"
6840   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6841         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6842                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6843    (clobber (reg:CC FLAGS_REG))]
6844   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6845   "sub{b}\t{%2, %0|%0, %2}"
6846   [(set_attr "type" "alu")
6847    (set_attr "mode" "QI")])
6848
6849 (define_insn "*subqi_1_slp"
6850   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6851         (minus:QI (match_dup 0)
6852                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6853    (clobber (reg:CC FLAGS_REG))]
6854   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6855    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6856   "sub{b}\t{%1, %0|%0, %1}"
6857   [(set_attr "type" "alu1")
6858    (set_attr "mode" "QI")])
6859
6860 (define_insn "*subqi_2"
6861   [(set (reg FLAGS_REG)
6862         (compare
6863           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6864                     (match_operand:QI 2 "general_operand" "qi,qm"))
6865           (const_int 0)))
6866    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6867         (minus:HI (match_dup 1) (match_dup 2)))]
6868   "ix86_match_ccmode (insn, CCGOCmode)
6869    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6870   "sub{b}\t{%2, %0|%0, %2}"
6871   [(set_attr "type" "alu")
6872    (set_attr "mode" "QI")])
6873
6874 (define_insn "*subqi_3"
6875   [(set (reg FLAGS_REG)
6876         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6877                  (match_operand:QI 2 "general_operand" "qi,qm")))
6878    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6879         (minus:HI (match_dup 1) (match_dup 2)))]
6880   "ix86_match_ccmode (insn, CCmode)
6881    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6882   "sub{b}\t{%2, %0|%0, %2}"
6883   [(set_attr "type" "alu")
6884    (set_attr "mode" "QI")])
6885
6886 ;; The patterns that match these are at the end of this file.
6887
6888 (define_expand "subxf3"
6889   [(set (match_operand:XF 0 "register_operand" "")
6890         (minus:XF (match_operand:XF 1 "register_operand" "")
6891                   (match_operand:XF 2 "register_operand" "")))]
6892   "TARGET_80387"
6893   "")
6894
6895 (define_expand "subdf3"
6896   [(set (match_operand:DF 0 "register_operand" "")
6897         (minus:DF (match_operand:DF 1 "register_operand" "")
6898                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6899   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6900   "")
6901
6902 (define_expand "subsf3"
6903   [(set (match_operand:SF 0 "register_operand" "")
6904         (minus:SF (match_operand:SF 1 "register_operand" "")
6905                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6906   "TARGET_80387 || TARGET_SSE_MATH"
6907   "")
6908 \f
6909 ;; Multiply instructions
6910
6911 (define_expand "muldi3"
6912   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6913                    (mult:DI (match_operand:DI 1 "register_operand" "")
6914                             (match_operand:DI 2 "x86_64_general_operand" "")))
6915               (clobber (reg:CC FLAGS_REG))])]
6916   "TARGET_64BIT"
6917   "")
6918
6919 (define_insn "*muldi3_1_rex64"
6920   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6921         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6922                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6923    (clobber (reg:CC FLAGS_REG))]
6924   "TARGET_64BIT
6925    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6926   "@
6927    imul{q}\t{%2, %1, %0|%0, %1, %2}
6928    imul{q}\t{%2, %1, %0|%0, %1, %2}
6929    imul{q}\t{%2, %0|%0, %2}"
6930   [(set_attr "type" "imul")
6931    (set_attr "prefix_0f" "0,0,1")
6932    (set (attr "athlon_decode")
6933         (cond [(eq_attr "cpu" "athlon")
6934                   (const_string "vector")
6935                (eq_attr "alternative" "1")
6936                   (const_string "vector")
6937                (and (eq_attr "alternative" "2")
6938                     (match_operand 1 "memory_operand" ""))
6939                   (const_string "vector")]
6940               (const_string "direct")))
6941    (set_attr "mode" "DI")])
6942
6943 (define_expand "mulsi3"
6944   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6945                    (mult:SI (match_operand:SI 1 "register_operand" "")
6946                             (match_operand:SI 2 "general_operand" "")))
6947               (clobber (reg:CC FLAGS_REG))])]
6948   ""
6949   "")
6950
6951 (define_insn "*mulsi3_1"
6952   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6953         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6954                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6955    (clobber (reg:CC FLAGS_REG))]
6956   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6957   "@
6958    imul{l}\t{%2, %1, %0|%0, %1, %2}
6959    imul{l}\t{%2, %1, %0|%0, %1, %2}
6960    imul{l}\t{%2, %0|%0, %2}"
6961   [(set_attr "type" "imul")
6962    (set_attr "prefix_0f" "0,0,1")
6963    (set (attr "athlon_decode")
6964         (cond [(eq_attr "cpu" "athlon")
6965                   (const_string "vector")
6966                (eq_attr "alternative" "1")
6967                   (const_string "vector")
6968                (and (eq_attr "alternative" "2")
6969                     (match_operand 1 "memory_operand" ""))
6970                   (const_string "vector")]
6971               (const_string "direct")))
6972    (set_attr "mode" "SI")])
6973
6974 (define_insn "*mulsi3_1_zext"
6975   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6976         (zero_extend:DI
6977           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6978                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6979    (clobber (reg:CC FLAGS_REG))]
6980   "TARGET_64BIT
6981    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6982   "@
6983    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6984    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6985    imul{l}\t{%2, %k0|%k0, %2}"
6986   [(set_attr "type" "imul")
6987    (set_attr "prefix_0f" "0,0,1")
6988    (set (attr "athlon_decode")
6989         (cond [(eq_attr "cpu" "athlon")
6990                   (const_string "vector")
6991                (eq_attr "alternative" "1")
6992                   (const_string "vector")
6993                (and (eq_attr "alternative" "2")
6994                     (match_operand 1 "memory_operand" ""))
6995                   (const_string "vector")]
6996               (const_string "direct")))
6997    (set_attr "mode" "SI")])
6998
6999 (define_expand "mulhi3"
7000   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7001                    (mult:HI (match_operand:HI 1 "register_operand" "")
7002                             (match_operand:HI 2 "general_operand" "")))
7003               (clobber (reg:CC FLAGS_REG))])]
7004   "TARGET_HIMODE_MATH"
7005   "")
7006
7007 (define_insn "*mulhi3_1"
7008   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7009         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7010                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7011    (clobber (reg:CC FLAGS_REG))]
7012   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7013   "@
7014    imul{w}\t{%2, %1, %0|%0, %1, %2}
7015    imul{w}\t{%2, %1, %0|%0, %1, %2}
7016    imul{w}\t{%2, %0|%0, %2}"
7017   [(set_attr "type" "imul")
7018    (set_attr "prefix_0f" "0,0,1")
7019    (set (attr "athlon_decode")
7020         (cond [(eq_attr "cpu" "athlon")
7021                   (const_string "vector")
7022                (eq_attr "alternative" "1,2")
7023                   (const_string "vector")]
7024               (const_string "direct")))
7025    (set_attr "mode" "HI")])
7026
7027 (define_expand "mulqi3"
7028   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7029                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7030                             (match_operand:QI 2 "register_operand" "")))
7031               (clobber (reg:CC FLAGS_REG))])]
7032   "TARGET_QIMODE_MATH"
7033   "")
7034
7035 (define_insn "*mulqi3_1"
7036   [(set (match_operand:QI 0 "register_operand" "=a")
7037         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7038                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7039    (clobber (reg:CC FLAGS_REG))]
7040   "TARGET_QIMODE_MATH
7041    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7042   "mul{b}\t%2"
7043   [(set_attr "type" "imul")
7044    (set_attr "length_immediate" "0")
7045    (set (attr "athlon_decode")
7046      (if_then_else (eq_attr "cpu" "athlon")
7047         (const_string "vector")
7048         (const_string "direct")))
7049    (set_attr "mode" "QI")])
7050
7051 (define_expand "umulqihi3"
7052   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7053                    (mult:HI (zero_extend:HI
7054                               (match_operand:QI 1 "nonimmediate_operand" ""))
7055                             (zero_extend:HI
7056                               (match_operand:QI 2 "register_operand" ""))))
7057               (clobber (reg:CC FLAGS_REG))])]
7058   "TARGET_QIMODE_MATH"
7059   "")
7060
7061 (define_insn "*umulqihi3_1"
7062   [(set (match_operand:HI 0 "register_operand" "=a")
7063         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7064                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7065    (clobber (reg:CC FLAGS_REG))]
7066   "TARGET_QIMODE_MATH
7067    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7068   "mul{b}\t%2"
7069   [(set_attr "type" "imul")
7070    (set_attr "length_immediate" "0")
7071    (set (attr "athlon_decode")
7072      (if_then_else (eq_attr "cpu" "athlon")
7073         (const_string "vector")
7074         (const_string "direct")))
7075    (set_attr "mode" "QI")])
7076
7077 (define_expand "mulqihi3"
7078   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7079                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7080                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7081               (clobber (reg:CC FLAGS_REG))])]
7082   "TARGET_QIMODE_MATH"
7083   "")
7084
7085 (define_insn "*mulqihi3_insn"
7086   [(set (match_operand:HI 0 "register_operand" "=a")
7087         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7088                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7089    (clobber (reg:CC FLAGS_REG))]
7090   "TARGET_QIMODE_MATH
7091    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7092   "imul{b}\t%2"
7093   [(set_attr "type" "imul")
7094    (set_attr "length_immediate" "0")
7095    (set (attr "athlon_decode")
7096      (if_then_else (eq_attr "cpu" "athlon")
7097         (const_string "vector")
7098         (const_string "direct")))
7099    (set_attr "mode" "QI")])
7100
7101 (define_expand "umulditi3"
7102   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7103                    (mult:TI (zero_extend:TI
7104                               (match_operand:DI 1 "nonimmediate_operand" ""))
7105                             (zero_extend:TI
7106                               (match_operand:DI 2 "register_operand" ""))))
7107               (clobber (reg:CC FLAGS_REG))])]
7108   "TARGET_64BIT"
7109   "")
7110
7111 (define_insn "*umulditi3_insn"
7112   [(set (match_operand:TI 0 "register_operand" "=A")
7113         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7114                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7115    (clobber (reg:CC FLAGS_REG))]
7116   "TARGET_64BIT
7117    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7118   "mul{q}\t%2"
7119   [(set_attr "type" "imul")
7120    (set_attr "length_immediate" "0")
7121    (set (attr "athlon_decode")
7122      (if_then_else (eq_attr "cpu" "athlon")
7123         (const_string "vector")
7124         (const_string "double")))
7125    (set_attr "mode" "DI")])
7126
7127 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7128 (define_expand "umulsidi3"
7129   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7130                    (mult:DI (zero_extend:DI
7131                               (match_operand:SI 1 "nonimmediate_operand" ""))
7132                             (zero_extend:DI
7133                               (match_operand:SI 2 "register_operand" ""))))
7134               (clobber (reg:CC FLAGS_REG))])]
7135   "!TARGET_64BIT"
7136   "")
7137
7138 (define_insn "*umulsidi3_insn"
7139   [(set (match_operand:DI 0 "register_operand" "=A")
7140         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7141                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7142    (clobber (reg:CC FLAGS_REG))]
7143   "!TARGET_64BIT
7144    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7145   "mul{l}\t%2"
7146   [(set_attr "type" "imul")
7147    (set_attr "length_immediate" "0")
7148    (set (attr "athlon_decode")
7149      (if_then_else (eq_attr "cpu" "athlon")
7150         (const_string "vector")
7151         (const_string "double")))
7152    (set_attr "mode" "SI")])
7153
7154 (define_expand "mulditi3"
7155   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7156                    (mult:TI (sign_extend:TI
7157                               (match_operand:DI 1 "nonimmediate_operand" ""))
7158                             (sign_extend:TI
7159                               (match_operand:DI 2 "register_operand" ""))))
7160               (clobber (reg:CC FLAGS_REG))])]
7161   "TARGET_64BIT"
7162   "")
7163
7164 (define_insn "*mulditi3_insn"
7165   [(set (match_operand:TI 0 "register_operand" "=A")
7166         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7167                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7168    (clobber (reg:CC FLAGS_REG))]
7169   "TARGET_64BIT
7170    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7171   "imul{q}\t%2"
7172   [(set_attr "type" "imul")
7173    (set_attr "length_immediate" "0")
7174    (set (attr "athlon_decode")
7175      (if_then_else (eq_attr "cpu" "athlon")
7176         (const_string "vector")
7177         (const_string "double")))
7178    (set_attr "mode" "DI")])
7179
7180 (define_expand "mulsidi3"
7181   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7182                    (mult:DI (sign_extend:DI
7183                               (match_operand:SI 1 "nonimmediate_operand" ""))
7184                             (sign_extend:DI
7185                               (match_operand:SI 2 "register_operand" ""))))
7186               (clobber (reg:CC FLAGS_REG))])]
7187   "!TARGET_64BIT"
7188   "")
7189
7190 (define_insn "*mulsidi3_insn"
7191   [(set (match_operand:DI 0 "register_operand" "=A")
7192         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7193                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7194    (clobber (reg:CC FLAGS_REG))]
7195   "!TARGET_64BIT
7196    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7197   "imul{l}\t%2"
7198   [(set_attr "type" "imul")
7199    (set_attr "length_immediate" "0")
7200    (set (attr "athlon_decode")
7201      (if_then_else (eq_attr "cpu" "athlon")
7202         (const_string "vector")
7203         (const_string "double")))
7204    (set_attr "mode" "SI")])
7205
7206 (define_expand "umuldi3_highpart"
7207   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7208                    (truncate:DI
7209                      (lshiftrt:TI
7210                        (mult:TI (zero_extend:TI
7211                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7212                                 (zero_extend:TI
7213                                   (match_operand:DI 2 "register_operand" "")))
7214                        (const_int 64))))
7215               (clobber (match_scratch:DI 3 ""))
7216               (clobber (reg:CC FLAGS_REG))])]
7217   "TARGET_64BIT"
7218   "")
7219
7220 (define_insn "*umuldi3_highpart_rex64"
7221   [(set (match_operand:DI 0 "register_operand" "=d")
7222         (truncate:DI
7223           (lshiftrt:TI
7224             (mult:TI (zero_extend:TI
7225                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7226                      (zero_extend:TI
7227                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7228             (const_int 64))))
7229    (clobber (match_scratch:DI 3 "=1"))
7230    (clobber (reg:CC FLAGS_REG))]
7231   "TARGET_64BIT
7232    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7233   "mul{q}\t%2"
7234   [(set_attr "type" "imul")
7235    (set_attr "length_immediate" "0")
7236    (set (attr "athlon_decode")
7237      (if_then_else (eq_attr "cpu" "athlon")
7238         (const_string "vector")
7239         (const_string "double")))
7240    (set_attr "mode" "DI")])
7241
7242 (define_expand "umulsi3_highpart"
7243   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7244                    (truncate:SI
7245                      (lshiftrt:DI
7246                        (mult:DI (zero_extend:DI
7247                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7248                                 (zero_extend:DI
7249                                   (match_operand:SI 2 "register_operand" "")))
7250                        (const_int 32))))
7251               (clobber (match_scratch:SI 3 ""))
7252               (clobber (reg:CC FLAGS_REG))])]
7253   ""
7254   "")
7255
7256 (define_insn "*umulsi3_highpart_insn"
7257   [(set (match_operand:SI 0 "register_operand" "=d")
7258         (truncate:SI
7259           (lshiftrt:DI
7260             (mult:DI (zero_extend:DI
7261                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7262                      (zero_extend:DI
7263                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7264             (const_int 32))))
7265    (clobber (match_scratch:SI 3 "=1"))
7266    (clobber (reg:CC FLAGS_REG))]
7267   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7268   "mul{l}\t%2"
7269   [(set_attr "type" "imul")
7270    (set_attr "length_immediate" "0")
7271    (set (attr "athlon_decode")
7272      (if_then_else (eq_attr "cpu" "athlon")
7273         (const_string "vector")
7274         (const_string "double")))
7275    (set_attr "mode" "SI")])
7276
7277 (define_insn "*umulsi3_highpart_zext"
7278   [(set (match_operand:DI 0 "register_operand" "=d")
7279         (zero_extend:DI (truncate:SI
7280           (lshiftrt:DI
7281             (mult:DI (zero_extend:DI
7282                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7283                      (zero_extend:DI
7284                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7285             (const_int 32)))))
7286    (clobber (match_scratch:SI 3 "=1"))
7287    (clobber (reg:CC FLAGS_REG))]
7288   "TARGET_64BIT
7289    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7290   "mul{l}\t%2"
7291   [(set_attr "type" "imul")
7292    (set_attr "length_immediate" "0")
7293    (set (attr "athlon_decode")
7294      (if_then_else (eq_attr "cpu" "athlon")
7295         (const_string "vector")
7296         (const_string "double")))
7297    (set_attr "mode" "SI")])
7298
7299 (define_expand "smuldi3_highpart"
7300   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7301                    (truncate:DI
7302                      (lshiftrt:TI
7303                        (mult:TI (sign_extend:TI
7304                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7305                                 (sign_extend:TI
7306                                   (match_operand:DI 2 "register_operand" "")))
7307                        (const_int 64))))
7308               (clobber (match_scratch:DI 3 ""))
7309               (clobber (reg:CC FLAGS_REG))])]
7310   "TARGET_64BIT"
7311   "")
7312
7313 (define_insn "*smuldi3_highpart_rex64"
7314   [(set (match_operand:DI 0 "register_operand" "=d")
7315         (truncate:DI
7316           (lshiftrt:TI
7317             (mult:TI (sign_extend:TI
7318                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7319                      (sign_extend:TI
7320                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7321             (const_int 64))))
7322    (clobber (match_scratch:DI 3 "=1"))
7323    (clobber (reg:CC FLAGS_REG))]
7324   "TARGET_64BIT
7325    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7326   "imul{q}\t%2"
7327   [(set_attr "type" "imul")
7328    (set (attr "athlon_decode")
7329      (if_then_else (eq_attr "cpu" "athlon")
7330         (const_string "vector")
7331         (const_string "double")))
7332    (set_attr "mode" "DI")])
7333
7334 (define_expand "smulsi3_highpart"
7335   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7336                    (truncate:SI
7337                      (lshiftrt:DI
7338                        (mult:DI (sign_extend:DI
7339                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7340                                 (sign_extend:DI
7341                                   (match_operand:SI 2 "register_operand" "")))
7342                        (const_int 32))))
7343               (clobber (match_scratch:SI 3 ""))
7344               (clobber (reg:CC FLAGS_REG))])]
7345   ""
7346   "")
7347
7348 (define_insn "*smulsi3_highpart_insn"
7349   [(set (match_operand:SI 0 "register_operand" "=d")
7350         (truncate:SI
7351           (lshiftrt:DI
7352             (mult:DI (sign_extend:DI
7353                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7354                      (sign_extend:DI
7355                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7356             (const_int 32))))
7357    (clobber (match_scratch:SI 3 "=1"))
7358    (clobber (reg:CC FLAGS_REG))]
7359   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7360   "imul{l}\t%2"
7361   [(set_attr "type" "imul")
7362    (set (attr "athlon_decode")
7363      (if_then_else (eq_attr "cpu" "athlon")
7364         (const_string "vector")
7365         (const_string "double")))
7366    (set_attr "mode" "SI")])
7367
7368 (define_insn "*smulsi3_highpart_zext"
7369   [(set (match_operand:DI 0 "register_operand" "=d")
7370         (zero_extend:DI (truncate:SI
7371           (lshiftrt:DI
7372             (mult:DI (sign_extend:DI
7373                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7374                      (sign_extend:DI
7375                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7376             (const_int 32)))))
7377    (clobber (match_scratch:SI 3 "=1"))
7378    (clobber (reg:CC FLAGS_REG))]
7379   "TARGET_64BIT
7380    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7381   "imul{l}\t%2"
7382   [(set_attr "type" "imul")
7383    (set (attr "athlon_decode")
7384      (if_then_else (eq_attr "cpu" "athlon")
7385         (const_string "vector")
7386         (const_string "double")))
7387    (set_attr "mode" "SI")])
7388
7389 ;; The patterns that match these are at the end of this file.
7390
7391 (define_expand "mulxf3"
7392   [(set (match_operand:XF 0 "register_operand" "")
7393         (mult:XF (match_operand:XF 1 "register_operand" "")
7394                  (match_operand:XF 2 "register_operand" "")))]
7395   "TARGET_80387"
7396   "")
7397
7398 (define_expand "muldf3"
7399   [(set (match_operand:DF 0 "register_operand" "")
7400         (mult:DF (match_operand:DF 1 "register_operand" "")
7401                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7402   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7403   "")
7404
7405 (define_expand "mulsf3"
7406   [(set (match_operand:SF 0 "register_operand" "")
7407         (mult:SF (match_operand:SF 1 "register_operand" "")
7408                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7409   "TARGET_80387 || TARGET_SSE_MATH"
7410   "")
7411 \f
7412 ;; Divide instructions
7413
7414 (define_insn "divqi3"
7415   [(set (match_operand:QI 0 "register_operand" "=a")
7416         (div:QI (match_operand:HI 1 "register_operand" "0")
7417                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7418    (clobber (reg:CC FLAGS_REG))]
7419   "TARGET_QIMODE_MATH"
7420   "idiv{b}\t%2"
7421   [(set_attr "type" "idiv")
7422    (set_attr "mode" "QI")])
7423
7424 (define_insn "udivqi3"
7425   [(set (match_operand:QI 0 "register_operand" "=a")
7426         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7427                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7428    (clobber (reg:CC FLAGS_REG))]
7429   "TARGET_QIMODE_MATH"
7430   "div{b}\t%2"
7431   [(set_attr "type" "idiv")
7432    (set_attr "mode" "QI")])
7433
7434 ;; The patterns that match these are at the end of this file.
7435
7436 (define_expand "divxf3"
7437   [(set (match_operand:XF 0 "register_operand" "")
7438         (div:XF (match_operand:XF 1 "register_operand" "")
7439                 (match_operand:XF 2 "register_operand" "")))]
7440   "TARGET_80387"
7441   "")
7442
7443 (define_expand "divdf3"
7444   [(set (match_operand:DF 0 "register_operand" "")
7445         (div:DF (match_operand:DF 1 "register_operand" "")
7446                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7447    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7448    "")
7449  
7450 (define_expand "divsf3"
7451   [(set (match_operand:SF 0 "register_operand" "")
7452         (div:SF (match_operand:SF 1 "register_operand" "")
7453                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7454   "TARGET_80387 || TARGET_SSE_MATH"
7455   "")
7456 \f
7457 ;; Remainder instructions.
7458
7459 (define_expand "divmoddi4"
7460   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7461                    (div:DI (match_operand:DI 1 "register_operand" "")
7462                            (match_operand:DI 2 "nonimmediate_operand" "")))
7463               (set (match_operand:DI 3 "register_operand" "")
7464                    (mod:DI (match_dup 1) (match_dup 2)))
7465               (clobber (reg:CC FLAGS_REG))])]
7466   "TARGET_64BIT"
7467   "")
7468
7469 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7470 ;; Penalize eax case slightly because it results in worse scheduling
7471 ;; of code.
7472 (define_insn "*divmoddi4_nocltd_rex64"
7473   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7474         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7475                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7476    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7477         (mod:DI (match_dup 2) (match_dup 3)))
7478    (clobber (reg:CC FLAGS_REG))]
7479   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7480   "#"
7481   [(set_attr "type" "multi")])
7482
7483 (define_insn "*divmoddi4_cltd_rex64"
7484   [(set (match_operand:DI 0 "register_operand" "=a")
7485         (div:DI (match_operand:DI 2 "register_operand" "a")
7486                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7487    (set (match_operand:DI 1 "register_operand" "=&d")
7488         (mod:DI (match_dup 2) (match_dup 3)))
7489    (clobber (reg:CC FLAGS_REG))]
7490   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7491   "#"
7492   [(set_attr "type" "multi")])
7493
7494 (define_insn "*divmoddi_noext_rex64"
7495   [(set (match_operand:DI 0 "register_operand" "=a")
7496         (div:DI (match_operand:DI 1 "register_operand" "0")
7497                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7498    (set (match_operand:DI 3 "register_operand" "=d")
7499         (mod:DI (match_dup 1) (match_dup 2)))
7500    (use (match_operand:DI 4 "register_operand" "3"))
7501    (clobber (reg:CC FLAGS_REG))]
7502   "TARGET_64BIT"
7503   "idiv{q}\t%2"
7504   [(set_attr "type" "idiv")
7505    (set_attr "mode" "DI")])
7506
7507 (define_split
7508   [(set (match_operand:DI 0 "register_operand" "")
7509         (div:DI (match_operand:DI 1 "register_operand" "")
7510                 (match_operand:DI 2 "nonimmediate_operand" "")))
7511    (set (match_operand:DI 3 "register_operand" "")
7512         (mod:DI (match_dup 1) (match_dup 2)))
7513    (clobber (reg:CC FLAGS_REG))]
7514   "TARGET_64BIT && reload_completed"
7515   [(parallel [(set (match_dup 3)
7516                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7517               (clobber (reg:CC FLAGS_REG))])
7518    (parallel [(set (match_dup 0)
7519                    (div:DI (reg:DI 0) (match_dup 2)))
7520               (set (match_dup 3)
7521                    (mod:DI (reg:DI 0) (match_dup 2)))
7522               (use (match_dup 3))
7523               (clobber (reg:CC FLAGS_REG))])]
7524 {
7525   /* Avoid use of cltd in favor of a mov+shift.  */
7526   if (!TARGET_USE_CLTD && !optimize_size)
7527     {
7528       if (true_regnum (operands[1]))
7529         emit_move_insn (operands[0], operands[1]);
7530       else
7531         emit_move_insn (operands[3], operands[1]);
7532       operands[4] = operands[3];
7533     }
7534   else
7535     {
7536       if (true_regnum (operands[1]))
7537         abort();
7538       operands[4] = operands[1];
7539     }
7540 })
7541
7542
7543 (define_expand "divmodsi4"
7544   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7545                    (div:SI (match_operand:SI 1 "register_operand" "")
7546                            (match_operand:SI 2 "nonimmediate_operand" "")))
7547               (set (match_operand:SI 3 "register_operand" "")
7548                    (mod:SI (match_dup 1) (match_dup 2)))
7549               (clobber (reg:CC FLAGS_REG))])]
7550   ""
7551   "")
7552
7553 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7554 ;; Penalize eax case slightly because it results in worse scheduling
7555 ;; of code.
7556 (define_insn "*divmodsi4_nocltd"
7557   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7558         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7559                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7560    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7561         (mod:SI (match_dup 2) (match_dup 3)))
7562    (clobber (reg:CC FLAGS_REG))]
7563   "!optimize_size && !TARGET_USE_CLTD"
7564   "#"
7565   [(set_attr "type" "multi")])
7566
7567 (define_insn "*divmodsi4_cltd"
7568   [(set (match_operand:SI 0 "register_operand" "=a")
7569         (div:SI (match_operand:SI 2 "register_operand" "a")
7570                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7571    (set (match_operand:SI 1 "register_operand" "=&d")
7572         (mod:SI (match_dup 2) (match_dup 3)))
7573    (clobber (reg:CC FLAGS_REG))]
7574   "optimize_size || TARGET_USE_CLTD"
7575   "#"
7576   [(set_attr "type" "multi")])
7577
7578 (define_insn "*divmodsi_noext"
7579   [(set (match_operand:SI 0 "register_operand" "=a")
7580         (div:SI (match_operand:SI 1 "register_operand" "0")
7581                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7582    (set (match_operand:SI 3 "register_operand" "=d")
7583         (mod:SI (match_dup 1) (match_dup 2)))
7584    (use (match_operand:SI 4 "register_operand" "3"))
7585    (clobber (reg:CC FLAGS_REG))]
7586   ""
7587   "idiv{l}\t%2"
7588   [(set_attr "type" "idiv")
7589    (set_attr "mode" "SI")])
7590
7591 (define_split
7592   [(set (match_operand:SI 0 "register_operand" "")
7593         (div:SI (match_operand:SI 1 "register_operand" "")
7594                 (match_operand:SI 2 "nonimmediate_operand" "")))
7595    (set (match_operand:SI 3 "register_operand" "")
7596         (mod:SI (match_dup 1) (match_dup 2)))
7597    (clobber (reg:CC FLAGS_REG))]
7598   "reload_completed"
7599   [(parallel [(set (match_dup 3)
7600                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7601               (clobber (reg:CC FLAGS_REG))])
7602    (parallel [(set (match_dup 0)
7603                    (div:SI (reg:SI 0) (match_dup 2)))
7604               (set (match_dup 3)
7605                    (mod:SI (reg:SI 0) (match_dup 2)))
7606               (use (match_dup 3))
7607               (clobber (reg:CC FLAGS_REG))])]
7608 {
7609   /* Avoid use of cltd in favor of a mov+shift.  */
7610   if (!TARGET_USE_CLTD && !optimize_size)
7611     {
7612       if (true_regnum (operands[1]))
7613         emit_move_insn (operands[0], operands[1]);
7614       else
7615         emit_move_insn (operands[3], operands[1]);
7616       operands[4] = operands[3];
7617     }
7618   else
7619     {
7620       if (true_regnum (operands[1]))
7621         abort();
7622       operands[4] = operands[1];
7623     }
7624 })
7625 ;; %%% Split me.
7626 (define_insn "divmodhi4"
7627   [(set (match_operand:HI 0 "register_operand" "=a")
7628         (div:HI (match_operand:HI 1 "register_operand" "0")
7629                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7630    (set (match_operand:HI 3 "register_operand" "=&d")
7631         (mod:HI (match_dup 1) (match_dup 2)))
7632    (clobber (reg:CC FLAGS_REG))]
7633   "TARGET_HIMODE_MATH"
7634   "cwtd\;idiv{w}\t%2"
7635   [(set_attr "type" "multi")
7636    (set_attr "length_immediate" "0")
7637    (set_attr "mode" "SI")])
7638
7639 (define_insn "udivmoddi4"
7640   [(set (match_operand:DI 0 "register_operand" "=a")
7641         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7642                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7643    (set (match_operand:DI 3 "register_operand" "=&d")
7644         (umod:DI (match_dup 1) (match_dup 2)))
7645    (clobber (reg:CC FLAGS_REG))]
7646   "TARGET_64BIT"
7647   "xor{q}\t%3, %3\;div{q}\t%2"
7648   [(set_attr "type" "multi")
7649    (set_attr "length_immediate" "0")
7650    (set_attr "mode" "DI")])
7651
7652 (define_insn "*udivmoddi4_noext"
7653   [(set (match_operand:DI 0 "register_operand" "=a")
7654         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7655                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7656    (set (match_operand:DI 3 "register_operand" "=d")
7657         (umod:DI (match_dup 1) (match_dup 2)))
7658    (use (match_dup 3))
7659    (clobber (reg:CC FLAGS_REG))]
7660   "TARGET_64BIT"
7661   "div{q}\t%2"
7662   [(set_attr "type" "idiv")
7663    (set_attr "mode" "DI")])
7664
7665 (define_split
7666   [(set (match_operand:DI 0 "register_operand" "")
7667         (udiv:DI (match_operand:DI 1 "register_operand" "")
7668                  (match_operand:DI 2 "nonimmediate_operand" "")))
7669    (set (match_operand:DI 3 "register_operand" "")
7670         (umod:DI (match_dup 1) (match_dup 2)))
7671    (clobber (reg:CC FLAGS_REG))]
7672   "TARGET_64BIT && reload_completed"
7673   [(set (match_dup 3) (const_int 0))
7674    (parallel [(set (match_dup 0)
7675                    (udiv:DI (match_dup 1) (match_dup 2)))
7676               (set (match_dup 3)
7677                    (umod:DI (match_dup 1) (match_dup 2)))
7678               (use (match_dup 3))
7679               (clobber (reg:CC FLAGS_REG))])]
7680   "")
7681
7682 (define_insn "udivmodsi4"
7683   [(set (match_operand:SI 0 "register_operand" "=a")
7684         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7685                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7686    (set (match_operand:SI 3 "register_operand" "=&d")
7687         (umod:SI (match_dup 1) (match_dup 2)))
7688    (clobber (reg:CC FLAGS_REG))]
7689   ""
7690   "xor{l}\t%3, %3\;div{l}\t%2"
7691   [(set_attr "type" "multi")
7692    (set_attr "length_immediate" "0")
7693    (set_attr "mode" "SI")])
7694
7695 (define_insn "*udivmodsi4_noext"
7696   [(set (match_operand:SI 0 "register_operand" "=a")
7697         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7698                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7699    (set (match_operand:SI 3 "register_operand" "=d")
7700         (umod:SI (match_dup 1) (match_dup 2)))
7701    (use (match_dup 3))
7702    (clobber (reg:CC FLAGS_REG))]
7703   ""
7704   "div{l}\t%2"
7705   [(set_attr "type" "idiv")
7706    (set_attr "mode" "SI")])
7707
7708 (define_split
7709   [(set (match_operand:SI 0 "register_operand" "")
7710         (udiv:SI (match_operand:SI 1 "register_operand" "")
7711                  (match_operand:SI 2 "nonimmediate_operand" "")))
7712    (set (match_operand:SI 3 "register_operand" "")
7713         (umod:SI (match_dup 1) (match_dup 2)))
7714    (clobber (reg:CC FLAGS_REG))]
7715   "reload_completed"
7716   [(set (match_dup 3) (const_int 0))
7717    (parallel [(set (match_dup 0)
7718                    (udiv:SI (match_dup 1) (match_dup 2)))
7719               (set (match_dup 3)
7720                    (umod:SI (match_dup 1) (match_dup 2)))
7721               (use (match_dup 3))
7722               (clobber (reg:CC FLAGS_REG))])]
7723   "")
7724
7725 (define_expand "udivmodhi4"
7726   [(set (match_dup 4) (const_int 0))
7727    (parallel [(set (match_operand:HI 0 "register_operand" "")
7728                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7729                             (match_operand:HI 2 "nonimmediate_operand" "")))
7730               (set (match_operand:HI 3 "register_operand" "")
7731                    (umod:HI (match_dup 1) (match_dup 2)))
7732               (use (match_dup 4))
7733               (clobber (reg:CC FLAGS_REG))])]
7734   "TARGET_HIMODE_MATH"
7735   "operands[4] = gen_reg_rtx (HImode);")
7736
7737 (define_insn "*udivmodhi_noext"
7738   [(set (match_operand:HI 0 "register_operand" "=a")
7739         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7740                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7741    (set (match_operand:HI 3 "register_operand" "=d")
7742         (umod:HI (match_dup 1) (match_dup 2)))
7743    (use (match_operand:HI 4 "register_operand" "3"))
7744    (clobber (reg:CC FLAGS_REG))]
7745   ""
7746   "div{w}\t%2"
7747   [(set_attr "type" "idiv")
7748    (set_attr "mode" "HI")])
7749
7750 ;; We cannot use div/idiv for double division, because it causes
7751 ;; "division by zero" on the overflow and that's not what we expect
7752 ;; from truncate.  Because true (non truncating) double division is
7753 ;; never generated, we can't create this insn anyway.
7754 ;
7755 ;(define_insn ""
7756 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7757 ;       (truncate:SI
7758 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7759 ;                  (zero_extend:DI
7760 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7761 ;   (set (match_operand:SI 3 "register_operand" "=d")
7762 ;       (truncate:SI
7763 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7764 ;   (clobber (reg:CC FLAGS_REG))]
7765 ;  ""
7766 ;  "div{l}\t{%2, %0|%0, %2}"
7767 ;  [(set_attr "type" "idiv")])
7768 \f
7769 ;;- Logical AND instructions
7770
7771 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7772 ;; Note that this excludes ah.
7773
7774 (define_insn "*testdi_1_rex64"
7775   [(set (reg FLAGS_REG)
7776         (compare
7777           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7778                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7779           (const_int 0)))]
7780   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7781    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7782   "@
7783    test{l}\t{%k1, %k0|%k0, %k1}
7784    test{l}\t{%k1, %k0|%k0, %k1}
7785    test{q}\t{%1, %0|%0, %1}
7786    test{q}\t{%1, %0|%0, %1}
7787    test{q}\t{%1, %0|%0, %1}"
7788   [(set_attr "type" "test")
7789    (set_attr "modrm" "0,1,0,1,1")
7790    (set_attr "mode" "SI,SI,DI,DI,DI")
7791    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7792
7793 (define_insn "testsi_1"
7794   [(set (reg FLAGS_REG)
7795         (compare
7796           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7797                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7798           (const_int 0)))]
7799   "ix86_match_ccmode (insn, CCNOmode)
7800    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7801   "test{l}\t{%1, %0|%0, %1}"
7802   [(set_attr "type" "test")
7803    (set_attr "modrm" "0,1,1")
7804    (set_attr "mode" "SI")
7805    (set_attr "pent_pair" "uv,np,uv")])
7806
7807 (define_expand "testsi_ccno_1"
7808   [(set (reg:CCNO FLAGS_REG)
7809         (compare:CCNO
7810           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7811                   (match_operand:SI 1 "nonmemory_operand" ""))
7812           (const_int 0)))]
7813   ""
7814   "")
7815
7816 (define_insn "*testhi_1"
7817   [(set (reg FLAGS_REG)
7818         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7819                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7820                  (const_int 0)))]
7821   "ix86_match_ccmode (insn, CCNOmode)
7822    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7823   "test{w}\t{%1, %0|%0, %1}"
7824   [(set_attr "type" "test")
7825    (set_attr "modrm" "0,1,1")
7826    (set_attr "mode" "HI")
7827    (set_attr "pent_pair" "uv,np,uv")])
7828
7829 (define_expand "testqi_ccz_1"
7830   [(set (reg:CCZ FLAGS_REG)
7831         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7832                              (match_operand:QI 1 "nonmemory_operand" ""))
7833                  (const_int 0)))]
7834   ""
7835   "")
7836
7837 (define_insn "*testqi_1_maybe_si"
7838   [(set (reg FLAGS_REG)
7839         (compare
7840           (and:QI
7841             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7842             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7843           (const_int 0)))]
7844    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7845     && ix86_match_ccmode (insn,
7846                          GET_CODE (operands[1]) == CONST_INT
7847                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7848 {
7849   if (which_alternative == 3)
7850     {
7851       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7852         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7853       return "test{l}\t{%1, %k0|%k0, %1}";
7854     }
7855   return "test{b}\t{%1, %0|%0, %1}";
7856 }
7857   [(set_attr "type" "test")
7858    (set_attr "modrm" "0,1,1,1")
7859    (set_attr "mode" "QI,QI,QI,SI")
7860    (set_attr "pent_pair" "uv,np,uv,np")])
7861
7862 (define_insn "*testqi_1"
7863   [(set (reg FLAGS_REG)
7864         (compare
7865           (and:QI
7866             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7867             (match_operand:QI 1 "general_operand" "n,n,qn"))
7868           (const_int 0)))]
7869   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7870    && ix86_match_ccmode (insn, CCNOmode)"
7871   "test{b}\t{%1, %0|%0, %1}"
7872   [(set_attr "type" "test")
7873    (set_attr "modrm" "0,1,1")
7874    (set_attr "mode" "QI")
7875    (set_attr "pent_pair" "uv,np,uv")])
7876
7877 (define_expand "testqi_ext_ccno_0"
7878   [(set (reg:CCNO FLAGS_REG)
7879         (compare:CCNO
7880           (and:SI
7881             (zero_extract:SI
7882               (match_operand 0 "ext_register_operand" "")
7883               (const_int 8)
7884               (const_int 8))
7885             (match_operand 1 "const_int_operand" ""))
7886           (const_int 0)))]
7887   ""
7888   "")
7889
7890 (define_insn "*testqi_ext_0"
7891   [(set (reg FLAGS_REG)
7892         (compare
7893           (and:SI
7894             (zero_extract:SI
7895               (match_operand 0 "ext_register_operand" "Q")
7896               (const_int 8)
7897               (const_int 8))
7898             (match_operand 1 "const_int_operand" "n"))
7899           (const_int 0)))]
7900   "ix86_match_ccmode (insn, CCNOmode)"
7901   "test{b}\t{%1, %h0|%h0, %1}"
7902   [(set_attr "type" "test")
7903    (set_attr "mode" "QI")
7904    (set_attr "length_immediate" "1")
7905    (set_attr "pent_pair" "np")])
7906
7907 (define_insn "*testqi_ext_1"
7908   [(set (reg FLAGS_REG)
7909         (compare
7910           (and:SI
7911             (zero_extract:SI
7912               (match_operand 0 "ext_register_operand" "Q")
7913               (const_int 8)
7914               (const_int 8))
7915             (zero_extend:SI
7916               (match_operand:QI 1 "general_operand" "Qm")))
7917           (const_int 0)))]
7918   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7919    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7920   "test{b}\t{%1, %h0|%h0, %1}"
7921   [(set_attr "type" "test")
7922    (set_attr "mode" "QI")])
7923
7924 (define_insn "*testqi_ext_1_rex64"
7925   [(set (reg FLAGS_REG)
7926         (compare
7927           (and:SI
7928             (zero_extract:SI
7929               (match_operand 0 "ext_register_operand" "Q")
7930               (const_int 8)
7931               (const_int 8))
7932             (zero_extend:SI
7933               (match_operand:QI 1 "register_operand" "Q")))
7934           (const_int 0)))]
7935   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7936   "test{b}\t{%1, %h0|%h0, %1}"
7937   [(set_attr "type" "test")
7938    (set_attr "mode" "QI")])
7939
7940 (define_insn "*testqi_ext_2"
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_extract:SI
7949               (match_operand 1 "ext_register_operand" "Q")
7950               (const_int 8)
7951               (const_int 8)))
7952           (const_int 0)))]
7953   "ix86_match_ccmode (insn, CCNOmode)"
7954   "test{b}\t{%h1, %h0|%h0, %h1}"
7955   [(set_attr "type" "test")
7956    (set_attr "mode" "QI")])
7957
7958 ;; Combine likes to form bit extractions for some tests.  Humor it.
7959 (define_insn "*testqi_ext_3"
7960   [(set (reg FLAGS_REG)
7961         (compare (zero_extract:SI
7962                    (match_operand 0 "nonimmediate_operand" "rm")
7963                    (match_operand:SI 1 "const_int_operand" "")
7964                    (match_operand:SI 2 "const_int_operand" ""))
7965                  (const_int 0)))]
7966   "ix86_match_ccmode (insn, CCNOmode)
7967    && (GET_MODE (operands[0]) == SImode
7968        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7969        || GET_MODE (operands[0]) == HImode
7970        || GET_MODE (operands[0]) == QImode)"
7971   "#")
7972
7973 (define_insn "*testqi_ext_3_rex64"
7974   [(set (reg FLAGS_REG)
7975         (compare (zero_extract:DI
7976                    (match_operand 0 "nonimmediate_operand" "rm")
7977                    (match_operand:DI 1 "const_int_operand" "")
7978                    (match_operand:DI 2 "const_int_operand" ""))
7979                  (const_int 0)))]
7980   "TARGET_64BIT
7981    && ix86_match_ccmode (insn, CCNOmode)
7982    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7983    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7984    /* Ensure that resulting mask is zero or sign extended operand.  */
7985    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7986        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7987            && INTVAL (operands[1]) > 32))
7988    && (GET_MODE (operands[0]) == SImode
7989        || GET_MODE (operands[0]) == DImode
7990        || GET_MODE (operands[0]) == HImode
7991        || GET_MODE (operands[0]) == QImode)"
7992   "#")
7993
7994 (define_split
7995   [(set (match_operand 0 "flags_reg_operand" "")
7996         (match_operator 1 "compare_operator"
7997           [(zero_extract
7998              (match_operand 2 "nonimmediate_operand" "")
7999              (match_operand 3 "const_int_operand" "")
8000              (match_operand 4 "const_int_operand" ""))
8001            (const_int 0)]))]
8002   "ix86_match_ccmode (insn, CCNOmode)"
8003   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8004 {
8005   rtx val = operands[2];
8006   HOST_WIDE_INT len = INTVAL (operands[3]);
8007   HOST_WIDE_INT pos = INTVAL (operands[4]);
8008   HOST_WIDE_INT mask;
8009   enum machine_mode mode, submode;
8010
8011   mode = GET_MODE (val);
8012   if (GET_CODE (val) == MEM)
8013     {
8014       /* ??? Combine likes to put non-volatile mem extractions in QImode
8015          no matter the size of the test.  So find a mode that works.  */
8016       if (! MEM_VOLATILE_P (val))
8017         {
8018           mode = smallest_mode_for_size (pos + len, MODE_INT);
8019           val = adjust_address (val, mode, 0);
8020         }
8021     }
8022   else if (GET_CODE (val) == SUBREG
8023            && (submode = GET_MODE (SUBREG_REG (val)),
8024                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8025            && pos + len <= GET_MODE_BITSIZE (submode))
8026     {
8027       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8028       mode = submode;
8029       val = SUBREG_REG (val);
8030     }
8031   else if (mode == HImode && pos + len <= 8)
8032     {
8033       /* Small HImode tests can be converted to QImode.  */
8034       mode = QImode;
8035       val = gen_lowpart (QImode, val);
8036     }
8037
8038   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8039   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8040
8041   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8042 })
8043
8044 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8045 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8046 ;; this is relatively important trick.
8047 ;; Do the conversion only post-reload to avoid limiting of the register class
8048 ;; to QI regs.
8049 (define_split
8050   [(set (match_operand 0 "flags_reg_operand" "")
8051         (match_operator 1 "compare_operator"
8052           [(and (match_operand 2 "register_operand" "")
8053                 (match_operand 3 "const_int_operand" ""))
8054            (const_int 0)]))]
8055    "reload_completed
8056     && QI_REG_P (operands[2])
8057     && GET_MODE (operands[2]) != QImode
8058     && ((ix86_match_ccmode (insn, CCZmode)
8059          && !(INTVAL (operands[3]) & ~(255 << 8)))
8060         || (ix86_match_ccmode (insn, CCNOmode)
8061             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8062   [(set (match_dup 0)
8063         (match_op_dup 1
8064           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8065                    (match_dup 3))
8066            (const_int 0)]))]
8067   "operands[2] = gen_lowpart (SImode, operands[2]);
8068    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8069
8070 (define_split
8071   [(set (match_operand 0 "flags_reg_operand" "")
8072         (match_operator 1 "compare_operator"
8073           [(and (match_operand 2 "nonimmediate_operand" "")
8074                 (match_operand 3 "const_int_operand" ""))
8075            (const_int 0)]))]
8076    "reload_completed
8077     && GET_MODE (operands[2]) != QImode
8078     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8079     && ((ix86_match_ccmode (insn, CCZmode)
8080          && !(INTVAL (operands[3]) & ~255))
8081         || (ix86_match_ccmode (insn, CCNOmode)
8082             && !(INTVAL (operands[3]) & ~127)))"
8083   [(set (match_dup 0)
8084         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8085                          (const_int 0)]))]
8086   "operands[2] = gen_lowpart (QImode, operands[2]);
8087    operands[3] = gen_lowpart (QImode, operands[3]);")
8088
8089
8090 ;; %%% This used to optimize known byte-wide and operations to memory,
8091 ;; and sometimes to QImode registers.  If this is considered useful,
8092 ;; it should be done with splitters.
8093
8094 (define_expand "anddi3"
8095   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8096         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8097                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8098    (clobber (reg:CC FLAGS_REG))]
8099   "TARGET_64BIT"
8100   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8101
8102 (define_insn "*anddi_1_rex64"
8103   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8104         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8105                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8106    (clobber (reg:CC FLAGS_REG))]
8107   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8108 {
8109   switch (get_attr_type (insn))
8110     {
8111     case TYPE_IMOVX:
8112       {
8113         enum machine_mode mode;
8114
8115         if (GET_CODE (operands[2]) != CONST_INT)
8116           abort ();
8117         if (INTVAL (operands[2]) == 0xff)
8118           mode = QImode;
8119         else if (INTVAL (operands[2]) == 0xffff)
8120           mode = HImode;
8121         else
8122           abort ();
8123         
8124         operands[1] = gen_lowpart (mode, operands[1]);
8125         if (mode == QImode)
8126           return "movz{bq|x}\t{%1,%0|%0, %1}";
8127         else
8128           return "movz{wq|x}\t{%1,%0|%0, %1}";
8129       }
8130
8131     default:
8132       if (! rtx_equal_p (operands[0], operands[1]))
8133         abort ();
8134       if (get_attr_mode (insn) == MODE_SI)
8135         return "and{l}\t{%k2, %k0|%k0, %k2}";
8136       else
8137         return "and{q}\t{%2, %0|%0, %2}";
8138     }
8139 }
8140   [(set_attr "type" "alu,alu,alu,imovx")
8141    (set_attr "length_immediate" "*,*,*,0")
8142    (set_attr "mode" "SI,DI,DI,DI")])
8143
8144 (define_insn "*anddi_2"
8145   [(set (reg FLAGS_REG)
8146         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8147                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8148                  (const_int 0)))
8149    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8150         (and:DI (match_dup 1) (match_dup 2)))]
8151   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8152    && ix86_binary_operator_ok (AND, DImode, operands)"
8153   "@
8154    and{l}\t{%k2, %k0|%k0, %k2}
8155    and{q}\t{%2, %0|%0, %2}
8156    and{q}\t{%2, %0|%0, %2}"
8157   [(set_attr "type" "alu")
8158    (set_attr "mode" "SI,DI,DI")])
8159
8160 (define_expand "andsi3"
8161   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8162         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8163                 (match_operand:SI 2 "general_operand" "")))
8164    (clobber (reg:CC FLAGS_REG))]
8165   ""
8166   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8167
8168 (define_insn "*andsi_1"
8169   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8170         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8171                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8172    (clobber (reg:CC FLAGS_REG))]
8173   "ix86_binary_operator_ok (AND, SImode, operands)"
8174 {
8175   switch (get_attr_type (insn))
8176     {
8177     case TYPE_IMOVX:
8178       {
8179         enum machine_mode mode;
8180
8181         if (GET_CODE (operands[2]) != CONST_INT)
8182           abort ();
8183         if (INTVAL (operands[2]) == 0xff)
8184           mode = QImode;
8185         else if (INTVAL (operands[2]) == 0xffff)
8186           mode = HImode;
8187         else
8188           abort ();
8189         
8190         operands[1] = gen_lowpart (mode, operands[1]);
8191         if (mode == QImode)
8192           return "movz{bl|x}\t{%1,%0|%0, %1}";
8193         else
8194           return "movz{wl|x}\t{%1,%0|%0, %1}";
8195       }
8196
8197     default:
8198       if (! rtx_equal_p (operands[0], operands[1]))
8199         abort ();
8200       return "and{l}\t{%2, %0|%0, %2}";
8201     }
8202 }
8203   [(set_attr "type" "alu,alu,imovx")
8204    (set_attr "length_immediate" "*,*,0")
8205    (set_attr "mode" "SI")])
8206
8207 (define_split
8208   [(set (match_operand 0 "register_operand" "")
8209         (and (match_dup 0)
8210              (const_int -65536)))
8211    (clobber (reg:CC FLAGS_REG))]
8212   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8213   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8214   "operands[1] = gen_lowpart (HImode, operands[0]);")
8215
8216 (define_split
8217   [(set (match_operand 0 "ext_register_operand" "")
8218         (and (match_dup 0)
8219              (const_int -256)))
8220    (clobber (reg:CC FLAGS_REG))]
8221   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8222   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8223   "operands[1] = gen_lowpart (QImode, operands[0]);")
8224
8225 (define_split
8226   [(set (match_operand 0 "ext_register_operand" "")
8227         (and (match_dup 0)
8228              (const_int -65281)))
8229    (clobber (reg:CC FLAGS_REG))]
8230   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8231   [(parallel [(set (zero_extract:SI (match_dup 0)
8232                                     (const_int 8)
8233                                     (const_int 8))
8234                    (xor:SI 
8235                      (zero_extract:SI (match_dup 0)
8236                                       (const_int 8)
8237                                       (const_int 8))
8238                      (zero_extract:SI (match_dup 0)
8239                                       (const_int 8)
8240                                       (const_int 8))))
8241               (clobber (reg:CC FLAGS_REG))])]
8242   "operands[0] = gen_lowpart (SImode, operands[0]);")
8243
8244 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8245 (define_insn "*andsi_1_zext"
8246   [(set (match_operand:DI 0 "register_operand" "=r")
8247         (zero_extend:DI
8248           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8249                   (match_operand:SI 2 "general_operand" "rim"))))
8250    (clobber (reg:CC FLAGS_REG))]
8251   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8252   "and{l}\t{%2, %k0|%k0, %2}"
8253   [(set_attr "type" "alu")
8254    (set_attr "mode" "SI")])
8255
8256 (define_insn "*andsi_2"
8257   [(set (reg FLAGS_REG)
8258         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8259                          (match_operand:SI 2 "general_operand" "rim,ri"))
8260                  (const_int 0)))
8261    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8262         (and:SI (match_dup 1) (match_dup 2)))]
8263   "ix86_match_ccmode (insn, CCNOmode)
8264    && ix86_binary_operator_ok (AND, SImode, operands)"
8265   "and{l}\t{%2, %0|%0, %2}"
8266   [(set_attr "type" "alu")
8267    (set_attr "mode" "SI")])
8268
8269 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8270 (define_insn "*andsi_2_zext"
8271   [(set (reg FLAGS_REG)
8272         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8273                          (match_operand:SI 2 "general_operand" "rim"))
8274                  (const_int 0)))
8275    (set (match_operand:DI 0 "register_operand" "=r")
8276         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8277   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8278    && ix86_binary_operator_ok (AND, SImode, operands)"
8279   "and{l}\t{%2, %k0|%k0, %2}"
8280   [(set_attr "type" "alu")
8281    (set_attr "mode" "SI")])
8282
8283 (define_expand "andhi3"
8284   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8285         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8286                 (match_operand:HI 2 "general_operand" "")))
8287    (clobber (reg:CC FLAGS_REG))]
8288   "TARGET_HIMODE_MATH"
8289   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8290
8291 (define_insn "*andhi_1"
8292   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8293         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8294                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8295    (clobber (reg:CC FLAGS_REG))]
8296   "ix86_binary_operator_ok (AND, HImode, operands)"
8297 {
8298   switch (get_attr_type (insn))
8299     {
8300     case TYPE_IMOVX:
8301       if (GET_CODE (operands[2]) != CONST_INT)
8302         abort ();
8303       if (INTVAL (operands[2]) == 0xff)
8304         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8305       abort ();
8306
8307     default:
8308       if (! rtx_equal_p (operands[0], operands[1]))
8309         abort ();
8310
8311       return "and{w}\t{%2, %0|%0, %2}";
8312     }
8313 }
8314   [(set_attr "type" "alu,alu,imovx")
8315    (set_attr "length_immediate" "*,*,0")
8316    (set_attr "mode" "HI,HI,SI")])
8317
8318 (define_insn "*andhi_2"
8319   [(set (reg FLAGS_REG)
8320         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8321                          (match_operand:HI 2 "general_operand" "rim,ri"))
8322                  (const_int 0)))
8323    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8324         (and:HI (match_dup 1) (match_dup 2)))]
8325   "ix86_match_ccmode (insn, CCNOmode)
8326    && ix86_binary_operator_ok (AND, HImode, operands)"
8327   "and{w}\t{%2, %0|%0, %2}"
8328   [(set_attr "type" "alu")
8329    (set_attr "mode" "HI")])
8330
8331 (define_expand "andqi3"
8332   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8333         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8334                 (match_operand:QI 2 "general_operand" "")))
8335    (clobber (reg:CC FLAGS_REG))]
8336   "TARGET_QIMODE_MATH"
8337   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8338
8339 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8340 (define_insn "*andqi_1"
8341   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8342         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8343                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8344    (clobber (reg:CC FLAGS_REG))]
8345   "ix86_binary_operator_ok (AND, QImode, operands)"
8346   "@
8347    and{b}\t{%2, %0|%0, %2}
8348    and{b}\t{%2, %0|%0, %2}
8349    and{l}\t{%k2, %k0|%k0, %k2}"
8350   [(set_attr "type" "alu")
8351    (set_attr "mode" "QI,QI,SI")])
8352
8353 (define_insn "*andqi_1_slp"
8354   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8355         (and:QI (match_dup 0)
8356                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8357    (clobber (reg:CC FLAGS_REG))]
8358   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8359    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8360   "and{b}\t{%1, %0|%0, %1}"
8361   [(set_attr "type" "alu1")
8362    (set_attr "mode" "QI")])
8363
8364 (define_insn "*andqi_2_maybe_si"
8365   [(set (reg FLAGS_REG)
8366         (compare (and:QI
8367                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8368                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8369                  (const_int 0)))
8370    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8371         (and:QI (match_dup 1) (match_dup 2)))]
8372   "ix86_binary_operator_ok (AND, QImode, operands)
8373    && ix86_match_ccmode (insn,
8374                          GET_CODE (operands[2]) == CONST_INT
8375                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8376 {
8377   if (which_alternative == 2)
8378     {
8379       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8380         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8381       return "and{l}\t{%2, %k0|%k0, %2}";
8382     }
8383   return "and{b}\t{%2, %0|%0, %2}";
8384 }
8385   [(set_attr "type" "alu")
8386    (set_attr "mode" "QI,QI,SI")])
8387
8388 (define_insn "*andqi_2"
8389   [(set (reg FLAGS_REG)
8390         (compare (and:QI
8391                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8392                    (match_operand:QI 2 "general_operand" "qim,qi"))
8393                  (const_int 0)))
8394    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8395         (and:QI (match_dup 1) (match_dup 2)))]
8396   "ix86_match_ccmode (insn, CCNOmode)
8397    && ix86_binary_operator_ok (AND, QImode, operands)"
8398   "and{b}\t{%2, %0|%0, %2}"
8399   [(set_attr "type" "alu")
8400    (set_attr "mode" "QI")])
8401
8402 (define_insn "*andqi_2_slp"
8403   [(set (reg FLAGS_REG)
8404         (compare (and:QI
8405                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8406                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8407                  (const_int 0)))
8408    (set (strict_low_part (match_dup 0))
8409         (and:QI (match_dup 0) (match_dup 1)))]
8410   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8411    && ix86_match_ccmode (insn, CCNOmode)
8412    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8413   "and{b}\t{%1, %0|%0, %1}"
8414   [(set_attr "type" "alu1")
8415    (set_attr "mode" "QI")])
8416
8417 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8418 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8419 ;; for a QImode operand, which of course failed.
8420
8421 (define_insn "andqi_ext_0"
8422   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8423                          (const_int 8)
8424                          (const_int 8))
8425         (and:SI 
8426           (zero_extract:SI
8427             (match_operand 1 "ext_register_operand" "0")
8428             (const_int 8)
8429             (const_int 8))
8430           (match_operand 2 "const_int_operand" "n")))
8431    (clobber (reg:CC FLAGS_REG))]
8432   ""
8433   "and{b}\t{%2, %h0|%h0, %2}"
8434   [(set_attr "type" "alu")
8435    (set_attr "length_immediate" "1")
8436    (set_attr "mode" "QI")])
8437
8438 ;; Generated by peephole translating test to and.  This shows up
8439 ;; often in fp comparisons.
8440
8441 (define_insn "*andqi_ext_0_cc"
8442   [(set (reg FLAGS_REG)
8443         (compare
8444           (and:SI
8445             (zero_extract:SI
8446               (match_operand 1 "ext_register_operand" "0")
8447               (const_int 8)
8448               (const_int 8))
8449             (match_operand 2 "const_int_operand" "n"))
8450           (const_int 0)))
8451    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8452                          (const_int 8)
8453                          (const_int 8))
8454         (and:SI 
8455           (zero_extract:SI
8456             (match_dup 1)
8457             (const_int 8)
8458             (const_int 8))
8459           (match_dup 2)))]
8460   "ix86_match_ccmode (insn, CCNOmode)"
8461   "and{b}\t{%2, %h0|%h0, %2}"
8462   [(set_attr "type" "alu")
8463    (set_attr "length_immediate" "1")
8464    (set_attr "mode" "QI")])
8465
8466 (define_insn "*andqi_ext_1"
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_operand 1 "ext_register_operand" "0")
8473             (const_int 8)
8474             (const_int 8))
8475           (zero_extend:SI
8476             (match_operand:QI 2 "general_operand" "Qm"))))
8477    (clobber (reg:CC FLAGS_REG))]
8478   "!TARGET_64BIT"
8479   "and{b}\t{%2, %h0|%h0, %2}"
8480   [(set_attr "type" "alu")
8481    (set_attr "length_immediate" "0")
8482    (set_attr "mode" "QI")])
8483
8484 (define_insn "*andqi_ext_1_rex64"
8485   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8486                          (const_int 8)
8487                          (const_int 8))
8488         (and:SI 
8489           (zero_extract:SI
8490             (match_operand 1 "ext_register_operand" "0")
8491             (const_int 8)
8492             (const_int 8))
8493           (zero_extend:SI
8494             (match_operand 2 "ext_register_operand" "Q"))))
8495    (clobber (reg:CC FLAGS_REG))]
8496   "TARGET_64BIT"
8497   "and{b}\t{%2, %h0|%h0, %2}"
8498   [(set_attr "type" "alu")
8499    (set_attr "length_immediate" "0")
8500    (set_attr "mode" "QI")])
8501
8502 (define_insn "*andqi_ext_2"
8503   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8504                          (const_int 8)
8505                          (const_int 8))
8506         (and:SI
8507           (zero_extract:SI
8508             (match_operand 1 "ext_register_operand" "%0")
8509             (const_int 8)
8510             (const_int 8))
8511           (zero_extract:SI
8512             (match_operand 2 "ext_register_operand" "Q")
8513             (const_int 8)
8514             (const_int 8))))
8515    (clobber (reg:CC FLAGS_REG))]
8516   ""
8517   "and{b}\t{%h2, %h0|%h0, %h2}"
8518   [(set_attr "type" "alu")
8519    (set_attr "length_immediate" "0")
8520    (set_attr "mode" "QI")])
8521
8522 ;; Convert wide AND instructions with immediate operand to shorter QImode
8523 ;; equivalents when possible.
8524 ;; Don't do the splitting with memory operands, since it introduces risk
8525 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8526 ;; for size, but that can (should?) be handled by generic code instead.
8527 (define_split
8528   [(set (match_operand 0 "register_operand" "")
8529         (and (match_operand 1 "register_operand" "")
8530              (match_operand 2 "const_int_operand" "")))
8531    (clobber (reg:CC FLAGS_REG))]
8532    "reload_completed
8533     && QI_REG_P (operands[0])
8534     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8535     && !(~INTVAL (operands[2]) & ~(255 << 8))
8536     && GET_MODE (operands[0]) != QImode"
8537   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8538                    (and:SI (zero_extract:SI (match_dup 1)
8539                                             (const_int 8) (const_int 8))
8540                            (match_dup 2)))
8541               (clobber (reg:CC FLAGS_REG))])]
8542   "operands[0] = gen_lowpart (SImode, operands[0]);
8543    operands[1] = gen_lowpart (SImode, operands[1]);
8544    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8545
8546 ;; Since AND can be encoded with sign extended immediate, this is only
8547 ;; profitable when 7th bit is not set.
8548 (define_split
8549   [(set (match_operand 0 "register_operand" "")
8550         (and (match_operand 1 "general_operand" "")
8551              (match_operand 2 "const_int_operand" "")))
8552    (clobber (reg:CC FLAGS_REG))]
8553    "reload_completed
8554     && ANY_QI_REG_P (operands[0])
8555     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8556     && !(~INTVAL (operands[2]) & ~255)
8557     && !(INTVAL (operands[2]) & 128)
8558     && GET_MODE (operands[0]) != QImode"
8559   [(parallel [(set (strict_low_part (match_dup 0))
8560                    (and:QI (match_dup 1)
8561                            (match_dup 2)))
8562               (clobber (reg:CC FLAGS_REG))])]
8563   "operands[0] = gen_lowpart (QImode, operands[0]);
8564    operands[1] = gen_lowpart (QImode, operands[1]);
8565    operands[2] = gen_lowpart (QImode, operands[2]);")
8566 \f
8567 ;; Logical inclusive OR instructions
8568
8569 ;; %%% This used to optimize known byte-wide and operations to memory.
8570 ;; If this is considered useful, it should be done with splitters.
8571
8572 (define_expand "iordi3"
8573   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8574         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8575                 (match_operand:DI 2 "x86_64_general_operand" "")))
8576    (clobber (reg:CC FLAGS_REG))]
8577   "TARGET_64BIT"
8578   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8579
8580 (define_insn "*iordi_1_rex64"
8581   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8582         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8583                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8584    (clobber (reg:CC FLAGS_REG))]
8585   "TARGET_64BIT
8586    && ix86_binary_operator_ok (IOR, DImode, operands)"
8587   "or{q}\t{%2, %0|%0, %2}"
8588   [(set_attr "type" "alu")
8589    (set_attr "mode" "DI")])
8590
8591 (define_insn "*iordi_2_rex64"
8592   [(set (reg FLAGS_REG)
8593         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8594                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8595                  (const_int 0)))
8596    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8597         (ior:DI (match_dup 1) (match_dup 2)))]
8598   "TARGET_64BIT
8599    && ix86_match_ccmode (insn, CCNOmode)
8600    && ix86_binary_operator_ok (IOR, DImode, operands)"
8601   "or{q}\t{%2, %0|%0, %2}"
8602   [(set_attr "type" "alu")
8603    (set_attr "mode" "DI")])
8604
8605 (define_insn "*iordi_3_rex64"
8606   [(set (reg FLAGS_REG)
8607         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8608                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8609                  (const_int 0)))
8610    (clobber (match_scratch:DI 0 "=r"))]
8611   "TARGET_64BIT
8612    && ix86_match_ccmode (insn, CCNOmode)
8613    && ix86_binary_operator_ok (IOR, DImode, operands)"
8614   "or{q}\t{%2, %0|%0, %2}"
8615   [(set_attr "type" "alu")
8616    (set_attr "mode" "DI")])
8617
8618
8619 (define_expand "iorsi3"
8620   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8621         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8622                 (match_operand:SI 2 "general_operand" "")))
8623    (clobber (reg:CC FLAGS_REG))]
8624   ""
8625   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8626
8627 (define_insn "*iorsi_1"
8628   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8629         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8630                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8631    (clobber (reg:CC FLAGS_REG))]
8632   "ix86_binary_operator_ok (IOR, SImode, operands)"
8633   "or{l}\t{%2, %0|%0, %2}"
8634   [(set_attr "type" "alu")
8635    (set_attr "mode" "SI")])
8636
8637 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8638 (define_insn "*iorsi_1_zext"
8639   [(set (match_operand:DI 0 "register_operand" "=rm")
8640         (zero_extend:DI
8641           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8642                   (match_operand:SI 2 "general_operand" "rim"))))
8643    (clobber (reg:CC FLAGS_REG))]
8644   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8645   "or{l}\t{%2, %k0|%k0, %2}"
8646   [(set_attr "type" "alu")
8647    (set_attr "mode" "SI")])
8648
8649 (define_insn "*iorsi_1_zext_imm"
8650   [(set (match_operand:DI 0 "register_operand" "=rm")
8651         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8652                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8653    (clobber (reg:CC FLAGS_REG))]
8654   "TARGET_64BIT"
8655   "or{l}\t{%2, %k0|%k0, %2}"
8656   [(set_attr "type" "alu")
8657    (set_attr "mode" "SI")])
8658
8659 (define_insn "*iorsi_2"
8660   [(set (reg FLAGS_REG)
8661         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8662                          (match_operand:SI 2 "general_operand" "rim,ri"))
8663                  (const_int 0)))
8664    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8665         (ior:SI (match_dup 1) (match_dup 2)))]
8666   "ix86_match_ccmode (insn, CCNOmode)
8667    && ix86_binary_operator_ok (IOR, SImode, operands)"
8668   "or{l}\t{%2, %0|%0, %2}"
8669   [(set_attr "type" "alu")
8670    (set_attr "mode" "SI")])
8671
8672 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8673 ;; ??? Special case for immediate operand is missing - it is tricky.
8674 (define_insn "*iorsi_2_zext"
8675   [(set (reg FLAGS_REG)
8676         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8677                          (match_operand:SI 2 "general_operand" "rim"))
8678                  (const_int 0)))
8679    (set (match_operand:DI 0 "register_operand" "=r")
8680         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8681   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8682    && ix86_binary_operator_ok (IOR, SImode, operands)"
8683   "or{l}\t{%2, %k0|%k0, %2}"
8684   [(set_attr "type" "alu")
8685    (set_attr "mode" "SI")])
8686
8687 (define_insn "*iorsi_2_zext_imm"
8688   [(set (reg FLAGS_REG)
8689         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8690                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8691                  (const_int 0)))
8692    (set (match_operand:DI 0 "register_operand" "=r")
8693         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8694   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8695    && ix86_binary_operator_ok (IOR, SImode, operands)"
8696   "or{l}\t{%2, %k0|%k0, %2}"
8697   [(set_attr "type" "alu")
8698    (set_attr "mode" "SI")])
8699
8700 (define_insn "*iorsi_3"
8701   [(set (reg FLAGS_REG)
8702         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8703                          (match_operand:SI 2 "general_operand" "rim"))
8704                  (const_int 0)))
8705    (clobber (match_scratch:SI 0 "=r"))]
8706   "ix86_match_ccmode (insn, CCNOmode)
8707    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8708   "or{l}\t{%2, %0|%0, %2}"
8709   [(set_attr "type" "alu")
8710    (set_attr "mode" "SI")])
8711
8712 (define_expand "iorhi3"
8713   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8714         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8715                 (match_operand:HI 2 "general_operand" "")))
8716    (clobber (reg:CC FLAGS_REG))]
8717   "TARGET_HIMODE_MATH"
8718   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8719
8720 (define_insn "*iorhi_1"
8721   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8722         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8723                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8724    (clobber (reg:CC FLAGS_REG))]
8725   "ix86_binary_operator_ok (IOR, HImode, operands)"
8726   "or{w}\t{%2, %0|%0, %2}"
8727   [(set_attr "type" "alu")
8728    (set_attr "mode" "HI")])
8729
8730 (define_insn "*iorhi_2"
8731   [(set (reg FLAGS_REG)
8732         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8733                          (match_operand:HI 2 "general_operand" "rim,ri"))
8734                  (const_int 0)))
8735    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8736         (ior:HI (match_dup 1) (match_dup 2)))]
8737   "ix86_match_ccmode (insn, CCNOmode)
8738    && ix86_binary_operator_ok (IOR, HImode, operands)"
8739   "or{w}\t{%2, %0|%0, %2}"
8740   [(set_attr "type" "alu")
8741    (set_attr "mode" "HI")])
8742
8743 (define_insn "*iorhi_3"
8744   [(set (reg FLAGS_REG)
8745         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8746                          (match_operand:HI 2 "general_operand" "rim"))
8747                  (const_int 0)))
8748    (clobber (match_scratch:HI 0 "=r"))]
8749   "ix86_match_ccmode (insn, CCNOmode)
8750    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8751   "or{w}\t{%2, %0|%0, %2}"
8752   [(set_attr "type" "alu")
8753    (set_attr "mode" "HI")])
8754
8755 (define_expand "iorqi3"
8756   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8757         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8758                 (match_operand:QI 2 "general_operand" "")))
8759    (clobber (reg:CC FLAGS_REG))]
8760   "TARGET_QIMODE_MATH"
8761   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8762
8763 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8764 (define_insn "*iorqi_1"
8765   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8766         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8767                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8768    (clobber (reg:CC FLAGS_REG))]
8769   "ix86_binary_operator_ok (IOR, QImode, operands)"
8770   "@
8771    or{b}\t{%2, %0|%0, %2}
8772    or{b}\t{%2, %0|%0, %2}
8773    or{l}\t{%k2, %k0|%k0, %k2}"
8774   [(set_attr "type" "alu")
8775    (set_attr "mode" "QI,QI,SI")])
8776
8777 (define_insn "*iorqi_1_slp"
8778   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8779         (ior:QI (match_dup 0)
8780                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8781    (clobber (reg:CC FLAGS_REG))]
8782   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8783    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8784   "or{b}\t{%1, %0|%0, %1}"
8785   [(set_attr "type" "alu1")
8786    (set_attr "mode" "QI")])
8787
8788 (define_insn "*iorqi_2"
8789   [(set (reg FLAGS_REG)
8790         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8791                          (match_operand:QI 2 "general_operand" "qim,qi"))
8792                  (const_int 0)))
8793    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8794         (ior:QI (match_dup 1) (match_dup 2)))]
8795   "ix86_match_ccmode (insn, CCNOmode)
8796    && ix86_binary_operator_ok (IOR, QImode, operands)"
8797   "or{b}\t{%2, %0|%0, %2}"
8798   [(set_attr "type" "alu")
8799    (set_attr "mode" "QI")])
8800
8801 (define_insn "*iorqi_2_slp"
8802   [(set (reg FLAGS_REG)
8803         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8804                          (match_operand:QI 1 "general_operand" "qim,qi"))
8805                  (const_int 0)))
8806    (set (strict_low_part (match_dup 0))
8807         (ior:QI (match_dup 0) (match_dup 1)))]
8808   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8809    && ix86_match_ccmode (insn, CCNOmode)
8810    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8811   "or{b}\t{%1, %0|%0, %1}"
8812   [(set_attr "type" "alu1")
8813    (set_attr "mode" "QI")])
8814
8815 (define_insn "*iorqi_3"
8816   [(set (reg FLAGS_REG)
8817         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8818                          (match_operand:QI 2 "general_operand" "qim"))
8819                  (const_int 0)))
8820    (clobber (match_scratch:QI 0 "=q"))]
8821   "ix86_match_ccmode (insn, CCNOmode)
8822    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8823   "or{b}\t{%2, %0|%0, %2}"
8824   [(set_attr "type" "alu")
8825    (set_attr "mode" "QI")])
8826
8827 (define_insn "iorqi_ext_0"
8828   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8829                          (const_int 8)
8830                          (const_int 8))
8831         (ior:SI 
8832           (zero_extract:SI
8833             (match_operand 1 "ext_register_operand" "0")
8834             (const_int 8)
8835             (const_int 8))
8836           (match_operand 2 "const_int_operand" "n")))
8837    (clobber (reg:CC FLAGS_REG))]
8838   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8839   "or{b}\t{%2, %h0|%h0, %2}"
8840   [(set_attr "type" "alu")
8841    (set_attr "length_immediate" "1")
8842    (set_attr "mode" "QI")])
8843
8844 (define_insn "*iorqi_ext_1"
8845   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8846                          (const_int 8)
8847                          (const_int 8))
8848         (ior:SI 
8849           (zero_extract:SI
8850             (match_operand 1 "ext_register_operand" "0")
8851             (const_int 8)
8852             (const_int 8))
8853           (zero_extend:SI
8854             (match_operand:QI 2 "general_operand" "Qm"))))
8855    (clobber (reg:CC FLAGS_REG))]
8856   "!TARGET_64BIT
8857    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8858   "or{b}\t{%2, %h0|%h0, %2}"
8859   [(set_attr "type" "alu")
8860    (set_attr "length_immediate" "0")
8861    (set_attr "mode" "QI")])
8862
8863 (define_insn "*iorqi_ext_1_rex64"
8864   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8865                          (const_int 8)
8866                          (const_int 8))
8867         (ior:SI 
8868           (zero_extract:SI
8869             (match_operand 1 "ext_register_operand" "0")
8870             (const_int 8)
8871             (const_int 8))
8872           (zero_extend:SI
8873             (match_operand 2 "ext_register_operand" "Q"))))
8874    (clobber (reg:CC FLAGS_REG))]
8875   "TARGET_64BIT
8876    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8877   "or{b}\t{%2, %h0|%h0, %2}"
8878   [(set_attr "type" "alu")
8879    (set_attr "length_immediate" "0")
8880    (set_attr "mode" "QI")])
8881
8882 (define_insn "*iorqi_ext_2"
8883   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8884                          (const_int 8)
8885                          (const_int 8))
8886         (ior:SI 
8887           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8888                            (const_int 8)
8889                            (const_int 8))
8890           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8891                            (const_int 8)
8892                            (const_int 8))))
8893    (clobber (reg:CC FLAGS_REG))]
8894   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8895   "ior{b}\t{%h2, %h0|%h0, %h2}"
8896   [(set_attr "type" "alu")
8897    (set_attr "length_immediate" "0")
8898    (set_attr "mode" "QI")])
8899
8900 (define_split
8901   [(set (match_operand 0 "register_operand" "")
8902         (ior (match_operand 1 "register_operand" "")
8903              (match_operand 2 "const_int_operand" "")))
8904    (clobber (reg:CC FLAGS_REG))]
8905    "reload_completed
8906     && QI_REG_P (operands[0])
8907     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8908     && !(INTVAL (operands[2]) & ~(255 << 8))
8909     && GET_MODE (operands[0]) != QImode"
8910   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8911                    (ior:SI (zero_extract:SI (match_dup 1)
8912                                             (const_int 8) (const_int 8))
8913                            (match_dup 2)))
8914               (clobber (reg:CC FLAGS_REG))])]
8915   "operands[0] = gen_lowpart (SImode, operands[0]);
8916    operands[1] = gen_lowpart (SImode, operands[1]);
8917    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8918
8919 ;; Since OR can be encoded with sign extended immediate, this is only
8920 ;; profitable when 7th bit is set.
8921 (define_split
8922   [(set (match_operand 0 "register_operand" "")
8923         (ior (match_operand 1 "general_operand" "")
8924              (match_operand 2 "const_int_operand" "")))
8925    (clobber (reg:CC FLAGS_REG))]
8926    "reload_completed
8927     && ANY_QI_REG_P (operands[0])
8928     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8929     && !(INTVAL (operands[2]) & ~255)
8930     && (INTVAL (operands[2]) & 128)
8931     && GET_MODE (operands[0]) != QImode"
8932   [(parallel [(set (strict_low_part (match_dup 0))
8933                    (ior:QI (match_dup 1)
8934                            (match_dup 2)))
8935               (clobber (reg:CC FLAGS_REG))])]
8936   "operands[0] = gen_lowpart (QImode, operands[0]);
8937    operands[1] = gen_lowpart (QImode, operands[1]);
8938    operands[2] = gen_lowpart (QImode, operands[2]);")
8939 \f
8940 ;; Logical XOR instructions
8941
8942 ;; %%% This used to optimize known byte-wide and operations to memory.
8943 ;; If this is considered useful, it should be done with splitters.
8944
8945 (define_expand "xordi3"
8946   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8947         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8948                 (match_operand:DI 2 "x86_64_general_operand" "")))
8949    (clobber (reg:CC FLAGS_REG))]
8950   "TARGET_64BIT"
8951   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8952
8953 (define_insn "*xordi_1_rex64"
8954   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8955         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8956                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8957    (clobber (reg:CC FLAGS_REG))]
8958   "TARGET_64BIT
8959    && ix86_binary_operator_ok (XOR, DImode, operands)"
8960   "@
8961    xor{q}\t{%2, %0|%0, %2}
8962    xor{q}\t{%2, %0|%0, %2}"
8963   [(set_attr "type" "alu")
8964    (set_attr "mode" "DI,DI")])
8965
8966 (define_insn "*xordi_2_rex64"
8967   [(set (reg FLAGS_REG)
8968         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8969                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8970                  (const_int 0)))
8971    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8972         (xor:DI (match_dup 1) (match_dup 2)))]
8973   "TARGET_64BIT
8974    && ix86_match_ccmode (insn, CCNOmode)
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_3_rex64"
8983   [(set (reg FLAGS_REG)
8984         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8985                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8986                  (const_int 0)))
8987    (clobber (match_scratch:DI 0 "=r"))]
8988   "TARGET_64BIT
8989    && ix86_match_ccmode (insn, CCNOmode)
8990    && ix86_binary_operator_ok (XOR, DImode, operands)"
8991   "xor{q}\t{%2, %0|%0, %2}"
8992   [(set_attr "type" "alu")
8993    (set_attr "mode" "DI")])
8994
8995 (define_expand "xorsi3"
8996   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8997         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8998                 (match_operand:SI 2 "general_operand" "")))
8999    (clobber (reg:CC FLAGS_REG))]
9000   ""
9001   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9002
9003 (define_insn "*xorsi_1"
9004   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9005         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9006                 (match_operand:SI 2 "general_operand" "ri,rm")))
9007    (clobber (reg:CC FLAGS_REG))]
9008   "ix86_binary_operator_ok (XOR, SImode, operands)"
9009   "xor{l}\t{%2, %0|%0, %2}"
9010   [(set_attr "type" "alu")
9011    (set_attr "mode" "SI")])
9012
9013 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9014 ;; Add speccase for immediates
9015 (define_insn "*xorsi_1_zext"
9016   [(set (match_operand:DI 0 "register_operand" "=r")
9017         (zero_extend:DI
9018           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9019                   (match_operand:SI 2 "general_operand" "rim"))))
9020    (clobber (reg:CC FLAGS_REG))]
9021   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9022   "xor{l}\t{%2, %k0|%k0, %2}"
9023   [(set_attr "type" "alu")
9024    (set_attr "mode" "SI")])
9025
9026 (define_insn "*xorsi_1_zext_imm"
9027   [(set (match_operand:DI 0 "register_operand" "=r")
9028         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9029                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9030    (clobber (reg:CC FLAGS_REG))]
9031   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9032   "xor{l}\t{%2, %k0|%k0, %2}"
9033   [(set_attr "type" "alu")
9034    (set_attr "mode" "SI")])
9035
9036 (define_insn "*xorsi_2"
9037   [(set (reg FLAGS_REG)
9038         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9039                          (match_operand:SI 2 "general_operand" "rim,ri"))
9040                  (const_int 0)))
9041    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9042         (xor:SI (match_dup 1) (match_dup 2)))]
9043   "ix86_match_ccmode (insn, CCNOmode)
9044    && ix86_binary_operator_ok (XOR, SImode, operands)"
9045   "xor{l}\t{%2, %0|%0, %2}"
9046   [(set_attr "type" "alu")
9047    (set_attr "mode" "SI")])
9048
9049 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9050 ;; ??? Special case for immediate operand is missing - it is tricky.
9051 (define_insn "*xorsi_2_zext"
9052   [(set (reg FLAGS_REG)
9053         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9054                          (match_operand:SI 2 "general_operand" "rim"))
9055                  (const_int 0)))
9056    (set (match_operand:DI 0 "register_operand" "=r")
9057         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9058   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9059    && ix86_binary_operator_ok (XOR, SImode, operands)"
9060   "xor{l}\t{%2, %k0|%k0, %2}"
9061   [(set_attr "type" "alu")
9062    (set_attr "mode" "SI")])
9063
9064 (define_insn "*xorsi_2_zext_imm"
9065   [(set (reg FLAGS_REG)
9066         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9067                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9068                  (const_int 0)))
9069    (set (match_operand:DI 0 "register_operand" "=r")
9070         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9071   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9072    && ix86_binary_operator_ok (XOR, SImode, operands)"
9073   "xor{l}\t{%2, %k0|%k0, %2}"
9074   [(set_attr "type" "alu")
9075    (set_attr "mode" "SI")])
9076
9077 (define_insn "*xorsi_3"
9078   [(set (reg FLAGS_REG)
9079         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9080                          (match_operand:SI 2 "general_operand" "rim"))
9081                  (const_int 0)))
9082    (clobber (match_scratch:SI 0 "=r"))]
9083   "ix86_match_ccmode (insn, CCNOmode)
9084    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9085   "xor{l}\t{%2, %0|%0, %2}"
9086   [(set_attr "type" "alu")
9087    (set_attr "mode" "SI")])
9088
9089 (define_expand "xorhi3"
9090   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9091         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9092                 (match_operand:HI 2 "general_operand" "")))
9093    (clobber (reg:CC FLAGS_REG))]
9094   "TARGET_HIMODE_MATH"
9095   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9096
9097 (define_insn "*xorhi_1"
9098   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9099         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9100                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9101    (clobber (reg:CC FLAGS_REG))]
9102   "ix86_binary_operator_ok (XOR, HImode, operands)"
9103   "xor{w}\t{%2, %0|%0, %2}"
9104   [(set_attr "type" "alu")
9105    (set_attr "mode" "HI")])
9106
9107 (define_insn "*xorhi_2"
9108   [(set (reg FLAGS_REG)
9109         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9110                          (match_operand:HI 2 "general_operand" "rim,ri"))
9111                  (const_int 0)))
9112    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9113         (xor:HI (match_dup 1) (match_dup 2)))]
9114   "ix86_match_ccmode (insn, CCNOmode)
9115    && ix86_binary_operator_ok (XOR, HImode, operands)"
9116   "xor{w}\t{%2, %0|%0, %2}"
9117   [(set_attr "type" "alu")
9118    (set_attr "mode" "HI")])
9119
9120 (define_insn "*xorhi_3"
9121   [(set (reg FLAGS_REG)
9122         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9123                          (match_operand:HI 2 "general_operand" "rim"))
9124                  (const_int 0)))
9125    (clobber (match_scratch:HI 0 "=r"))]
9126   "ix86_match_ccmode (insn, CCNOmode)
9127    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9128   "xor{w}\t{%2, %0|%0, %2}"
9129   [(set_attr "type" "alu")
9130    (set_attr "mode" "HI")])
9131
9132 (define_expand "xorqi3"
9133   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9134         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9135                 (match_operand:QI 2 "general_operand" "")))
9136    (clobber (reg:CC FLAGS_REG))]
9137   "TARGET_QIMODE_MATH"
9138   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9139
9140 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9141 (define_insn "*xorqi_1"
9142   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9143         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9144                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9145    (clobber (reg:CC FLAGS_REG))]
9146   "ix86_binary_operator_ok (XOR, QImode, operands)"
9147   "@
9148    xor{b}\t{%2, %0|%0, %2}
9149    xor{b}\t{%2, %0|%0, %2}
9150    xor{l}\t{%k2, %k0|%k0, %k2}"
9151   [(set_attr "type" "alu")
9152    (set_attr "mode" "QI,QI,SI")])
9153
9154 (define_insn "*xorqi_1_slp"
9155   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9156         (xor:QI (match_dup 0)
9157                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9158    (clobber (reg:CC FLAGS_REG))]
9159   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9160    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9161   "xor{b}\t{%1, %0|%0, %1}"
9162   [(set_attr "type" "alu1")
9163    (set_attr "mode" "QI")])
9164
9165 (define_insn "xorqi_ext_0"
9166   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9167                          (const_int 8)
9168                          (const_int 8))
9169         (xor:SI 
9170           (zero_extract:SI
9171             (match_operand 1 "ext_register_operand" "0")
9172             (const_int 8)
9173             (const_int 8))
9174           (match_operand 2 "const_int_operand" "n")))
9175    (clobber (reg:CC FLAGS_REG))]
9176   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9177   "xor{b}\t{%2, %h0|%h0, %2}"
9178   [(set_attr "type" "alu")
9179    (set_attr "length_immediate" "1")
9180    (set_attr "mode" "QI")])
9181
9182 (define_insn "*xorqi_ext_1"
9183   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9184                          (const_int 8)
9185                          (const_int 8))
9186         (xor:SI 
9187           (zero_extract:SI
9188             (match_operand 1 "ext_register_operand" "0")
9189             (const_int 8)
9190             (const_int 8))
9191           (zero_extend:SI
9192             (match_operand:QI 2 "general_operand" "Qm"))))
9193    (clobber (reg:CC FLAGS_REG))]
9194   "!TARGET_64BIT
9195    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9196   "xor{b}\t{%2, %h0|%h0, %2}"
9197   [(set_attr "type" "alu")
9198    (set_attr "length_immediate" "0")
9199    (set_attr "mode" "QI")])
9200
9201 (define_insn "*xorqi_ext_1_rex64"
9202   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9203                          (const_int 8)
9204                          (const_int 8))
9205         (xor:SI 
9206           (zero_extract:SI
9207             (match_operand 1 "ext_register_operand" "0")
9208             (const_int 8)
9209             (const_int 8))
9210           (zero_extend:SI
9211             (match_operand 2 "ext_register_operand" "Q"))))
9212    (clobber (reg:CC FLAGS_REG))]
9213   "TARGET_64BIT
9214    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9215   "xor{b}\t{%2, %h0|%h0, %2}"
9216   [(set_attr "type" "alu")
9217    (set_attr "length_immediate" "0")
9218    (set_attr "mode" "QI")])
9219
9220 (define_insn "*xorqi_ext_2"
9221   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9222                          (const_int 8)
9223                          (const_int 8))
9224         (xor:SI 
9225           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9226                            (const_int 8)
9227                            (const_int 8))
9228           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9229                            (const_int 8)
9230                            (const_int 8))))
9231    (clobber (reg:CC FLAGS_REG))]
9232   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9233   "xor{b}\t{%h2, %h0|%h0, %h2}"
9234   [(set_attr "type" "alu")
9235    (set_attr "length_immediate" "0")
9236    (set_attr "mode" "QI")])
9237
9238 (define_insn "*xorqi_cc_1"
9239   [(set (reg FLAGS_REG)
9240         (compare
9241           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9242                   (match_operand:QI 2 "general_operand" "qim,qi"))
9243           (const_int 0)))
9244    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9245         (xor:QI (match_dup 1) (match_dup 2)))]
9246   "ix86_match_ccmode (insn, CCNOmode)
9247    && ix86_binary_operator_ok (XOR, QImode, operands)"
9248   "xor{b}\t{%2, %0|%0, %2}"
9249   [(set_attr "type" "alu")
9250    (set_attr "mode" "QI")])
9251
9252 (define_insn "*xorqi_2_slp"
9253   [(set (reg FLAGS_REG)
9254         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9255                          (match_operand:QI 1 "general_operand" "qim,qi"))
9256                  (const_int 0)))
9257    (set (strict_low_part (match_dup 0))
9258         (xor:QI (match_dup 0) (match_dup 1)))]
9259   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9260    && ix86_match_ccmode (insn, CCNOmode)
9261    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9262   "xor{b}\t{%1, %0|%0, %1}"
9263   [(set_attr "type" "alu1")
9264    (set_attr "mode" "QI")])
9265
9266 (define_insn "*xorqi_cc_2"
9267   [(set (reg FLAGS_REG)
9268         (compare
9269           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9270                   (match_operand:QI 2 "general_operand" "qim"))
9271           (const_int 0)))
9272    (clobber (match_scratch:QI 0 "=q"))]
9273   "ix86_match_ccmode (insn, CCNOmode)
9274    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9275   "xor{b}\t{%2, %0|%0, %2}"
9276   [(set_attr "type" "alu")
9277    (set_attr "mode" "QI")])
9278
9279 (define_insn "*xorqi_cc_ext_1"
9280   [(set (reg FLAGS_REG)
9281         (compare
9282           (xor:SI
9283             (zero_extract:SI
9284               (match_operand 1 "ext_register_operand" "0")
9285               (const_int 8)
9286               (const_int 8))
9287             (match_operand:QI 2 "general_operand" "qmn"))
9288           (const_int 0)))
9289    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9290                          (const_int 8)
9291                          (const_int 8))
9292         (xor:SI 
9293           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9294           (match_dup 2)))]
9295   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9296   "xor{b}\t{%2, %h0|%h0, %2}"
9297   [(set_attr "type" "alu")
9298    (set_attr "mode" "QI")])
9299
9300 (define_insn "*xorqi_cc_ext_1_rex64"
9301   [(set (reg FLAGS_REG)
9302         (compare
9303           (xor:SI
9304             (zero_extract:SI
9305               (match_operand 1 "ext_register_operand" "0")
9306               (const_int 8)
9307               (const_int 8))
9308             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9309           (const_int 0)))
9310    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9311                          (const_int 8)
9312                          (const_int 8))
9313         (xor:SI 
9314           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9315           (match_dup 2)))]
9316   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9317   "xor{b}\t{%2, %h0|%h0, %2}"
9318   [(set_attr "type" "alu")
9319    (set_attr "mode" "QI")])
9320
9321 (define_expand "xorqi_cc_ext_1"
9322   [(parallel [
9323      (set (reg:CCNO FLAGS_REG)
9324           (compare:CCNO
9325             (xor:SI
9326               (zero_extract:SI
9327                 (match_operand 1 "ext_register_operand" "")
9328                 (const_int 8)
9329                 (const_int 8))
9330               (match_operand:QI 2 "general_operand" ""))
9331             (const_int 0)))
9332      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9333                            (const_int 8)
9334                            (const_int 8))
9335           (xor:SI 
9336             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9337             (match_dup 2)))])]
9338   ""
9339   "")
9340
9341 (define_split
9342   [(set (match_operand 0 "register_operand" "")
9343         (xor (match_operand 1 "register_operand" "")
9344              (match_operand 2 "const_int_operand" "")))
9345    (clobber (reg:CC FLAGS_REG))]
9346    "reload_completed
9347     && QI_REG_P (operands[0])
9348     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9349     && !(INTVAL (operands[2]) & ~(255 << 8))
9350     && GET_MODE (operands[0]) != QImode"
9351   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9352                    (xor:SI (zero_extract:SI (match_dup 1)
9353                                             (const_int 8) (const_int 8))
9354                            (match_dup 2)))
9355               (clobber (reg:CC FLAGS_REG))])]
9356   "operands[0] = gen_lowpart (SImode, operands[0]);
9357    operands[1] = gen_lowpart (SImode, operands[1]);
9358    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9359
9360 ;; Since XOR can be encoded with sign extended immediate, this is only
9361 ;; profitable when 7th bit is set.
9362 (define_split
9363   [(set (match_operand 0 "register_operand" "")
9364         (xor (match_operand 1 "general_operand" "")
9365              (match_operand 2 "const_int_operand" "")))
9366    (clobber (reg:CC FLAGS_REG))]
9367    "reload_completed
9368     && ANY_QI_REG_P (operands[0])
9369     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9370     && !(INTVAL (operands[2]) & ~255)
9371     && (INTVAL (operands[2]) & 128)
9372     && GET_MODE (operands[0]) != QImode"
9373   [(parallel [(set (strict_low_part (match_dup 0))
9374                    (xor:QI (match_dup 1)
9375                            (match_dup 2)))
9376               (clobber (reg:CC FLAGS_REG))])]
9377   "operands[0] = gen_lowpart (QImode, operands[0]);
9378    operands[1] = gen_lowpart (QImode, operands[1]);
9379    operands[2] = gen_lowpart (QImode, operands[2]);")
9380 \f
9381 ;; Negation instructions
9382
9383 (define_expand "negdi2"
9384   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9385                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9386               (clobber (reg:CC FLAGS_REG))])]
9387   ""
9388   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9389
9390 (define_insn "*negdi2_1"
9391   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9392         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9393    (clobber (reg:CC FLAGS_REG))]
9394   "!TARGET_64BIT
9395    && ix86_unary_operator_ok (NEG, DImode, operands)"
9396   "#")
9397
9398 (define_split
9399   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9400         (neg:DI (match_operand:DI 1 "general_operand" "")))
9401    (clobber (reg:CC FLAGS_REG))]
9402   "!TARGET_64BIT && reload_completed"
9403   [(parallel
9404     [(set (reg:CCZ FLAGS_REG)
9405           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9406      (set (match_dup 0) (neg:SI (match_dup 2)))])
9407    (parallel
9408     [(set (match_dup 1)
9409           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9410                             (match_dup 3))
9411                    (const_int 0)))
9412      (clobber (reg:CC FLAGS_REG))])
9413    (parallel
9414     [(set (match_dup 1)
9415           (neg:SI (match_dup 1)))
9416      (clobber (reg:CC FLAGS_REG))])]
9417   "split_di (operands+1, 1, operands+2, operands+3);
9418    split_di (operands+0, 1, operands+0, operands+1);")
9419
9420 (define_insn "*negdi2_1_rex64"
9421   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9422         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9423    (clobber (reg:CC FLAGS_REG))]
9424   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9425   "neg{q}\t%0"
9426   [(set_attr "type" "negnot")
9427    (set_attr "mode" "DI")])
9428
9429 ;; The problem with neg is that it does not perform (compare x 0),
9430 ;; it really performs (compare 0 x), which leaves us with the zero
9431 ;; flag being the only useful item.
9432
9433 (define_insn "*negdi2_cmpz_rex64"
9434   [(set (reg:CCZ FLAGS_REG)
9435         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9436                      (const_int 0)))
9437    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9438         (neg:DI (match_dup 1)))]
9439   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9440   "neg{q}\t%0"
9441   [(set_attr "type" "negnot")
9442    (set_attr "mode" "DI")])
9443
9444
9445 (define_expand "negsi2"
9446   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9447                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9448               (clobber (reg:CC FLAGS_REG))])]
9449   ""
9450   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9451
9452 (define_insn "*negsi2_1"
9453   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9454         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9455    (clobber (reg:CC FLAGS_REG))]
9456   "ix86_unary_operator_ok (NEG, SImode, operands)"
9457   "neg{l}\t%0"
9458   [(set_attr "type" "negnot")
9459    (set_attr "mode" "SI")])
9460
9461 ;; Combine is quite creative about this pattern.
9462 (define_insn "*negsi2_1_zext"
9463   [(set (match_operand:DI 0 "register_operand" "=r")
9464         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9465                                         (const_int 32)))
9466                      (const_int 32)))
9467    (clobber (reg:CC FLAGS_REG))]
9468   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9469   "neg{l}\t%k0"
9470   [(set_attr "type" "negnot")
9471    (set_attr "mode" "SI")])
9472
9473 ;; The problem with neg is that it does not perform (compare x 0),
9474 ;; it really performs (compare 0 x), which leaves us with the zero
9475 ;; flag being the only useful item.
9476
9477 (define_insn "*negsi2_cmpz"
9478   [(set (reg:CCZ FLAGS_REG)
9479         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9480                      (const_int 0)))
9481    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9482         (neg:SI (match_dup 1)))]
9483   "ix86_unary_operator_ok (NEG, SImode, operands)"
9484   "neg{l}\t%0"
9485   [(set_attr "type" "negnot")
9486    (set_attr "mode" "SI")])
9487
9488 (define_insn "*negsi2_cmpz_zext"
9489   [(set (reg:CCZ FLAGS_REG)
9490         (compare:CCZ (lshiftrt:DI
9491                        (neg:DI (ashift:DI
9492                                  (match_operand:DI 1 "register_operand" "0")
9493                                  (const_int 32)))
9494                        (const_int 32))
9495                      (const_int 0)))
9496    (set (match_operand:DI 0 "register_operand" "=r")
9497         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9498                                         (const_int 32)))
9499                      (const_int 32)))]
9500   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9501   "neg{l}\t%k0"
9502   [(set_attr "type" "negnot")
9503    (set_attr "mode" "SI")])
9504
9505 (define_expand "neghi2"
9506   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9507                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9508               (clobber (reg:CC FLAGS_REG))])]
9509   "TARGET_HIMODE_MATH"
9510   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9511
9512 (define_insn "*neghi2_1"
9513   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9514         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9515    (clobber (reg:CC FLAGS_REG))]
9516   "ix86_unary_operator_ok (NEG, HImode, operands)"
9517   "neg{w}\t%0"
9518   [(set_attr "type" "negnot")
9519    (set_attr "mode" "HI")])
9520
9521 (define_insn "*neghi2_cmpz"
9522   [(set (reg:CCZ FLAGS_REG)
9523         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9524                      (const_int 0)))
9525    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9526         (neg:HI (match_dup 1)))]
9527   "ix86_unary_operator_ok (NEG, HImode, operands)"
9528   "neg{w}\t%0"
9529   [(set_attr "type" "negnot")
9530    (set_attr "mode" "HI")])
9531
9532 (define_expand "negqi2"
9533   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9534                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9535               (clobber (reg:CC FLAGS_REG))])]
9536   "TARGET_QIMODE_MATH"
9537   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9538
9539 (define_insn "*negqi2_1"
9540   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9541         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9542    (clobber (reg:CC FLAGS_REG))]
9543   "ix86_unary_operator_ok (NEG, QImode, operands)"
9544   "neg{b}\t%0"
9545   [(set_attr "type" "negnot")
9546    (set_attr "mode" "QI")])
9547
9548 (define_insn "*negqi2_cmpz"
9549   [(set (reg:CCZ FLAGS_REG)
9550         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9551                      (const_int 0)))
9552    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9553         (neg:QI (match_dup 1)))]
9554   "ix86_unary_operator_ok (NEG, QImode, operands)"
9555   "neg{b}\t%0"
9556   [(set_attr "type" "negnot")
9557    (set_attr "mode" "QI")])
9558
9559 ;; Changing of sign for FP values is doable using integer unit too.
9560
9561 (define_expand "negsf2"
9562   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9563         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9564   "TARGET_80387 || TARGET_SSE_MATH"
9565   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9566
9567 (define_expand "abssf2"
9568   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9569         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9570   "TARGET_80387 || TARGET_SSE_MATH"
9571   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9572
9573 (define_insn "*absnegsf2_mixed"
9574   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#fr,x#fr,f#xr,rm#xf")
9575         (match_operator:SF 3 "absneg_operator"
9576           [(match_operand:SF 1 "nonimmediate_operand" "0    ,x#fr,0   ,0")]))
9577    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm   ,0   ,X   ,X"))
9578    (clobber (reg:CC FLAGS_REG))]
9579   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9580    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9581   "#")
9582
9583 (define_insn "*absnegsf2_sse"
9584   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#r,x#r,rm#x")
9585         (match_operator:SF 3 "absneg_operator"
9586           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#r,0")]))
9587    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X"))
9588    (clobber (reg:CC FLAGS_REG))]
9589   "TARGET_SSE_MATH
9590    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9591   "#")
9592
9593 (define_insn "*absnegsf2_i387"
9594   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9595         (match_operator:SF 3 "absneg_operator"
9596           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9597    (use (match_operand 2 "" ""))
9598    (clobber (reg:CC FLAGS_REG))]
9599   "TARGET_80387 && !TARGET_SSE_MATH
9600    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9601   "#")
9602
9603 (define_expand "negdf2"
9604   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9605         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9606   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9607   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9608
9609 (define_expand "absdf2"
9610   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9611         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9612   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9613   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9614
9615 (define_insn "*absnegdf2_mixed"
9616   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#fr,Y#fr,f#Yr,rm#Yf")
9617         (match_operator:DF 3 "absneg_operator"
9618           [(match_operand:DF 1 "nonimmediate_operand" "0    ,Y#fr,0   ,0")]))
9619    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym   ,0   ,X   ,X"))
9620    (clobber (reg:CC FLAGS_REG))]
9621   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9622    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9623   "#")
9624
9625 (define_insn "*absnegdf2_sse"
9626   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#r,Y#r,rm#Y")
9627         (match_operator:DF 3 "absneg_operator"
9628           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#r,0")]))
9629    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X"))
9630    (clobber (reg:CC FLAGS_REG))]
9631   "TARGET_SSE2 && TARGET_SSE_MATH
9632    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9633   "#")
9634
9635 (define_insn "*absnegdf2_i387"
9636   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9637         (match_operator:DF 3 "absneg_operator"
9638           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9639    (use (match_operand 2 "" ""))
9640    (clobber (reg:CC FLAGS_REG))]
9641   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9642    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9643   "#")
9644
9645 (define_expand "negxf2"
9646   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9647         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9648   "TARGET_80387"
9649   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9650
9651 (define_expand "absxf2"
9652   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9653         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9654   "TARGET_80387"
9655   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9656
9657 (define_insn "*absnegxf2_i387"
9658   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9659         (match_operator:XF 3 "absneg_operator"
9660           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9661    (use (match_operand 2 "" ""))
9662    (clobber (reg:CC FLAGS_REG))]
9663   "TARGET_80387
9664    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9665   "#")
9666
9667 ;; Splitters for fp abs and neg.
9668
9669 (define_split
9670   [(set (match_operand 0 "fp_register_operand" "")
9671         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9672    (use (match_operand 2 "" ""))
9673    (clobber (reg:CC FLAGS_REG))]
9674   "reload_completed"
9675   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9676
9677 (define_split
9678   [(set (match_operand 0 "register_operand" "")
9679         (match_operator 3 "absneg_operator"
9680           [(match_operand 1 "register_operand" "")]))
9681    (use (match_operand 2 "nonimmediate_operand" ""))
9682    (clobber (reg:CC FLAGS_REG))]
9683   "reload_completed && SSE_REG_P (operands[0])"
9684   [(set (match_dup 0) (match_dup 3))]
9685 {
9686   enum machine_mode mode = GET_MODE (operands[0]);
9687   enum machine_mode vmode = GET_MODE (operands[2]);
9688   rtx tmp;
9689   
9690   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9691   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9692   if (operands_match_p (operands[0], operands[2]))
9693     {
9694       tmp = operands[1];
9695       operands[1] = operands[2];
9696       operands[2] = tmp;
9697     }
9698   if (GET_CODE (operands[3]) == ABS)
9699     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9700   else
9701     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9702   operands[3] = tmp;
9703 })
9704
9705 (define_split
9706   [(set (match_operand:SF 0 "register_operand" "")
9707         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9708    (use (match_operand:V4SF 2 "" ""))
9709    (clobber (reg:CC FLAGS_REG))]
9710   "reload_completed"
9711   [(parallel [(set (match_dup 0) (match_dup 1))
9712               (clobber (reg:CC FLAGS_REG))])]
9713
9714   rtx tmp;
9715   operands[0] = gen_lowpart (SImode, operands[0]);
9716   if (GET_CODE (operands[1]) == ABS)
9717     {
9718       tmp = gen_int_mode (0x7fffffff, SImode);
9719       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9720     }
9721   else
9722     {
9723       tmp = gen_int_mode (0x80000000, SImode);
9724       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9725     }
9726   operands[1] = tmp;
9727 })
9728
9729 (define_split
9730   [(set (match_operand:DF 0 "register_operand" "")
9731         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9732    (use (match_operand 2 "" ""))
9733    (clobber (reg:CC FLAGS_REG))]
9734   "reload_completed"
9735   [(parallel [(set (match_dup 0) (match_dup 1))
9736               (clobber (reg:CC FLAGS_REG))])]
9737 {
9738   rtx tmp;
9739   if (TARGET_64BIT)
9740     {
9741       tmp = gen_lowpart (DImode, operands[0]);
9742       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9743       operands[0] = tmp;
9744
9745       if (GET_CODE (operands[1]) == ABS)
9746         tmp = const0_rtx;
9747       else
9748         tmp = gen_rtx_NOT (DImode, tmp);
9749     }
9750   else
9751     {
9752       operands[0] = gen_highpart (SImode, operands[0]);
9753       if (GET_CODE (operands[1]) == ABS)
9754         {
9755           tmp = gen_int_mode (0x7fffffff, SImode);
9756           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9757         }
9758       else
9759         {
9760           tmp = gen_int_mode (0x80000000, SImode);
9761           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9762         }
9763     }
9764   operands[1] = tmp;
9765 })
9766
9767 (define_split
9768   [(set (match_operand:XF 0 "register_operand" "")
9769         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9770    (use (match_operand 2 "" ""))
9771    (clobber (reg:CC FLAGS_REG))]
9772   "reload_completed"
9773   [(parallel [(set (match_dup 0) (match_dup 1))
9774               (clobber (reg:CC FLAGS_REG))])]
9775 {
9776   rtx tmp;
9777   operands[0] = gen_rtx_REG (SImode,
9778                              true_regnum (operands[0])
9779                              + (TARGET_64BIT ? 1 : 2));
9780   if (GET_CODE (operands[1]) == ABS)
9781     {
9782       tmp = GEN_INT (0x7fff);
9783       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9784     }
9785   else
9786     {
9787       tmp = GEN_INT (0x8000);
9788       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9789     }
9790   operands[1] = tmp;
9791 })
9792
9793 (define_split
9794   [(set (match_operand 0 "memory_operand" "")
9795         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9796    (use (match_operand 2 "" ""))
9797    (clobber (reg:CC FLAGS_REG))]
9798   "reload_completed"
9799   [(parallel [(set (match_dup 0) (match_dup 1))
9800               (clobber (reg:CC FLAGS_REG))])]
9801 {
9802   enum machine_mode mode = GET_MODE (operands[0]);
9803   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9804   rtx tmp;
9805
9806   operands[0] = adjust_address (operands[0], QImode, size - 1);
9807   if (GET_CODE (operands[1]) == ABS)
9808     {
9809       tmp = gen_int_mode (0x7f, QImode);
9810       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9811     }
9812   else
9813     {
9814       tmp = gen_int_mode (0x80, QImode);
9815       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9816     }
9817   operands[1] = tmp;
9818 })
9819
9820 ;; Conditionalize these after reload. If they match before reload, we 
9821 ;; lose the clobber and ability to use integer instructions.
9822
9823 (define_insn "*negsf2_1"
9824   [(set (match_operand:SF 0 "register_operand" "=f")
9825         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9826   "TARGET_80387 && reload_completed"
9827   "fchs"
9828   [(set_attr "type" "fsgn")
9829    (set_attr "mode" "SF")])
9830
9831 (define_insn "*negdf2_1"
9832   [(set (match_operand:DF 0 "register_operand" "=f")
9833         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9834   "TARGET_80387 && reload_completed"
9835   "fchs"
9836   [(set_attr "type" "fsgn")
9837    (set_attr "mode" "DF")])
9838
9839 (define_insn "*negxf2_1"
9840   [(set (match_operand:XF 0 "register_operand" "=f")
9841         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9842   "TARGET_80387 && reload_completed"
9843   "fchs"
9844   [(set_attr "type" "fsgn")
9845    (set_attr "mode" "XF")])
9846
9847 (define_insn "*abssf2_1"
9848   [(set (match_operand:SF 0 "register_operand" "=f")
9849         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9850   "TARGET_80387 && reload_completed"
9851   "fabs"
9852   [(set_attr "type" "fsgn")
9853    (set_attr "mode" "SF")])
9854
9855 (define_insn "*absdf2_1"
9856   [(set (match_operand:DF 0 "register_operand" "=f")
9857         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9858   "TARGET_80387 && reload_completed"
9859   "fabs"
9860   [(set_attr "type" "fsgn")
9861    (set_attr "mode" "DF")])
9862
9863 (define_insn "*absxf2_1"
9864   [(set (match_operand:XF 0 "register_operand" "=f")
9865         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9866   "TARGET_80387 && reload_completed"
9867   "fabs"
9868   [(set_attr "type" "fsgn")
9869    (set_attr "mode" "DF")])
9870
9871 (define_insn "*negextendsfdf2"
9872   [(set (match_operand:DF 0 "register_operand" "=f")
9873         (neg:DF (float_extend:DF
9874                   (match_operand:SF 1 "register_operand" "0"))))]
9875   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9876   "fchs"
9877   [(set_attr "type" "fsgn")
9878    (set_attr "mode" "DF")])
9879
9880 (define_insn "*negextenddfxf2"
9881   [(set (match_operand:XF 0 "register_operand" "=f")
9882         (neg:XF (float_extend:XF
9883                   (match_operand:DF 1 "register_operand" "0"))))]
9884   "TARGET_80387"
9885   "fchs"
9886   [(set_attr "type" "fsgn")
9887    (set_attr "mode" "XF")])
9888
9889 (define_insn "*negextendsfxf2"
9890   [(set (match_operand:XF 0 "register_operand" "=f")
9891         (neg:XF (float_extend:XF
9892                   (match_operand:SF 1 "register_operand" "0"))))]
9893   "TARGET_80387"
9894   "fchs"
9895   [(set_attr "type" "fsgn")
9896    (set_attr "mode" "XF")])
9897
9898 (define_insn "*absextendsfdf2"
9899   [(set (match_operand:DF 0 "register_operand" "=f")
9900         (abs:DF (float_extend:DF
9901                   (match_operand:SF 1 "register_operand" "0"))))]
9902   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9903   "fabs"
9904   [(set_attr "type" "fsgn")
9905    (set_attr "mode" "DF")])
9906
9907 (define_insn "*absextenddfxf2"
9908   [(set (match_operand:XF 0 "register_operand" "=f")
9909         (abs:XF (float_extend:XF
9910           (match_operand:DF 1 "register_operand" "0"))))]
9911   "TARGET_80387"
9912   "fabs"
9913   [(set_attr "type" "fsgn")
9914    (set_attr "mode" "XF")])
9915
9916 (define_insn "*absextendsfxf2"
9917   [(set (match_operand:XF 0 "register_operand" "=f")
9918         (abs:XF (float_extend:XF
9919           (match_operand:SF 1 "register_operand" "0"))))]
9920   "TARGET_80387"
9921   "fabs"
9922   [(set_attr "type" "fsgn")
9923    (set_attr "mode" "XF")])
9924 \f
9925 ;; One complement instructions
9926
9927 (define_expand "one_cmpldi2"
9928   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9929         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9930   "TARGET_64BIT"
9931   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9932
9933 (define_insn "*one_cmpldi2_1_rex64"
9934   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9935         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9936   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9937   "not{q}\t%0"
9938   [(set_attr "type" "negnot")
9939    (set_attr "mode" "DI")])
9940
9941 (define_insn "*one_cmpldi2_2_rex64"
9942   [(set (reg FLAGS_REG)
9943         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9944                  (const_int 0)))
9945    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9946         (not:DI (match_dup 1)))]
9947   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9948    && ix86_unary_operator_ok (NOT, DImode, operands)"
9949   "#"
9950   [(set_attr "type" "alu1")
9951    (set_attr "mode" "DI")])
9952
9953 (define_split
9954   [(set (match_operand 0 "flags_reg_operand" "")
9955         (match_operator 2 "compare_operator"
9956           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9957            (const_int 0)]))
9958    (set (match_operand:DI 1 "nonimmediate_operand" "")
9959         (not:DI (match_dup 3)))]
9960   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9961   [(parallel [(set (match_dup 0)
9962                    (match_op_dup 2
9963                      [(xor:DI (match_dup 3) (const_int -1))
9964                       (const_int 0)]))
9965               (set (match_dup 1)
9966                    (xor:DI (match_dup 3) (const_int -1)))])]
9967   "")
9968
9969 (define_expand "one_cmplsi2"
9970   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9971         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9972   ""
9973   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9974
9975 (define_insn "*one_cmplsi2_1"
9976   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9977         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9978   "ix86_unary_operator_ok (NOT, SImode, operands)"
9979   "not{l}\t%0"
9980   [(set_attr "type" "negnot")
9981    (set_attr "mode" "SI")])
9982
9983 ;; ??? Currently never generated - xor is used instead.
9984 (define_insn "*one_cmplsi2_1_zext"
9985   [(set (match_operand:DI 0 "register_operand" "=r")
9986         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9987   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9988   "not{l}\t%k0"
9989   [(set_attr "type" "negnot")
9990    (set_attr "mode" "SI")])
9991
9992 (define_insn "*one_cmplsi2_2"
9993   [(set (reg FLAGS_REG)
9994         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9995                  (const_int 0)))
9996    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9997         (not:SI (match_dup 1)))]
9998   "ix86_match_ccmode (insn, CCNOmode)
9999    && ix86_unary_operator_ok (NOT, SImode, operands)"
10000   "#"
10001   [(set_attr "type" "alu1")
10002    (set_attr "mode" "SI")])
10003
10004 (define_split
10005   [(set (match_operand 0 "flags_reg_operand" "")
10006         (match_operator 2 "compare_operator"
10007           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10008            (const_int 0)]))
10009    (set (match_operand:SI 1 "nonimmediate_operand" "")
10010         (not:SI (match_dup 3)))]
10011   "ix86_match_ccmode (insn, CCNOmode)"
10012   [(parallel [(set (match_dup 0)
10013                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10014                                     (const_int 0)]))
10015               (set (match_dup 1)
10016                    (xor:SI (match_dup 3) (const_int -1)))])]
10017   "")
10018
10019 ;; ??? Currently never generated - xor is used instead.
10020 (define_insn "*one_cmplsi2_2_zext"
10021   [(set (reg FLAGS_REG)
10022         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10023                  (const_int 0)))
10024    (set (match_operand:DI 0 "register_operand" "=r")
10025         (zero_extend:DI (not:SI (match_dup 1))))]
10026   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10027    && ix86_unary_operator_ok (NOT, SImode, operands)"
10028   "#"
10029   [(set_attr "type" "alu1")
10030    (set_attr "mode" "SI")])
10031
10032 (define_split
10033   [(set (match_operand 0 "flags_reg_operand" "")
10034         (match_operator 2 "compare_operator"
10035           [(not:SI (match_operand:SI 3 "register_operand" ""))
10036            (const_int 0)]))
10037    (set (match_operand:DI 1 "register_operand" "")
10038         (zero_extend:DI (not:SI (match_dup 3))))]
10039   "ix86_match_ccmode (insn, CCNOmode)"
10040   [(parallel [(set (match_dup 0)
10041                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10042                                     (const_int 0)]))
10043               (set (match_dup 1)
10044                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10045   "")
10046
10047 (define_expand "one_cmplhi2"
10048   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10049         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10050   "TARGET_HIMODE_MATH"
10051   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10052
10053 (define_insn "*one_cmplhi2_1"
10054   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10055         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10056   "ix86_unary_operator_ok (NOT, HImode, operands)"
10057   "not{w}\t%0"
10058   [(set_attr "type" "negnot")
10059    (set_attr "mode" "HI")])
10060
10061 (define_insn "*one_cmplhi2_2"
10062   [(set (reg FLAGS_REG)
10063         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10064                  (const_int 0)))
10065    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10066         (not:HI (match_dup 1)))]
10067   "ix86_match_ccmode (insn, CCNOmode)
10068    && ix86_unary_operator_ok (NEG, HImode, operands)"
10069   "#"
10070   [(set_attr "type" "alu1")
10071    (set_attr "mode" "HI")])
10072
10073 (define_split
10074   [(set (match_operand 0 "flags_reg_operand" "")
10075         (match_operator 2 "compare_operator"
10076           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10077            (const_int 0)]))
10078    (set (match_operand:HI 1 "nonimmediate_operand" "")
10079         (not:HI (match_dup 3)))]
10080   "ix86_match_ccmode (insn, CCNOmode)"
10081   [(parallel [(set (match_dup 0)
10082                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10083                                     (const_int 0)]))
10084               (set (match_dup 1)
10085                    (xor:HI (match_dup 3) (const_int -1)))])]
10086   "")
10087
10088 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10089 (define_expand "one_cmplqi2"
10090   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10091         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10092   "TARGET_QIMODE_MATH"
10093   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10094
10095 (define_insn "*one_cmplqi2_1"
10096   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10097         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10098   "ix86_unary_operator_ok (NOT, QImode, operands)"
10099   "@
10100    not{b}\t%0
10101    not{l}\t%k0"
10102   [(set_attr "type" "negnot")
10103    (set_attr "mode" "QI,SI")])
10104
10105 (define_insn "*one_cmplqi2_2"
10106   [(set (reg FLAGS_REG)
10107         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10108                  (const_int 0)))
10109    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10110         (not:QI (match_dup 1)))]
10111   "ix86_match_ccmode (insn, CCNOmode)
10112    && ix86_unary_operator_ok (NOT, QImode, operands)"
10113   "#"
10114   [(set_attr "type" "alu1")
10115    (set_attr "mode" "QI")])
10116
10117 (define_split
10118   [(set (match_operand 0 "flags_reg_operand" "")
10119         (match_operator 2 "compare_operator"
10120           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10121            (const_int 0)]))
10122    (set (match_operand:QI 1 "nonimmediate_operand" "")
10123         (not:QI (match_dup 3)))]
10124   "ix86_match_ccmode (insn, CCNOmode)"
10125   [(parallel [(set (match_dup 0)
10126                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10127                                     (const_int 0)]))
10128               (set (match_dup 1)
10129                    (xor:QI (match_dup 3) (const_int -1)))])]
10130   "")
10131 \f
10132 ;; Arithmetic shift instructions
10133
10134 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10135 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10136 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10137 ;; from the assembler input.
10138 ;;
10139 ;; This instruction shifts the target reg/mem as usual, but instead of
10140 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10141 ;; is a left shift double, bits are taken from the high order bits of
10142 ;; reg, else if the insn is a shift right double, bits are taken from the
10143 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10144 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10145 ;;
10146 ;; Since sh[lr]d does not change the `reg' operand, that is done
10147 ;; separately, making all shifts emit pairs of shift double and normal
10148 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10149 ;; support a 63 bit shift, each shift where the count is in a reg expands
10150 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10151 ;;
10152 ;; If the shift count is a constant, we need never emit more than one
10153 ;; shift pair, instead using moves and sign extension for counts greater
10154 ;; than 31.
10155
10156 (define_expand "ashldi3"
10157   [(set (match_operand:DI 0 "shiftdi_operand" "")
10158         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10159                    (match_operand:QI 2 "nonmemory_operand" "")))]
10160   ""
10161   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10162
10163 (define_insn "*ashldi3_1_rex64"
10164   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10165         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10166                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10167    (clobber (reg:CC FLAGS_REG))]
10168   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10169 {
10170   switch (get_attr_type (insn))
10171     {
10172     case TYPE_ALU:
10173       if (operands[2] != const1_rtx)
10174         abort ();
10175       if (!rtx_equal_p (operands[0], operands[1]))
10176         abort ();
10177       return "add{q}\t{%0, %0|%0, %0}";
10178
10179     case TYPE_LEA:
10180       if (GET_CODE (operands[2]) != CONST_INT
10181           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10182         abort ();
10183       operands[1] = gen_rtx_MULT (DImode, operands[1],
10184                                   GEN_INT (1 << INTVAL (operands[2])));
10185       return "lea{q}\t{%a1, %0|%0, %a1}";
10186
10187     default:
10188       if (REG_P (operands[2]))
10189         return "sal{q}\t{%b2, %0|%0, %b2}";
10190       else if (operands[2] == const1_rtx
10191                && (TARGET_SHIFT1 || optimize_size))
10192         return "sal{q}\t%0";
10193       else
10194         return "sal{q}\t{%2, %0|%0, %2}";
10195     }
10196 }
10197   [(set (attr "type")
10198      (cond [(eq_attr "alternative" "1")
10199               (const_string "lea")
10200             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10201                           (const_int 0))
10202                       (match_operand 0 "register_operand" ""))
10203                  (match_operand 2 "const1_operand" ""))
10204               (const_string "alu")
10205            ]
10206            (const_string "ishift")))
10207    (set_attr "mode" "DI")])
10208
10209 ;; Convert lea to the lea pattern to avoid flags dependency.
10210 (define_split
10211   [(set (match_operand:DI 0 "register_operand" "")
10212         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10213                    (match_operand:QI 2 "immediate_operand" "")))
10214    (clobber (reg:CC FLAGS_REG))]
10215   "TARGET_64BIT && reload_completed
10216    && true_regnum (operands[0]) != true_regnum (operands[1])"
10217   [(set (match_dup 0)
10218         (mult:DI (match_dup 1)
10219                  (match_dup 2)))]
10220   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10221
10222 ;; This pattern can't accept a variable shift count, since shifts by
10223 ;; zero don't affect the flags.  We assume that shifts by constant
10224 ;; zero are optimized away.
10225 (define_insn "*ashldi3_cmp_rex64"
10226   [(set (reg FLAGS_REG)
10227         (compare
10228           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10229                      (match_operand:QI 2 "immediate_operand" "e"))
10230           (const_int 0)))
10231    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10232         (ashift:DI (match_dup 1) (match_dup 2)))]
10233   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10234    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10235 {
10236   switch (get_attr_type (insn))
10237     {
10238     case TYPE_ALU:
10239       if (operands[2] != const1_rtx)
10240         abort ();
10241       return "add{q}\t{%0, %0|%0, %0}";
10242
10243     default:
10244       if (REG_P (operands[2]))
10245         return "sal{q}\t{%b2, %0|%0, %b2}";
10246       else if (operands[2] == const1_rtx
10247                && (TARGET_SHIFT1 || optimize_size))
10248         return "sal{q}\t%0";
10249       else
10250         return "sal{q}\t{%2, %0|%0, %2}";
10251     }
10252 }
10253   [(set (attr "type")
10254      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10255                           (const_int 0))
10256                       (match_operand 0 "register_operand" ""))
10257                  (match_operand 2 "const1_operand" ""))
10258               (const_string "alu")
10259            ]
10260            (const_string "ishift")))
10261    (set_attr "mode" "DI")])
10262
10263 (define_insn "*ashldi3_1"
10264   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10265         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10266                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10267    (clobber (reg:CC FLAGS_REG))]
10268   "!TARGET_64BIT"
10269   "#"
10270   [(set_attr "type" "multi")])
10271
10272 ;; By default we don't ask for a scratch register, because when DImode
10273 ;; values are manipulated, registers are already at a premium.  But if
10274 ;; we have one handy, we won't turn it away.
10275 (define_peephole2
10276   [(match_scratch:SI 3 "r")
10277    (parallel [(set (match_operand:DI 0 "register_operand" "")
10278                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10279                               (match_operand:QI 2 "nonmemory_operand" "")))
10280               (clobber (reg:CC FLAGS_REG))])
10281    (match_dup 3)]
10282   "!TARGET_64BIT && TARGET_CMOVE"
10283   [(const_int 0)]
10284   "ix86_split_ashldi (operands, operands[3]); DONE;")
10285
10286 (define_split
10287   [(set (match_operand:DI 0 "register_operand" "")
10288         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10289                    (match_operand:QI 2 "nonmemory_operand" "")))
10290    (clobber (reg:CC FLAGS_REG))]
10291   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10292   [(const_int 0)]
10293   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10294
10295 (define_insn "x86_shld_1"
10296   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10297         (ior:SI (ashift:SI (match_dup 0)
10298                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10299                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10300                   (minus:QI (const_int 32) (match_dup 2)))))
10301    (clobber (reg:CC FLAGS_REG))]
10302   ""
10303   "@
10304    shld{l}\t{%2, %1, %0|%0, %1, %2}
10305    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10306   [(set_attr "type" "ishift")
10307    (set_attr "prefix_0f" "1")
10308    (set_attr "mode" "SI")
10309    (set_attr "pent_pair" "np")
10310    (set_attr "athlon_decode" "vector")])
10311
10312 (define_expand "x86_shift_adj_1"
10313   [(set (reg:CCZ FLAGS_REG)
10314         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10315                              (const_int 32))
10316                      (const_int 0)))
10317    (set (match_operand:SI 0 "register_operand" "")
10318         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10319                          (match_operand:SI 1 "register_operand" "")
10320                          (match_dup 0)))
10321    (set (match_dup 1)
10322         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10323                          (match_operand:SI 3 "register_operand" "r")
10324                          (match_dup 1)))]
10325   "TARGET_CMOVE"
10326   "")
10327
10328 (define_expand "x86_shift_adj_2"
10329   [(use (match_operand:SI 0 "register_operand" ""))
10330    (use (match_operand:SI 1 "register_operand" ""))
10331    (use (match_operand:QI 2 "register_operand" ""))]
10332   ""
10333 {
10334   rtx label = gen_label_rtx ();
10335   rtx tmp;
10336
10337   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10338
10339   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10340   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10341   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10342                               gen_rtx_LABEL_REF (VOIDmode, label),
10343                               pc_rtx);
10344   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10345   JUMP_LABEL (tmp) = label;
10346
10347   emit_move_insn (operands[0], operands[1]);
10348   ix86_expand_clear (operands[1]);
10349
10350   emit_label (label);
10351   LABEL_NUSES (label) = 1;
10352
10353   DONE;
10354 })
10355
10356 (define_expand "ashlsi3"
10357   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10358         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10359                    (match_operand:QI 2 "nonmemory_operand" "")))
10360    (clobber (reg:CC FLAGS_REG))]
10361   ""
10362   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10363
10364 (define_insn "*ashlsi3_1"
10365   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10366         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10367                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10368    (clobber (reg:CC FLAGS_REG))]
10369   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10370 {
10371   switch (get_attr_type (insn))
10372     {
10373     case TYPE_ALU:
10374       if (operands[2] != const1_rtx)
10375         abort ();
10376       if (!rtx_equal_p (operands[0], operands[1]))
10377         abort ();
10378       return "add{l}\t{%0, %0|%0, %0}";
10379
10380     case TYPE_LEA:
10381       return "#";
10382
10383     default:
10384       if (REG_P (operands[2]))
10385         return "sal{l}\t{%b2, %0|%0, %b2}";
10386       else if (operands[2] == const1_rtx
10387                && (TARGET_SHIFT1 || optimize_size))
10388         return "sal{l}\t%0";
10389       else
10390         return "sal{l}\t{%2, %0|%0, %2}";
10391     }
10392 }
10393   [(set (attr "type")
10394      (cond [(eq_attr "alternative" "1")
10395               (const_string "lea")
10396             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10397                           (const_int 0))
10398                       (match_operand 0 "register_operand" ""))
10399                  (match_operand 2 "const1_operand" ""))
10400               (const_string "alu")
10401            ]
10402            (const_string "ishift")))
10403    (set_attr "mode" "SI")])
10404
10405 ;; Convert lea to the lea pattern to avoid flags dependency.
10406 (define_split
10407   [(set (match_operand 0 "register_operand" "")
10408         (ashift (match_operand 1 "index_register_operand" "")
10409                 (match_operand:QI 2 "const_int_operand" "")))
10410    (clobber (reg:CC FLAGS_REG))]
10411   "reload_completed
10412    && true_regnum (operands[0]) != true_regnum (operands[1])
10413    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10414   [(const_int 0)]
10415 {
10416   rtx pat;
10417   enum machine_mode mode = GET_MODE (operands[0]);
10418
10419   if (GET_MODE_SIZE (mode) < 4)
10420     operands[0] = gen_lowpart (SImode, operands[0]);
10421   if (mode != Pmode)
10422     operands[1] = gen_lowpart (Pmode, operands[1]);
10423   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10424
10425   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10426   if (Pmode != SImode)
10427     pat = gen_rtx_SUBREG (SImode, pat, 0);
10428   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10429   DONE;
10430 })
10431
10432 ;; Rare case of shifting RSP is handled by generating move and shift
10433 (define_split
10434   [(set (match_operand 0 "register_operand" "")
10435         (ashift (match_operand 1 "register_operand" "")
10436                 (match_operand:QI 2 "const_int_operand" "")))
10437    (clobber (reg:CC FLAGS_REG))]
10438   "reload_completed
10439    && true_regnum (operands[0]) != true_regnum (operands[1])"
10440   [(const_int 0)]
10441 {
10442   rtx pat, clob;
10443   emit_move_insn (operands[1], operands[0]);
10444   pat = gen_rtx_SET (VOIDmode, operands[0],
10445                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10446                                      operands[0], operands[2]));
10447   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10448   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10449   DONE;
10450 })
10451
10452 (define_insn "*ashlsi3_1_zext"
10453   [(set (match_operand:DI 0 "register_operand" "=r,r")
10454         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10455                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10456    (clobber (reg:CC FLAGS_REG))]
10457   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10458 {
10459   switch (get_attr_type (insn))
10460     {
10461     case TYPE_ALU:
10462       if (operands[2] != const1_rtx)
10463         abort ();
10464       return "add{l}\t{%k0, %k0|%k0, %k0}";
10465
10466     case TYPE_LEA:
10467       return "#";
10468
10469     default:
10470       if (REG_P (operands[2]))
10471         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10472       else if (operands[2] == const1_rtx
10473                && (TARGET_SHIFT1 || optimize_size))
10474         return "sal{l}\t%k0";
10475       else
10476         return "sal{l}\t{%2, %k0|%k0, %2}";
10477     }
10478 }
10479   [(set (attr "type")
10480      (cond [(eq_attr "alternative" "1")
10481               (const_string "lea")
10482             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10483                      (const_int 0))
10484                  (match_operand 2 "const1_operand" ""))
10485               (const_string "alu")
10486            ]
10487            (const_string "ishift")))
10488    (set_attr "mode" "SI")])
10489
10490 ;; Convert lea to the lea pattern to avoid flags dependency.
10491 (define_split
10492   [(set (match_operand:DI 0 "register_operand" "")
10493         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10494                                 (match_operand:QI 2 "const_int_operand" ""))))
10495    (clobber (reg:CC FLAGS_REG))]
10496   "TARGET_64BIT && reload_completed
10497    && true_regnum (operands[0]) != true_regnum (operands[1])"
10498   [(set (match_dup 0) (zero_extend:DI
10499                         (subreg:SI (mult:SI (match_dup 1)
10500                                             (match_dup 2)) 0)))]
10501 {
10502   operands[1] = gen_lowpart (Pmode, operands[1]);
10503   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10504 })
10505
10506 ;; This pattern can't accept a variable shift count, since shifts by
10507 ;; zero don't affect the flags.  We assume that shifts by constant
10508 ;; zero are optimized away.
10509 (define_insn "*ashlsi3_cmp"
10510   [(set (reg FLAGS_REG)
10511         (compare
10512           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10513                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10514           (const_int 0)))
10515    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10516         (ashift:SI (match_dup 1) (match_dup 2)))]
10517   "ix86_match_ccmode (insn, CCGOCmode)
10518    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10519 {
10520   switch (get_attr_type (insn))
10521     {
10522     case TYPE_ALU:
10523       if (operands[2] != const1_rtx)
10524         abort ();
10525       return "add{l}\t{%0, %0|%0, %0}";
10526
10527     default:
10528       if (REG_P (operands[2]))
10529         return "sal{l}\t{%b2, %0|%0, %b2}";
10530       else if (operands[2] == const1_rtx
10531                && (TARGET_SHIFT1 || optimize_size))
10532         return "sal{l}\t%0";
10533       else
10534         return "sal{l}\t{%2, %0|%0, %2}";
10535     }
10536 }
10537   [(set (attr "type")
10538      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10539                           (const_int 0))
10540                       (match_operand 0 "register_operand" ""))
10541                  (match_operand 2 "const1_operand" ""))
10542               (const_string "alu")
10543            ]
10544            (const_string "ishift")))
10545    (set_attr "mode" "SI")])
10546
10547 (define_insn "*ashlsi3_cmp_zext"
10548   [(set (reg FLAGS_REG)
10549         (compare
10550           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10551                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10552           (const_int 0)))
10553    (set (match_operand:DI 0 "register_operand" "=r")
10554         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10555   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10556    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10557 {
10558   switch (get_attr_type (insn))
10559     {
10560     case TYPE_ALU:
10561       if (operands[2] != const1_rtx)
10562         abort ();
10563       return "add{l}\t{%k0, %k0|%k0, %k0}";
10564
10565     default:
10566       if (REG_P (operands[2]))
10567         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10568       else if (operands[2] == const1_rtx
10569                && (TARGET_SHIFT1 || optimize_size))
10570         return "sal{l}\t%k0";
10571       else
10572         return "sal{l}\t{%2, %k0|%k0, %2}";
10573     }
10574 }
10575   [(set (attr "type")
10576      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10577                      (const_int 0))
10578                  (match_operand 2 "const1_operand" ""))
10579               (const_string "alu")
10580            ]
10581            (const_string "ishift")))
10582    (set_attr "mode" "SI")])
10583
10584 (define_expand "ashlhi3"
10585   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10586         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10587                    (match_operand:QI 2 "nonmemory_operand" "")))
10588    (clobber (reg:CC FLAGS_REG))]
10589   "TARGET_HIMODE_MATH"
10590   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10591
10592 (define_insn "*ashlhi3_1_lea"
10593   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10594         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10595                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10596    (clobber (reg:CC FLAGS_REG))]
10597   "!TARGET_PARTIAL_REG_STALL
10598    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10599 {
10600   switch (get_attr_type (insn))
10601     {
10602     case TYPE_LEA:
10603       return "#";
10604     case TYPE_ALU:
10605       if (operands[2] != const1_rtx)
10606         abort ();
10607       return "add{w}\t{%0, %0|%0, %0}";
10608
10609     default:
10610       if (REG_P (operands[2]))
10611         return "sal{w}\t{%b2, %0|%0, %b2}";
10612       else if (operands[2] == const1_rtx
10613                && (TARGET_SHIFT1 || optimize_size))
10614         return "sal{w}\t%0";
10615       else
10616         return "sal{w}\t{%2, %0|%0, %2}";
10617     }
10618 }
10619   [(set (attr "type")
10620      (cond [(eq_attr "alternative" "1")
10621               (const_string "lea")
10622             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10623                           (const_int 0))
10624                       (match_operand 0 "register_operand" ""))
10625                  (match_operand 2 "const1_operand" ""))
10626               (const_string "alu")
10627            ]
10628            (const_string "ishift")))
10629    (set_attr "mode" "HI,SI")])
10630
10631 (define_insn "*ashlhi3_1"
10632   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10633         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10634                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10635    (clobber (reg:CC FLAGS_REG))]
10636   "TARGET_PARTIAL_REG_STALL
10637    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10638 {
10639   switch (get_attr_type (insn))
10640     {
10641     case TYPE_ALU:
10642       if (operands[2] != const1_rtx)
10643         abort ();
10644       return "add{w}\t{%0, %0|%0, %0}";
10645
10646     default:
10647       if (REG_P (operands[2]))
10648         return "sal{w}\t{%b2, %0|%0, %b2}";
10649       else if (operands[2] == const1_rtx
10650                && (TARGET_SHIFT1 || optimize_size))
10651         return "sal{w}\t%0";
10652       else
10653         return "sal{w}\t{%2, %0|%0, %2}";
10654     }
10655 }
10656   [(set (attr "type")
10657      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10658                           (const_int 0))
10659                       (match_operand 0 "register_operand" ""))
10660                  (match_operand 2 "const1_operand" ""))
10661               (const_string "alu")
10662            ]
10663            (const_string "ishift")))
10664    (set_attr "mode" "HI")])
10665
10666 ;; This pattern can't accept a variable shift count, since shifts by
10667 ;; zero don't affect the flags.  We assume that shifts by constant
10668 ;; zero are optimized away.
10669 (define_insn "*ashlhi3_cmp"
10670   [(set (reg FLAGS_REG)
10671         (compare
10672           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10673                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10674           (const_int 0)))
10675    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10676         (ashift:HI (match_dup 1) (match_dup 2)))]
10677   "ix86_match_ccmode (insn, CCGOCmode)
10678    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10679 {
10680   switch (get_attr_type (insn))
10681     {
10682     case TYPE_ALU:
10683       if (operands[2] != const1_rtx)
10684         abort ();
10685       return "add{w}\t{%0, %0|%0, %0}";
10686
10687     default:
10688       if (REG_P (operands[2]))
10689         return "sal{w}\t{%b2, %0|%0, %b2}";
10690       else if (operands[2] == const1_rtx
10691                && (TARGET_SHIFT1 || optimize_size))
10692         return "sal{w}\t%0";
10693       else
10694         return "sal{w}\t{%2, %0|%0, %2}";
10695     }
10696 }
10697   [(set (attr "type")
10698      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10699                           (const_int 0))
10700                       (match_operand 0 "register_operand" ""))
10701                  (match_operand 2 "const1_operand" ""))
10702               (const_string "alu")
10703            ]
10704            (const_string "ishift")))
10705    (set_attr "mode" "HI")])
10706
10707 (define_expand "ashlqi3"
10708   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10709         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10710                    (match_operand:QI 2 "nonmemory_operand" "")))
10711    (clobber (reg:CC FLAGS_REG))]
10712   "TARGET_QIMODE_MATH"
10713   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10714
10715 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10716
10717 (define_insn "*ashlqi3_1_lea"
10718   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10719         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10720                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10721    (clobber (reg:CC FLAGS_REG))]
10722   "!TARGET_PARTIAL_REG_STALL
10723    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10724 {
10725   switch (get_attr_type (insn))
10726     {
10727     case TYPE_LEA:
10728       return "#";
10729     case TYPE_ALU:
10730       if (operands[2] != const1_rtx)
10731         abort ();
10732       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10733         return "add{l}\t{%k0, %k0|%k0, %k0}";
10734       else
10735         return "add{b}\t{%0, %0|%0, %0}";
10736
10737     default:
10738       if (REG_P (operands[2]))
10739         {
10740           if (get_attr_mode (insn) == MODE_SI)
10741             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10742           else
10743             return "sal{b}\t{%b2, %0|%0, %b2}";
10744         }
10745       else if (operands[2] == const1_rtx
10746                && (TARGET_SHIFT1 || optimize_size))
10747         {
10748           if (get_attr_mode (insn) == MODE_SI)
10749             return "sal{l}\t%0";
10750           else
10751             return "sal{b}\t%0";
10752         }
10753       else
10754         {
10755           if (get_attr_mode (insn) == MODE_SI)
10756             return "sal{l}\t{%2, %k0|%k0, %2}";
10757           else
10758             return "sal{b}\t{%2, %0|%0, %2}";
10759         }
10760     }
10761 }
10762   [(set (attr "type")
10763      (cond [(eq_attr "alternative" "2")
10764               (const_string "lea")
10765             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10766                           (const_int 0))
10767                       (match_operand 0 "register_operand" ""))
10768                  (match_operand 2 "const1_operand" ""))
10769               (const_string "alu")
10770            ]
10771            (const_string "ishift")))
10772    (set_attr "mode" "QI,SI,SI")])
10773
10774 (define_insn "*ashlqi3_1"
10775   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10776         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10777                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10778    (clobber (reg:CC FLAGS_REG))]
10779   "TARGET_PARTIAL_REG_STALL
10780    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10781 {
10782   switch (get_attr_type (insn))
10783     {
10784     case TYPE_ALU:
10785       if (operands[2] != const1_rtx)
10786         abort ();
10787       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10788         return "add{l}\t{%k0, %k0|%k0, %k0}";
10789       else
10790         return "add{b}\t{%0, %0|%0, %0}";
10791
10792     default:
10793       if (REG_P (operands[2]))
10794         {
10795           if (get_attr_mode (insn) == MODE_SI)
10796             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10797           else
10798             return "sal{b}\t{%b2, %0|%0, %b2}";
10799         }
10800       else if (operands[2] == const1_rtx
10801                && (TARGET_SHIFT1 || optimize_size))
10802         {
10803           if (get_attr_mode (insn) == MODE_SI)
10804             return "sal{l}\t%0";
10805           else
10806             return "sal{b}\t%0";
10807         }
10808       else
10809         {
10810           if (get_attr_mode (insn) == MODE_SI)
10811             return "sal{l}\t{%2, %k0|%k0, %2}";
10812           else
10813             return "sal{b}\t{%2, %0|%0, %2}";
10814         }
10815     }
10816 }
10817   [(set (attr "type")
10818      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10819                           (const_int 0))
10820                       (match_operand 0 "register_operand" ""))
10821                  (match_operand 2 "const1_operand" ""))
10822               (const_string "alu")
10823            ]
10824            (const_string "ishift")))
10825    (set_attr "mode" "QI,SI")])
10826
10827 ;; This pattern can't accept a variable shift count, since shifts by
10828 ;; zero don't affect the flags.  We assume that shifts by constant
10829 ;; zero are optimized away.
10830 (define_insn "*ashlqi3_cmp"
10831   [(set (reg FLAGS_REG)
10832         (compare
10833           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10834                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10835           (const_int 0)))
10836    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10837         (ashift:QI (match_dup 1) (match_dup 2)))]
10838   "ix86_match_ccmode (insn, CCGOCmode)
10839    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10840 {
10841   switch (get_attr_type (insn))
10842     {
10843     case TYPE_ALU:
10844       if (operands[2] != const1_rtx)
10845         abort ();
10846       return "add{b}\t{%0, %0|%0, %0}";
10847
10848     default:
10849       if (REG_P (operands[2]))
10850         return "sal{b}\t{%b2, %0|%0, %b2}";
10851       else if (operands[2] == const1_rtx
10852                && (TARGET_SHIFT1 || optimize_size))
10853         return "sal{b}\t%0";
10854       else
10855         return "sal{b}\t{%2, %0|%0, %2}";
10856     }
10857 }
10858   [(set (attr "type")
10859      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10860                           (const_int 0))
10861                       (match_operand 0 "register_operand" ""))
10862                  (match_operand 2 "const1_operand" ""))
10863               (const_string "alu")
10864            ]
10865            (const_string "ishift")))
10866    (set_attr "mode" "QI")])
10867
10868 ;; See comment above `ashldi3' about how this works.
10869
10870 (define_expand "ashrdi3"
10871   [(set (match_operand:DI 0 "shiftdi_operand" "")
10872         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10873                      (match_operand:QI 2 "nonmemory_operand" "")))]
10874   ""
10875   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10876
10877 (define_insn "*ashrdi3_63_rex64"
10878   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10879         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10880                      (match_operand:DI 2 "const_int_operand" "i,i")))
10881    (clobber (reg:CC FLAGS_REG))]
10882   "TARGET_64BIT && INTVAL (operands[2]) == 63
10883    && (TARGET_USE_CLTD || optimize_size)
10884    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10885   "@
10886    {cqto|cqo}
10887    sar{q}\t{%2, %0|%0, %2}"
10888   [(set_attr "type" "imovx,ishift")
10889    (set_attr "prefix_0f" "0,*")
10890    (set_attr "length_immediate" "0,*")
10891    (set_attr "modrm" "0,1")
10892    (set_attr "mode" "DI")])
10893
10894 (define_insn "*ashrdi3_1_one_bit_rex64"
10895   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10896         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10897                      (match_operand:QI 2 "const1_operand" "")))
10898    (clobber (reg:CC FLAGS_REG))]
10899   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10900    && (TARGET_SHIFT1 || optimize_size)"
10901   "sar{q}\t%0"
10902   [(set_attr "type" "ishift")
10903    (set (attr "length") 
10904      (if_then_else (match_operand:DI 0 "register_operand" "") 
10905         (const_string "2")
10906         (const_string "*")))])
10907
10908 (define_insn "*ashrdi3_1_rex64"
10909   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10910         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10911                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10912    (clobber (reg:CC FLAGS_REG))]
10913   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10914   "@
10915    sar{q}\t{%2, %0|%0, %2}
10916    sar{q}\t{%b2, %0|%0, %b2}"
10917   [(set_attr "type" "ishift")
10918    (set_attr "mode" "DI")])
10919
10920 ;; This pattern can't accept a variable shift count, since shifts by
10921 ;; zero don't affect the flags.  We assume that shifts by constant
10922 ;; zero are optimized away.
10923 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10924   [(set (reg FLAGS_REG)
10925         (compare
10926           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10927                        (match_operand:QI 2 "const1_operand" ""))
10928           (const_int 0)))
10929    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10930         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10931   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10932    && (TARGET_SHIFT1 || optimize_size)
10933    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10934   "sar{q}\t%0"
10935   [(set_attr "type" "ishift")
10936    (set (attr "length") 
10937      (if_then_else (match_operand:DI 0 "register_operand" "") 
10938         (const_string "2")
10939         (const_string "*")))])
10940
10941 ;; This pattern can't accept a variable shift count, since shifts by
10942 ;; zero don't affect the flags.  We assume that shifts by constant
10943 ;; zero are optimized away.
10944 (define_insn "*ashrdi3_cmp_rex64"
10945   [(set (reg FLAGS_REG)
10946         (compare
10947           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10948                        (match_operand:QI 2 "const_int_operand" "n"))
10949           (const_int 0)))
10950    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10951         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10952   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10953    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10954   "sar{q}\t{%2, %0|%0, %2}"
10955   [(set_attr "type" "ishift")
10956    (set_attr "mode" "DI")])
10957
10958 (define_insn "*ashrdi3_1"
10959   [(set (match_operand:DI 0 "register_operand" "=r")
10960         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10961                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10962    (clobber (reg:CC FLAGS_REG))]
10963   "!TARGET_64BIT"
10964   "#"
10965   [(set_attr "type" "multi")])
10966
10967 ;; By default we don't ask for a scratch register, because when DImode
10968 ;; values are manipulated, registers are already at a premium.  But if
10969 ;; we have one handy, we won't turn it away.
10970 (define_peephole2
10971   [(match_scratch:SI 3 "r")
10972    (parallel [(set (match_operand:DI 0 "register_operand" "")
10973                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10974                                 (match_operand:QI 2 "nonmemory_operand" "")))
10975               (clobber (reg:CC FLAGS_REG))])
10976    (match_dup 3)]
10977   "!TARGET_64BIT && TARGET_CMOVE"
10978   [(const_int 0)]
10979   "ix86_split_ashrdi (operands, operands[3]); DONE;")
10980
10981 (define_split
10982   [(set (match_operand:DI 0 "register_operand" "")
10983         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10984                      (match_operand:QI 2 "nonmemory_operand" "")))
10985    (clobber (reg:CC FLAGS_REG))]
10986   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10987   [(const_int 0)]
10988   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
10989
10990 (define_insn "x86_shrd_1"
10991   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10992         (ior:SI (ashiftrt:SI (match_dup 0)
10993                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10994                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
10995                   (minus:QI (const_int 32) (match_dup 2)))))
10996    (clobber (reg:CC FLAGS_REG))]
10997   ""
10998   "@
10999    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11000    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11001   [(set_attr "type" "ishift")
11002    (set_attr "prefix_0f" "1")
11003    (set_attr "pent_pair" "np")
11004    (set_attr "mode" "SI")])
11005
11006 (define_expand "x86_shift_adj_3"
11007   [(use (match_operand:SI 0 "register_operand" ""))
11008    (use (match_operand:SI 1 "register_operand" ""))
11009    (use (match_operand:QI 2 "register_operand" ""))]
11010   ""
11011 {
11012   rtx label = gen_label_rtx ();
11013   rtx tmp;
11014
11015   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11016
11017   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11018   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11019   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11020                               gen_rtx_LABEL_REF (VOIDmode, label),
11021                               pc_rtx);
11022   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11023   JUMP_LABEL (tmp) = label;
11024
11025   emit_move_insn (operands[0], operands[1]);
11026   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11027
11028   emit_label (label);
11029   LABEL_NUSES (label) = 1;
11030
11031   DONE;
11032 })
11033
11034 (define_insn "ashrsi3_31"
11035   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11036         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11037                      (match_operand:SI 2 "const_int_operand" "i,i")))
11038    (clobber (reg:CC FLAGS_REG))]
11039   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11040    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11041   "@
11042    {cltd|cdq}
11043    sar{l}\t{%2, %0|%0, %2}"
11044   [(set_attr "type" "imovx,ishift")
11045    (set_attr "prefix_0f" "0,*")
11046    (set_attr "length_immediate" "0,*")
11047    (set_attr "modrm" "0,1")
11048    (set_attr "mode" "SI")])
11049
11050 (define_insn "*ashrsi3_31_zext"
11051   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11052         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11053                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11054    (clobber (reg:CC FLAGS_REG))]
11055   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11056    && INTVAL (operands[2]) == 31
11057    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11058   "@
11059    {cltd|cdq}
11060    sar{l}\t{%2, %k0|%k0, %2}"
11061   [(set_attr "type" "imovx,ishift")
11062    (set_attr "prefix_0f" "0,*")
11063    (set_attr "length_immediate" "0,*")
11064    (set_attr "modrm" "0,1")
11065    (set_attr "mode" "SI")])
11066
11067 (define_expand "ashrsi3"
11068   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11069         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11070                      (match_operand:QI 2 "nonmemory_operand" "")))
11071    (clobber (reg:CC FLAGS_REG))]
11072   ""
11073   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11074
11075 (define_insn "*ashrsi3_1_one_bit"
11076   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11077         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11078                      (match_operand:QI 2 "const1_operand" "")))
11079    (clobber (reg:CC FLAGS_REG))]
11080   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11081    && (TARGET_SHIFT1 || optimize_size)"
11082   "sar{l}\t%0"
11083   [(set_attr "type" "ishift")
11084    (set (attr "length") 
11085      (if_then_else (match_operand:SI 0 "register_operand" "") 
11086         (const_string "2")
11087         (const_string "*")))])
11088
11089 (define_insn "*ashrsi3_1_one_bit_zext"
11090   [(set (match_operand:DI 0 "register_operand" "=r")
11091         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11092                                      (match_operand:QI 2 "const1_operand" ""))))
11093    (clobber (reg:CC FLAGS_REG))]
11094   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11095    && (TARGET_SHIFT1 || optimize_size)"
11096   "sar{l}\t%k0"
11097   [(set_attr "type" "ishift")
11098    (set_attr "length" "2")])
11099
11100 (define_insn "*ashrsi3_1"
11101   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11102         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11103                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11104    (clobber (reg:CC FLAGS_REG))]
11105   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11106   "@
11107    sar{l}\t{%2, %0|%0, %2}
11108    sar{l}\t{%b2, %0|%0, %b2}"
11109   [(set_attr "type" "ishift")
11110    (set_attr "mode" "SI")])
11111
11112 (define_insn "*ashrsi3_1_zext"
11113   [(set (match_operand:DI 0 "register_operand" "=r,r")
11114         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11115                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11116    (clobber (reg:CC FLAGS_REG))]
11117   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11118   "@
11119    sar{l}\t{%2, %k0|%k0, %2}
11120    sar{l}\t{%b2, %k0|%k0, %b2}"
11121   [(set_attr "type" "ishift")
11122    (set_attr "mode" "SI")])
11123
11124 ;; This pattern can't accept a variable shift count, since shifts by
11125 ;; zero don't affect the flags.  We assume that shifts by constant
11126 ;; zero are optimized away.
11127 (define_insn "*ashrsi3_one_bit_cmp"
11128   [(set (reg FLAGS_REG)
11129         (compare
11130           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11131                        (match_operand:QI 2 "const1_operand" ""))
11132           (const_int 0)))
11133    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11134         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11135   "ix86_match_ccmode (insn, CCGOCmode)
11136    && (TARGET_SHIFT1 || optimize_size)
11137    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11138   "sar{l}\t%0"
11139   [(set_attr "type" "ishift")
11140    (set (attr "length") 
11141      (if_then_else (match_operand:SI 0 "register_operand" "") 
11142         (const_string "2")
11143         (const_string "*")))])
11144
11145 (define_insn "*ashrsi3_one_bit_cmp_zext"
11146   [(set (reg FLAGS_REG)
11147         (compare
11148           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11149                        (match_operand:QI 2 "const1_operand" ""))
11150           (const_int 0)))
11151    (set (match_operand:DI 0 "register_operand" "=r")
11152         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11153   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11154    && (TARGET_SHIFT1 || optimize_size)
11155    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11156   "sar{l}\t%k0"
11157   [(set_attr "type" "ishift")
11158    (set_attr "length" "2")])
11159
11160 ;; This pattern can't accept a variable shift count, since shifts by
11161 ;; zero don't affect the flags.  We assume that shifts by constant
11162 ;; zero are optimized away.
11163 (define_insn "*ashrsi3_cmp"
11164   [(set (reg FLAGS_REG)
11165         (compare
11166           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11167                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11168           (const_int 0)))
11169    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11170         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11171   "ix86_match_ccmode (insn, CCGOCmode)
11172    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11173   "sar{l}\t{%2, %0|%0, %2}"
11174   [(set_attr "type" "ishift")
11175    (set_attr "mode" "SI")])
11176
11177 (define_insn "*ashrsi3_cmp_zext"
11178   [(set (reg FLAGS_REG)
11179         (compare
11180           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11181                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11182           (const_int 0)))
11183    (set (match_operand:DI 0 "register_operand" "=r")
11184         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11185   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11186    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11187   "sar{l}\t{%2, %k0|%k0, %2}"
11188   [(set_attr "type" "ishift")
11189    (set_attr "mode" "SI")])
11190
11191 (define_expand "ashrhi3"
11192   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11193         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11194                      (match_operand:QI 2 "nonmemory_operand" "")))
11195    (clobber (reg:CC FLAGS_REG))]
11196   "TARGET_HIMODE_MATH"
11197   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11198
11199 (define_insn "*ashrhi3_1_one_bit"
11200   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11201         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11202                      (match_operand:QI 2 "const1_operand" "")))
11203    (clobber (reg:CC FLAGS_REG))]
11204   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11205    && (TARGET_SHIFT1 || optimize_size)"
11206   "sar{w}\t%0"
11207   [(set_attr "type" "ishift")
11208    (set (attr "length") 
11209      (if_then_else (match_operand 0 "register_operand" "") 
11210         (const_string "2")
11211         (const_string "*")))])
11212
11213 (define_insn "*ashrhi3_1"
11214   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11215         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11216                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11217    (clobber (reg:CC FLAGS_REG))]
11218   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11219   "@
11220    sar{w}\t{%2, %0|%0, %2}
11221    sar{w}\t{%b2, %0|%0, %b2}"
11222   [(set_attr "type" "ishift")
11223    (set_attr "mode" "HI")])
11224
11225 ;; This pattern can't accept a variable shift count, since shifts by
11226 ;; zero don't affect the flags.  We assume that shifts by constant
11227 ;; zero are optimized away.
11228 (define_insn "*ashrhi3_one_bit_cmp"
11229   [(set (reg FLAGS_REG)
11230         (compare
11231           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11232                        (match_operand:QI 2 "const1_operand" ""))
11233           (const_int 0)))
11234    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11235         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11236   "ix86_match_ccmode (insn, CCGOCmode)
11237    && (TARGET_SHIFT1 || optimize_size)
11238    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11239   "sar{w}\t%0"
11240   [(set_attr "type" "ishift")
11241    (set (attr "length") 
11242      (if_then_else (match_operand 0 "register_operand" "") 
11243         (const_string "2")
11244         (const_string "*")))])
11245
11246 ;; This pattern can't accept a variable shift count, since shifts by
11247 ;; zero don't affect the flags.  We assume that shifts by constant
11248 ;; zero are optimized away.
11249 (define_insn "*ashrhi3_cmp"
11250   [(set (reg FLAGS_REG)
11251         (compare
11252           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11253                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11254           (const_int 0)))
11255    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11256         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11257   "ix86_match_ccmode (insn, CCGOCmode)
11258    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11259   "sar{w}\t{%2, %0|%0, %2}"
11260   [(set_attr "type" "ishift")
11261    (set_attr "mode" "HI")])
11262
11263 (define_expand "ashrqi3"
11264   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11265         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11266                      (match_operand:QI 2 "nonmemory_operand" "")))
11267    (clobber (reg:CC FLAGS_REG))]
11268   "TARGET_QIMODE_MATH"
11269   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11270
11271 (define_insn "*ashrqi3_1_one_bit"
11272   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11273         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11274                      (match_operand:QI 2 "const1_operand" "")))
11275    (clobber (reg:CC FLAGS_REG))]
11276   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11277    && (TARGET_SHIFT1 || optimize_size)"
11278   "sar{b}\t%0"
11279   [(set_attr "type" "ishift")
11280    (set (attr "length") 
11281      (if_then_else (match_operand 0 "register_operand" "") 
11282         (const_string "2")
11283         (const_string "*")))])
11284
11285 (define_insn "*ashrqi3_1_one_bit_slp"
11286   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11287         (ashiftrt:QI (match_dup 0)
11288                      (match_operand:QI 1 "const1_operand" "")))
11289    (clobber (reg:CC FLAGS_REG))]
11290   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11291    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11292    && (TARGET_SHIFT1 || optimize_size)"
11293   "sar{b}\t%0"
11294   [(set_attr "type" "ishift1")
11295    (set (attr "length") 
11296      (if_then_else (match_operand 0 "register_operand" "") 
11297         (const_string "2")
11298         (const_string "*")))])
11299
11300 (define_insn "*ashrqi3_1"
11301   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11302         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11303                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11304    (clobber (reg:CC FLAGS_REG))]
11305   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11306   "@
11307    sar{b}\t{%2, %0|%0, %2}
11308    sar{b}\t{%b2, %0|%0, %b2}"
11309   [(set_attr "type" "ishift")
11310    (set_attr "mode" "QI")])
11311
11312 (define_insn "*ashrqi3_1_slp"
11313   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11314         (ashiftrt:QI (match_dup 0)
11315                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11316    (clobber (reg:CC FLAGS_REG))]
11317   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11318    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11319   "@
11320    sar{b}\t{%1, %0|%0, %1}
11321    sar{b}\t{%b1, %0|%0, %b1}"
11322   [(set_attr "type" "ishift1")
11323    (set_attr "mode" "QI")])
11324
11325 ;; This pattern can't accept a variable shift count, since shifts by
11326 ;; zero don't affect the flags.  We assume that shifts by constant
11327 ;; zero are optimized away.
11328 (define_insn "*ashrqi3_one_bit_cmp"
11329   [(set (reg FLAGS_REG)
11330         (compare
11331           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11332                        (match_operand:QI 2 "const1_operand" "I"))
11333           (const_int 0)))
11334    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11335         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11336   "ix86_match_ccmode (insn, CCGOCmode)
11337    && (TARGET_SHIFT1 || optimize_size)
11338    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11339   "sar{b}\t%0"
11340   [(set_attr "type" "ishift")
11341    (set (attr "length") 
11342      (if_then_else (match_operand 0 "register_operand" "") 
11343         (const_string "2")
11344         (const_string "*")))])
11345
11346 ;; This pattern can't accept a variable shift count, since shifts by
11347 ;; zero don't affect the flags.  We assume that shifts by constant
11348 ;; zero are optimized away.
11349 (define_insn "*ashrqi3_cmp"
11350   [(set (reg FLAGS_REG)
11351         (compare
11352           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11353                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11354           (const_int 0)))
11355    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11356         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11357   "ix86_match_ccmode (insn, CCGOCmode)
11358    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11359   "sar{b}\t{%2, %0|%0, %2}"
11360   [(set_attr "type" "ishift")
11361    (set_attr "mode" "QI")])
11362 \f
11363 ;; Logical shift instructions
11364
11365 ;; See comment above `ashldi3' about how this works.
11366
11367 (define_expand "lshrdi3"
11368   [(set (match_operand:DI 0 "shiftdi_operand" "")
11369         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11370                      (match_operand:QI 2 "nonmemory_operand" "")))]
11371   ""
11372   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11373
11374 (define_insn "*lshrdi3_1_one_bit_rex64"
11375   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11376         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11377                      (match_operand:QI 2 "const1_operand" "")))
11378    (clobber (reg:CC FLAGS_REG))]
11379   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11380    && (TARGET_SHIFT1 || optimize_size)"
11381   "shr{q}\t%0"
11382   [(set_attr "type" "ishift")
11383    (set (attr "length") 
11384      (if_then_else (match_operand:DI 0 "register_operand" "") 
11385         (const_string "2")
11386         (const_string "*")))])
11387
11388 (define_insn "*lshrdi3_1_rex64"
11389   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11390         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11391                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11392    (clobber (reg:CC FLAGS_REG))]
11393   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11394   "@
11395    shr{q}\t{%2, %0|%0, %2}
11396    shr{q}\t{%b2, %0|%0, %b2}"
11397   [(set_attr "type" "ishift")
11398    (set_attr "mode" "DI")])
11399
11400 ;; This pattern can't accept a variable shift count, since shifts by
11401 ;; zero don't affect the flags.  We assume that shifts by constant
11402 ;; zero are optimized away.
11403 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11404   [(set (reg FLAGS_REG)
11405         (compare
11406           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11407                        (match_operand:QI 2 "const1_operand" ""))
11408           (const_int 0)))
11409    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11410         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11411   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11412    && (TARGET_SHIFT1 || optimize_size)
11413    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11414   "shr{q}\t%0"
11415   [(set_attr "type" "ishift")
11416    (set (attr "length") 
11417      (if_then_else (match_operand:DI 0 "register_operand" "") 
11418         (const_string "2")
11419         (const_string "*")))])
11420
11421 ;; This pattern can't accept a variable shift count, since shifts by
11422 ;; zero don't affect the flags.  We assume that shifts by constant
11423 ;; zero are optimized away.
11424 (define_insn "*lshrdi3_cmp_rex64"
11425   [(set (reg FLAGS_REG)
11426         (compare
11427           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11428                        (match_operand:QI 2 "const_int_operand" "e"))
11429           (const_int 0)))
11430    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11431         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11432   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11433    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11434   "shr{q}\t{%2, %0|%0, %2}"
11435   [(set_attr "type" "ishift")
11436    (set_attr "mode" "DI")])
11437
11438 (define_insn "*lshrdi3_1"
11439   [(set (match_operand:DI 0 "register_operand" "=r")
11440         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11441                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11442    (clobber (reg:CC FLAGS_REG))]
11443   "!TARGET_64BIT"
11444   "#"
11445   [(set_attr "type" "multi")])
11446
11447 ;; By default we don't ask for a scratch register, because when DImode
11448 ;; values are manipulated, registers are already at a premium.  But if
11449 ;; we have one handy, we won't turn it away.
11450 (define_peephole2
11451   [(match_scratch:SI 3 "r")
11452    (parallel [(set (match_operand:DI 0 "register_operand" "")
11453                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11454                                 (match_operand:QI 2 "nonmemory_operand" "")))
11455               (clobber (reg:CC FLAGS_REG))])
11456    (match_dup 3)]
11457   "!TARGET_64BIT && TARGET_CMOVE"
11458   [(const_int 0)]
11459   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11460
11461 (define_split 
11462   [(set (match_operand:DI 0 "register_operand" "")
11463         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11464                      (match_operand:QI 2 "nonmemory_operand" "")))
11465    (clobber (reg:CC FLAGS_REG))]
11466   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11467   [(const_int 0)]
11468   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11469
11470 (define_expand "lshrsi3"
11471   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11472         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11473                      (match_operand:QI 2 "nonmemory_operand" "")))
11474    (clobber (reg:CC FLAGS_REG))]
11475   ""
11476   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11477
11478 (define_insn "*lshrsi3_1_one_bit"
11479   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11480         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11481                      (match_operand:QI 2 "const1_operand" "")))
11482    (clobber (reg:CC FLAGS_REG))]
11483   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11484    && (TARGET_SHIFT1 || optimize_size)"
11485   "shr{l}\t%0"
11486   [(set_attr "type" "ishift")
11487    (set (attr "length") 
11488      (if_then_else (match_operand:SI 0 "register_operand" "") 
11489         (const_string "2")
11490         (const_string "*")))])
11491
11492 (define_insn "*lshrsi3_1_one_bit_zext"
11493   [(set (match_operand:DI 0 "register_operand" "=r")
11494         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11495                      (match_operand:QI 2 "const1_operand" "")))
11496    (clobber (reg:CC FLAGS_REG))]
11497   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11498    && (TARGET_SHIFT1 || optimize_size)"
11499   "shr{l}\t%k0"
11500   [(set_attr "type" "ishift")
11501    (set_attr "length" "2")])
11502
11503 (define_insn "*lshrsi3_1"
11504   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11505         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11506                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11507    (clobber (reg:CC FLAGS_REG))]
11508   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11509   "@
11510    shr{l}\t{%2, %0|%0, %2}
11511    shr{l}\t{%b2, %0|%0, %b2}"
11512   [(set_attr "type" "ishift")
11513    (set_attr "mode" "SI")])
11514
11515 (define_insn "*lshrsi3_1_zext"
11516   [(set (match_operand:DI 0 "register_operand" "=r,r")
11517         (zero_extend:DI
11518           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11519                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11520    (clobber (reg:CC FLAGS_REG))]
11521   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11522   "@
11523    shr{l}\t{%2, %k0|%k0, %2}
11524    shr{l}\t{%b2, %k0|%k0, %b2}"
11525   [(set_attr "type" "ishift")
11526    (set_attr "mode" "SI")])
11527
11528 ;; This pattern can't accept a variable shift count, since shifts by
11529 ;; zero don't affect the flags.  We assume that shifts by constant
11530 ;; zero are optimized away.
11531 (define_insn "*lshrsi3_one_bit_cmp"
11532   [(set (reg FLAGS_REG)
11533         (compare
11534           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11535                        (match_operand:QI 2 "const1_operand" ""))
11536           (const_int 0)))
11537    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11538         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11539   "ix86_match_ccmode (insn, CCGOCmode)
11540    && (TARGET_SHIFT1 || optimize_size)
11541    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11542   "shr{l}\t%0"
11543   [(set_attr "type" "ishift")
11544    (set (attr "length") 
11545      (if_then_else (match_operand:SI 0 "register_operand" "") 
11546         (const_string "2")
11547         (const_string "*")))])
11548
11549 (define_insn "*lshrsi3_cmp_one_bit_zext"
11550   [(set (reg FLAGS_REG)
11551         (compare
11552           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11553                        (match_operand:QI 2 "const1_operand" ""))
11554           (const_int 0)))
11555    (set (match_operand:DI 0 "register_operand" "=r")
11556         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11557   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11558    && (TARGET_SHIFT1 || optimize_size)
11559    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11560   "shr{l}\t%k0"
11561   [(set_attr "type" "ishift")
11562    (set_attr "length" "2")])
11563
11564 ;; This pattern can't accept a variable shift count, since shifts by
11565 ;; zero don't affect the flags.  We assume that shifts by constant
11566 ;; zero are optimized away.
11567 (define_insn "*lshrsi3_cmp"
11568   [(set (reg FLAGS_REG)
11569         (compare
11570           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11571                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11572           (const_int 0)))
11573    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11574         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11575   "ix86_match_ccmode (insn, CCGOCmode)
11576    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11577   "shr{l}\t{%2, %0|%0, %2}"
11578   [(set_attr "type" "ishift")
11579    (set_attr "mode" "SI")])
11580
11581 (define_insn "*lshrsi3_cmp_zext"
11582   [(set (reg FLAGS_REG)
11583         (compare
11584           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11585                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11586           (const_int 0)))
11587    (set (match_operand:DI 0 "register_operand" "=r")
11588         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11589   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11590    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11591   "shr{l}\t{%2, %k0|%k0, %2}"
11592   [(set_attr "type" "ishift")
11593    (set_attr "mode" "SI")])
11594
11595 (define_expand "lshrhi3"
11596   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11597         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11598                      (match_operand:QI 2 "nonmemory_operand" "")))
11599    (clobber (reg:CC FLAGS_REG))]
11600   "TARGET_HIMODE_MATH"
11601   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11602
11603 (define_insn "*lshrhi3_1_one_bit"
11604   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11605         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11606                      (match_operand:QI 2 "const1_operand" "")))
11607    (clobber (reg:CC FLAGS_REG))]
11608   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11609    && (TARGET_SHIFT1 || optimize_size)"
11610   "shr{w}\t%0"
11611   [(set_attr "type" "ishift")
11612    (set (attr "length") 
11613      (if_then_else (match_operand 0 "register_operand" "") 
11614         (const_string "2")
11615         (const_string "*")))])
11616
11617 (define_insn "*lshrhi3_1"
11618   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11619         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11620                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11621    (clobber (reg:CC FLAGS_REG))]
11622   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11623   "@
11624    shr{w}\t{%2, %0|%0, %2}
11625    shr{w}\t{%b2, %0|%0, %b2}"
11626   [(set_attr "type" "ishift")
11627    (set_attr "mode" "HI")])
11628
11629 ;; This pattern can't accept a variable shift count, since shifts by
11630 ;; zero don't affect the flags.  We assume that shifts by constant
11631 ;; zero are optimized away.
11632 (define_insn "*lshrhi3_one_bit_cmp"
11633   [(set (reg FLAGS_REG)
11634         (compare
11635           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11636                        (match_operand:QI 2 "const1_operand" ""))
11637           (const_int 0)))
11638    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11639         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11640   "ix86_match_ccmode (insn, CCGOCmode)
11641    && (TARGET_SHIFT1 || optimize_size)
11642    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11643   "shr{w}\t%0"
11644   [(set_attr "type" "ishift")
11645    (set (attr "length") 
11646      (if_then_else (match_operand:SI 0 "register_operand" "") 
11647         (const_string "2")
11648         (const_string "*")))])
11649
11650 ;; This pattern can't accept a variable shift count, since shifts by
11651 ;; zero don't affect the flags.  We assume that shifts by constant
11652 ;; zero are optimized away.
11653 (define_insn "*lshrhi3_cmp"
11654   [(set (reg FLAGS_REG)
11655         (compare
11656           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11657                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11658           (const_int 0)))
11659    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11660         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11661   "ix86_match_ccmode (insn, CCGOCmode)
11662    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11663   "shr{w}\t{%2, %0|%0, %2}"
11664   [(set_attr "type" "ishift")
11665    (set_attr "mode" "HI")])
11666
11667 (define_expand "lshrqi3"
11668   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11669         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11670                      (match_operand:QI 2 "nonmemory_operand" "")))
11671    (clobber (reg:CC FLAGS_REG))]
11672   "TARGET_QIMODE_MATH"
11673   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11674
11675 (define_insn "*lshrqi3_1_one_bit"
11676   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11677         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11678                      (match_operand:QI 2 "const1_operand" "")))
11679    (clobber (reg:CC FLAGS_REG))]
11680   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11681    && (TARGET_SHIFT1 || optimize_size)"
11682   "shr{b}\t%0"
11683   [(set_attr "type" "ishift")
11684    (set (attr "length") 
11685      (if_then_else (match_operand 0 "register_operand" "") 
11686         (const_string "2")
11687         (const_string "*")))])
11688
11689 (define_insn "*lshrqi3_1_one_bit_slp"
11690   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11691         (lshiftrt:QI (match_dup 0)
11692                      (match_operand:QI 1 "const1_operand" "")))
11693    (clobber (reg:CC FLAGS_REG))]
11694   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11695    && (TARGET_SHIFT1 || optimize_size)"
11696   "shr{b}\t%0"
11697   [(set_attr "type" "ishift1")
11698    (set (attr "length") 
11699      (if_then_else (match_operand 0 "register_operand" "") 
11700         (const_string "2")
11701         (const_string "*")))])
11702
11703 (define_insn "*lshrqi3_1"
11704   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11705         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11706                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11707    (clobber (reg:CC FLAGS_REG))]
11708   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11709   "@
11710    shr{b}\t{%2, %0|%0, %2}
11711    shr{b}\t{%b2, %0|%0, %b2}"
11712   [(set_attr "type" "ishift")
11713    (set_attr "mode" "QI")])
11714
11715 (define_insn "*lshrqi3_1_slp"
11716   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11717         (lshiftrt:QI (match_dup 0)
11718                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11719    (clobber (reg:CC FLAGS_REG))]
11720   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11721    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11722   "@
11723    shr{b}\t{%1, %0|%0, %1}
11724    shr{b}\t{%b1, %0|%0, %b1}"
11725   [(set_attr "type" "ishift1")
11726    (set_attr "mode" "QI")])
11727
11728 ;; This pattern can't accept a variable shift count, since shifts by
11729 ;; zero don't affect the flags.  We assume that shifts by constant
11730 ;; zero are optimized away.
11731 (define_insn "*lshrqi2_one_bit_cmp"
11732   [(set (reg FLAGS_REG)
11733         (compare
11734           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11735                        (match_operand:QI 2 "const1_operand" ""))
11736           (const_int 0)))
11737    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11738         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11739   "ix86_match_ccmode (insn, CCGOCmode)
11740    && (TARGET_SHIFT1 || optimize_size)
11741    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11742   "shr{b}\t%0"
11743   [(set_attr "type" "ishift")
11744    (set (attr "length") 
11745      (if_then_else (match_operand:SI 0 "register_operand" "") 
11746         (const_string "2")
11747         (const_string "*")))])
11748
11749 ;; This pattern can't accept a variable shift count, since shifts by
11750 ;; zero don't affect the flags.  We assume that shifts by constant
11751 ;; zero are optimized away.
11752 (define_insn "*lshrqi2_cmp"
11753   [(set (reg FLAGS_REG)
11754         (compare
11755           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11756                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11757           (const_int 0)))
11758    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11759         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11760   "ix86_match_ccmode (insn, CCGOCmode)
11761    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11762   "shr{b}\t{%2, %0|%0, %2}"
11763   [(set_attr "type" "ishift")
11764    (set_attr "mode" "QI")])
11765 \f
11766 ;; Rotate instructions
11767
11768 (define_expand "rotldi3"
11769   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11770         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11771                    (match_operand:QI 2 "nonmemory_operand" "")))
11772    (clobber (reg:CC FLAGS_REG))]
11773   "TARGET_64BIT"
11774   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11775
11776 (define_insn "*rotlsi3_1_one_bit_rex64"
11777   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11778         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11779                    (match_operand:QI 2 "const1_operand" "")))
11780    (clobber (reg:CC FLAGS_REG))]
11781   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11782    && (TARGET_SHIFT1 || optimize_size)"
11783   "rol{q}\t%0"
11784   [(set_attr "type" "rotate")
11785    (set (attr "length") 
11786      (if_then_else (match_operand:DI 0 "register_operand" "") 
11787         (const_string "2")
11788         (const_string "*")))])
11789
11790 (define_insn "*rotldi3_1_rex64"
11791   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11792         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11793                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11794    (clobber (reg:CC FLAGS_REG))]
11795   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11796   "@
11797    rol{q}\t{%2, %0|%0, %2}
11798    rol{q}\t{%b2, %0|%0, %b2}"
11799   [(set_attr "type" "rotate")
11800    (set_attr "mode" "DI")])
11801
11802 (define_expand "rotlsi3"
11803   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11804         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11805                    (match_operand:QI 2 "nonmemory_operand" "")))
11806    (clobber (reg:CC FLAGS_REG))]
11807   ""
11808   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11809
11810 (define_insn "*rotlsi3_1_one_bit"
11811   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11812         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11813                    (match_operand:QI 2 "const1_operand" "")))
11814    (clobber (reg:CC FLAGS_REG))]
11815   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11816    && (TARGET_SHIFT1 || optimize_size)"
11817   "rol{l}\t%0"
11818   [(set_attr "type" "rotate")
11819    (set (attr "length") 
11820      (if_then_else (match_operand:SI 0 "register_operand" "") 
11821         (const_string "2")
11822         (const_string "*")))])
11823
11824 (define_insn "*rotlsi3_1_one_bit_zext"
11825   [(set (match_operand:DI 0 "register_operand" "=r")
11826         (zero_extend:DI
11827           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11828                      (match_operand:QI 2 "const1_operand" ""))))
11829    (clobber (reg:CC FLAGS_REG))]
11830   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11831    && (TARGET_SHIFT1 || optimize_size)"
11832   "rol{l}\t%k0"
11833   [(set_attr "type" "rotate")
11834    (set_attr "length" "2")])
11835
11836 (define_insn "*rotlsi3_1"
11837   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11838         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11839                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11840    (clobber (reg:CC FLAGS_REG))]
11841   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11842   "@
11843    rol{l}\t{%2, %0|%0, %2}
11844    rol{l}\t{%b2, %0|%0, %b2}"
11845   [(set_attr "type" "rotate")
11846    (set_attr "mode" "SI")])
11847
11848 (define_insn "*rotlsi3_1_zext"
11849   [(set (match_operand:DI 0 "register_operand" "=r,r")
11850         (zero_extend:DI
11851           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11852                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11853    (clobber (reg:CC FLAGS_REG))]
11854   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11855   "@
11856    rol{l}\t{%2, %k0|%k0, %2}
11857    rol{l}\t{%b2, %k0|%k0, %b2}"
11858   [(set_attr "type" "rotate")
11859    (set_attr "mode" "SI")])
11860
11861 (define_expand "rotlhi3"
11862   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11863         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11864                    (match_operand:QI 2 "nonmemory_operand" "")))
11865    (clobber (reg:CC FLAGS_REG))]
11866   "TARGET_HIMODE_MATH"
11867   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11868
11869 (define_insn "*rotlhi3_1_one_bit"
11870   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11871         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11872                    (match_operand:QI 2 "const1_operand" "")))
11873    (clobber (reg:CC FLAGS_REG))]
11874   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11875    && (TARGET_SHIFT1 || optimize_size)"
11876   "rol{w}\t%0"
11877   [(set_attr "type" "rotate")
11878    (set (attr "length") 
11879      (if_then_else (match_operand 0 "register_operand" "") 
11880         (const_string "2")
11881         (const_string "*")))])
11882
11883 (define_insn "*rotlhi3_1"
11884   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11885         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11886                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11887    (clobber (reg:CC FLAGS_REG))]
11888   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11889   "@
11890    rol{w}\t{%2, %0|%0, %2}
11891    rol{w}\t{%b2, %0|%0, %b2}"
11892   [(set_attr "type" "rotate")
11893    (set_attr "mode" "HI")])
11894
11895 (define_expand "rotlqi3"
11896   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11897         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11898                    (match_operand:QI 2 "nonmemory_operand" "")))
11899    (clobber (reg:CC FLAGS_REG))]
11900   "TARGET_QIMODE_MATH"
11901   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11902
11903 (define_insn "*rotlqi3_1_one_bit_slp"
11904   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11905         (rotate:QI (match_dup 0)
11906                    (match_operand:QI 1 "const1_operand" "")))
11907    (clobber (reg:CC FLAGS_REG))]
11908   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11909    && (TARGET_SHIFT1 || optimize_size)"
11910   "rol{b}\t%0"
11911   [(set_attr "type" "rotate1")
11912    (set (attr "length") 
11913      (if_then_else (match_operand 0 "register_operand" "") 
11914         (const_string "2")
11915         (const_string "*")))])
11916
11917 (define_insn "*rotlqi3_1_one_bit"
11918   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11919         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11920                    (match_operand:QI 2 "const1_operand" "")))
11921    (clobber (reg:CC FLAGS_REG))]
11922   "ix86_binary_operator_ok (ROTATE, QImode, operands)
11923    && (TARGET_SHIFT1 || optimize_size)"
11924   "rol{b}\t%0"
11925   [(set_attr "type" "rotate")
11926    (set (attr "length") 
11927      (if_then_else (match_operand 0 "register_operand" "") 
11928         (const_string "2")
11929         (const_string "*")))])
11930
11931 (define_insn "*rotlqi3_1_slp"
11932   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11933         (rotate:QI (match_dup 0)
11934                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
11935    (clobber (reg:CC FLAGS_REG))]
11936   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11937    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11938   "@
11939    rol{b}\t{%1, %0|%0, %1}
11940    rol{b}\t{%b1, %0|%0, %b1}"
11941   [(set_attr "type" "rotate1")
11942    (set_attr "mode" "QI")])
11943
11944 (define_insn "*rotlqi3_1"
11945   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11946         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11947                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11948    (clobber (reg:CC FLAGS_REG))]
11949   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11950   "@
11951    rol{b}\t{%2, %0|%0, %2}
11952    rol{b}\t{%b2, %0|%0, %b2}"
11953   [(set_attr "type" "rotate")
11954    (set_attr "mode" "QI")])
11955
11956 (define_expand "rotrdi3"
11957   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11958         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11959                      (match_operand:QI 2 "nonmemory_operand" "")))
11960    (clobber (reg:CC FLAGS_REG))]
11961   "TARGET_64BIT"
11962   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11963
11964 (define_insn "*rotrdi3_1_one_bit_rex64"
11965   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11966         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11967                      (match_operand:QI 2 "const1_operand" "")))
11968    (clobber (reg:CC FLAGS_REG))]
11969   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11970    && (TARGET_SHIFT1 || optimize_size)"
11971   "ror{q}\t%0"
11972   [(set_attr "type" "rotate")
11973    (set (attr "length") 
11974      (if_then_else (match_operand:DI 0 "register_operand" "") 
11975         (const_string "2")
11976         (const_string "*")))])
11977
11978 (define_insn "*rotrdi3_1_rex64"
11979   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11980         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11981                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11982    (clobber (reg:CC FLAGS_REG))]
11983   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11984   "@
11985    ror{q}\t{%2, %0|%0, %2}
11986    ror{q}\t{%b2, %0|%0, %b2}"
11987   [(set_attr "type" "rotate")
11988    (set_attr "mode" "DI")])
11989
11990 (define_expand "rotrsi3"
11991   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11992         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11993                      (match_operand:QI 2 "nonmemory_operand" "")))
11994    (clobber (reg:CC FLAGS_REG))]
11995   ""
11996   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11997
11998 (define_insn "*rotrsi3_1_one_bit"
11999   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12000         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12001                      (match_operand:QI 2 "const1_operand" "")))
12002    (clobber (reg:CC FLAGS_REG))]
12003   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12004    && (TARGET_SHIFT1 || optimize_size)"
12005   "ror{l}\t%0"
12006   [(set_attr "type" "rotate")
12007    (set (attr "length") 
12008      (if_then_else (match_operand:SI 0 "register_operand" "") 
12009         (const_string "2")
12010         (const_string "*")))])
12011
12012 (define_insn "*rotrsi3_1_one_bit_zext"
12013   [(set (match_operand:DI 0 "register_operand" "=r")
12014         (zero_extend:DI
12015           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12016                        (match_operand:QI 2 "const1_operand" ""))))
12017    (clobber (reg:CC FLAGS_REG))]
12018   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12019    && (TARGET_SHIFT1 || optimize_size)"
12020   "ror{l}\t%k0"
12021   [(set_attr "type" "rotate")
12022    (set (attr "length") 
12023      (if_then_else (match_operand:SI 0 "register_operand" "") 
12024         (const_string "2")
12025         (const_string "*")))])
12026
12027 (define_insn "*rotrsi3_1"
12028   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12029         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12030                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12031    (clobber (reg:CC FLAGS_REG))]
12032   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12033   "@
12034    ror{l}\t{%2, %0|%0, %2}
12035    ror{l}\t{%b2, %0|%0, %b2}"
12036   [(set_attr "type" "rotate")
12037    (set_attr "mode" "SI")])
12038
12039 (define_insn "*rotrsi3_1_zext"
12040   [(set (match_operand:DI 0 "register_operand" "=r,r")
12041         (zero_extend:DI
12042           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12043                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12044    (clobber (reg:CC FLAGS_REG))]
12045   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12046   "@
12047    ror{l}\t{%2, %k0|%k0, %2}
12048    ror{l}\t{%b2, %k0|%k0, %b2}"
12049   [(set_attr "type" "rotate")
12050    (set_attr "mode" "SI")])
12051
12052 (define_expand "rotrhi3"
12053   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12054         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12055                      (match_operand:QI 2 "nonmemory_operand" "")))
12056    (clobber (reg:CC FLAGS_REG))]
12057   "TARGET_HIMODE_MATH"
12058   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12059
12060 (define_insn "*rotrhi3_one_bit"
12061   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12062         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12063                      (match_operand:QI 2 "const1_operand" "")))
12064    (clobber (reg:CC FLAGS_REG))]
12065   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12066    && (TARGET_SHIFT1 || optimize_size)"
12067   "ror{w}\t%0"
12068   [(set_attr "type" "rotate")
12069    (set (attr "length") 
12070      (if_then_else (match_operand 0 "register_operand" "") 
12071         (const_string "2")
12072         (const_string "*")))])
12073
12074 (define_insn "*rotrhi3"
12075   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12076         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12077                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12078    (clobber (reg:CC FLAGS_REG))]
12079   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12080   "@
12081    ror{w}\t{%2, %0|%0, %2}
12082    ror{w}\t{%b2, %0|%0, %b2}"
12083   [(set_attr "type" "rotate")
12084    (set_attr "mode" "HI")])
12085
12086 (define_expand "rotrqi3"
12087   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12088         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12089                      (match_operand:QI 2 "nonmemory_operand" "")))
12090    (clobber (reg:CC FLAGS_REG))]
12091   "TARGET_QIMODE_MATH"
12092   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12093
12094 (define_insn "*rotrqi3_1_one_bit"
12095   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12096         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12097                      (match_operand:QI 2 "const1_operand" "")))
12098    (clobber (reg:CC FLAGS_REG))]
12099   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12100    && (TARGET_SHIFT1 || optimize_size)"
12101   "ror{b}\t%0"
12102   [(set_attr "type" "rotate")
12103    (set (attr "length") 
12104      (if_then_else (match_operand 0 "register_operand" "") 
12105         (const_string "2")
12106         (const_string "*")))])
12107
12108 (define_insn "*rotrqi3_1_one_bit_slp"
12109   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12110         (rotatert:QI (match_dup 0)
12111                      (match_operand:QI 1 "const1_operand" "")))
12112    (clobber (reg:CC FLAGS_REG))]
12113   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12114    && (TARGET_SHIFT1 || optimize_size)"
12115   "ror{b}\t%0"
12116   [(set_attr "type" "rotate1")
12117    (set (attr "length") 
12118      (if_then_else (match_operand 0 "register_operand" "") 
12119         (const_string "2")
12120         (const_string "*")))])
12121
12122 (define_insn "*rotrqi3_1"
12123   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12124         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12125                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12126    (clobber (reg:CC FLAGS_REG))]
12127   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12128   "@
12129    ror{b}\t{%2, %0|%0, %2}
12130    ror{b}\t{%b2, %0|%0, %b2}"
12131   [(set_attr "type" "rotate")
12132    (set_attr "mode" "QI")])
12133
12134 (define_insn "*rotrqi3_1_slp"
12135   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12136         (rotatert:QI (match_dup 0)
12137                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12138    (clobber (reg:CC FLAGS_REG))]
12139   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12140    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12141   "@
12142    ror{b}\t{%1, %0|%0, %1}
12143    ror{b}\t{%b1, %0|%0, %b1}"
12144   [(set_attr "type" "rotate1")
12145    (set_attr "mode" "QI")])
12146 \f
12147 ;; Bit set / bit test instructions
12148
12149 (define_expand "extv"
12150   [(set (match_operand:SI 0 "register_operand" "")
12151         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12152                          (match_operand:SI 2 "immediate_operand" "")
12153                          (match_operand:SI 3 "immediate_operand" "")))]
12154   ""
12155 {
12156   /* Handle extractions from %ah et al.  */
12157   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12158     FAIL;
12159
12160   /* From mips.md: extract_bit_field doesn't verify that our source
12161      matches the predicate, so check it again here.  */
12162   if (! ext_register_operand (operands[1], VOIDmode))
12163     FAIL;
12164 })
12165
12166 (define_expand "extzv"
12167   [(set (match_operand:SI 0 "register_operand" "")
12168         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12169                          (match_operand:SI 2 "immediate_operand" "")
12170                          (match_operand:SI 3 "immediate_operand" "")))]
12171   ""
12172 {
12173   /* Handle extractions from %ah et al.  */
12174   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12175     FAIL;
12176
12177   /* From mips.md: extract_bit_field doesn't verify that our source
12178      matches the predicate, so check it again here.  */
12179   if (! ext_register_operand (operands[1], VOIDmode))
12180     FAIL;
12181 })
12182
12183 (define_expand "insv"
12184   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12185                       (match_operand 1 "immediate_operand" "")
12186                       (match_operand 2 "immediate_operand" ""))
12187         (match_operand 3 "register_operand" ""))]
12188   ""
12189 {
12190   /* Handle extractions from %ah et al.  */
12191   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12192     FAIL;
12193
12194   /* From mips.md: insert_bit_field doesn't verify that our source
12195      matches the predicate, so check it again here.  */
12196   if (! ext_register_operand (operands[0], VOIDmode))
12197     FAIL;
12198
12199   if (TARGET_64BIT)
12200     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12201   else
12202     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12203
12204   DONE;
12205 })
12206
12207 ;; %%% bts, btr, btc, bt.
12208 ;; In general these instructions are *slow* when applied to memory,
12209 ;; since they enforce atomic operation.  When applied to registers,
12210 ;; it depends on the cpu implementation.  They're never faster than
12211 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12212 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12213 ;; within the instruction itself, so operating on bits in the high
12214 ;; 32-bits of a register becomes easier.
12215 ;;
12216 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12217 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12218 ;; negdf respectively, so they can never be disabled entirely.
12219
12220 (define_insn "*btsq"
12221   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12222                          (const_int 1)
12223                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12224         (const_int 1))
12225    (clobber (reg:CC FLAGS_REG))]
12226   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12227   "bts{q} %1,%0"
12228   [(set_attr "type" "alu1")])
12229
12230 (define_insn "*btrq"
12231   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12232                          (const_int 1)
12233                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12234         (const_int 0))
12235    (clobber (reg:CC FLAGS_REG))]
12236   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12237   "btr{q} %1,%0"
12238   [(set_attr "type" "alu1")])
12239
12240 (define_insn "*btcq"
12241   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12242                          (const_int 1)
12243                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12244         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12245    (clobber (reg:CC FLAGS_REG))]
12246   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12247   "btc{q} %1,%0"
12248   [(set_attr "type" "alu1")])
12249
12250 ;; Allow Nocona to avoid these instructions if a register is available.
12251
12252 (define_peephole2
12253   [(match_scratch:DI 2 "r")
12254    (parallel [(set (zero_extract:DI
12255                      (match_operand:DI 0 "register_operand" "")
12256                      (const_int 1)
12257                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12258                    (const_int 1))
12259               (clobber (reg:CC FLAGS_REG))])]
12260   "TARGET_64BIT && !TARGET_USE_BT"
12261   [(const_int 0)]
12262 {
12263   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12264   rtx op1;
12265
12266   if (HOST_BITS_PER_WIDE_INT >= 64)
12267     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12268   else if (i < HOST_BITS_PER_WIDE_INT)
12269     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12270   else
12271     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12272
12273   op1 = immed_double_const (lo, hi, DImode);
12274   if (i >= 31)
12275     {
12276       emit_move_insn (operands[2], op1);
12277       op1 = operands[2];
12278     }
12279
12280   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12281   DONE;
12282 })
12283
12284 (define_peephole2
12285   [(match_scratch:DI 2 "r")
12286    (parallel [(set (zero_extract:DI
12287                      (match_operand:DI 0 "register_operand" "")
12288                      (const_int 1)
12289                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12290                    (const_int 0))
12291               (clobber (reg:CC FLAGS_REG))])]
12292   "TARGET_64BIT && !TARGET_USE_BT"
12293   [(const_int 0)]
12294 {
12295   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12296   rtx op1;
12297
12298   if (HOST_BITS_PER_WIDE_INT >= 64)
12299     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12300   else if (i < HOST_BITS_PER_WIDE_INT)
12301     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12302   else
12303     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12304
12305   op1 = immed_double_const (~lo, ~hi, DImode);
12306   if (i >= 32)
12307     {
12308       emit_move_insn (operands[2], op1);
12309       op1 = operands[2];
12310     }
12311
12312   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12313   DONE;
12314 })
12315
12316 (define_peephole2
12317   [(match_scratch:DI 2 "r")
12318    (parallel [(set (zero_extract:DI
12319                      (match_operand:DI 0 "register_operand" "")
12320                      (const_int 1)
12321                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12322               (not:DI (zero_extract:DI
12323                         (match_dup 0) (const_int 1) (match_dup 1))))
12324               (clobber (reg:CC FLAGS_REG))])]
12325   "TARGET_64BIT && !TARGET_USE_BT"
12326   [(const_int 0)]
12327 {
12328   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12329   rtx op1;
12330
12331   if (HOST_BITS_PER_WIDE_INT >= 64)
12332     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12333   else if (i < HOST_BITS_PER_WIDE_INT)
12334     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12335   else
12336     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12337
12338   op1 = immed_double_const (lo, hi, DImode);
12339   if (i >= 31)
12340     {
12341       emit_move_insn (operands[2], op1);
12342       op1 = operands[2];
12343     }
12344
12345   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12346   DONE;
12347 })
12348 \f
12349 ;; Store-flag instructions.
12350
12351 ;; For all sCOND expanders, also expand the compare or test insn that
12352 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12353
12354 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12355 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12356 ;; way, which can later delete the movzx if only QImode is needed.
12357
12358 (define_expand "seq"
12359   [(set (match_operand:QI 0 "register_operand" "")
12360         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12361   ""
12362   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12363
12364 (define_expand "sne"
12365   [(set (match_operand:QI 0 "register_operand" "")
12366         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12367   ""
12368   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12369
12370 (define_expand "sgt"
12371   [(set (match_operand:QI 0 "register_operand" "")
12372         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12373   ""
12374   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12375
12376 (define_expand "sgtu"
12377   [(set (match_operand:QI 0 "register_operand" "")
12378         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12379   ""
12380   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12381
12382 (define_expand "slt"
12383   [(set (match_operand:QI 0 "register_operand" "")
12384         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12385   ""
12386   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12387
12388 (define_expand "sltu"
12389   [(set (match_operand:QI 0 "register_operand" "")
12390         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12391   ""
12392   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12393
12394 (define_expand "sge"
12395   [(set (match_operand:QI 0 "register_operand" "")
12396         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12397   ""
12398   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12399
12400 (define_expand "sgeu"
12401   [(set (match_operand:QI 0 "register_operand" "")
12402         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12403   ""
12404   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12405
12406 (define_expand "sle"
12407   [(set (match_operand:QI 0 "register_operand" "")
12408         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12409   ""
12410   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12411
12412 (define_expand "sleu"
12413   [(set (match_operand:QI 0 "register_operand" "")
12414         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12415   ""
12416   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12417
12418 (define_expand "sunordered"
12419   [(set (match_operand:QI 0 "register_operand" "")
12420         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12421   "TARGET_80387 || TARGET_SSE"
12422   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12423
12424 (define_expand "sordered"
12425   [(set (match_operand:QI 0 "register_operand" "")
12426         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12427   "TARGET_80387"
12428   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12429
12430 (define_expand "suneq"
12431   [(set (match_operand:QI 0 "register_operand" "")
12432         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12433   "TARGET_80387 || TARGET_SSE"
12434   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12435
12436 (define_expand "sunge"
12437   [(set (match_operand:QI 0 "register_operand" "")
12438         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12439   "TARGET_80387 || TARGET_SSE"
12440   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12441
12442 (define_expand "sungt"
12443   [(set (match_operand:QI 0 "register_operand" "")
12444         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12445   "TARGET_80387 || TARGET_SSE"
12446   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12447
12448 (define_expand "sunle"
12449   [(set (match_operand:QI 0 "register_operand" "")
12450         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12451   "TARGET_80387 || TARGET_SSE"
12452   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12453
12454 (define_expand "sunlt"
12455   [(set (match_operand:QI 0 "register_operand" "")
12456         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12457   "TARGET_80387 || TARGET_SSE"
12458   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12459
12460 (define_expand "sltgt"
12461   [(set (match_operand:QI 0 "register_operand" "")
12462         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12463   "TARGET_80387 || TARGET_SSE"
12464   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12465
12466 (define_insn "*setcc_1"
12467   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12468         (match_operator:QI 1 "ix86_comparison_operator"
12469           [(reg FLAGS_REG) (const_int 0)]))]
12470   ""
12471   "set%C1\t%0"
12472   [(set_attr "type" "setcc")
12473    (set_attr "mode" "QI")])
12474
12475 (define_insn "*setcc_2"
12476   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12477         (match_operator:QI 1 "ix86_comparison_operator"
12478           [(reg FLAGS_REG) (const_int 0)]))]
12479   ""
12480   "set%C1\t%0"
12481   [(set_attr "type" "setcc")
12482    (set_attr "mode" "QI")])
12483
12484 ;; In general it is not safe to assume too much about CCmode registers,
12485 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12486 ;; conditions this is safe on x86, so help combine not create
12487 ;;
12488 ;;      seta    %al
12489 ;;      testb   %al, %al
12490 ;;      sete    %al
12491
12492 (define_split 
12493   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12494         (ne:QI (match_operator 1 "ix86_comparison_operator"
12495                  [(reg FLAGS_REG) (const_int 0)])
12496             (const_int 0)))]
12497   ""
12498   [(set (match_dup 0) (match_dup 1))]
12499 {
12500   PUT_MODE (operands[1], QImode);
12501 })
12502
12503 (define_split 
12504   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12505         (ne:QI (match_operator 1 "ix86_comparison_operator"
12506                  [(reg FLAGS_REG) (const_int 0)])
12507             (const_int 0)))]
12508   ""
12509   [(set (match_dup 0) (match_dup 1))]
12510 {
12511   PUT_MODE (operands[1], QImode);
12512 })
12513
12514 (define_split 
12515   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12516         (eq:QI (match_operator 1 "ix86_comparison_operator"
12517                  [(reg FLAGS_REG) (const_int 0)])
12518             (const_int 0)))]
12519   ""
12520   [(set (match_dup 0) (match_dup 1))]
12521 {
12522   rtx new_op1 = copy_rtx (operands[1]);
12523   operands[1] = new_op1;
12524   PUT_MODE (new_op1, QImode);
12525   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12526                                              GET_MODE (XEXP (new_op1, 0))));
12527
12528   /* Make sure that (a) the CCmode we have for the flags is strong
12529      enough for the reversed compare or (b) we have a valid FP compare.  */
12530   if (! ix86_comparison_operator (new_op1, VOIDmode))
12531     FAIL;
12532 })
12533
12534 (define_split 
12535   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12536         (eq:QI (match_operator 1 "ix86_comparison_operator"
12537                  [(reg FLAGS_REG) (const_int 0)])
12538             (const_int 0)))]
12539   ""
12540   [(set (match_dup 0) (match_dup 1))]
12541 {
12542   rtx new_op1 = copy_rtx (operands[1]);
12543   operands[1] = new_op1;
12544   PUT_MODE (new_op1, QImode);
12545   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12546                                              GET_MODE (XEXP (new_op1, 0))));
12547
12548   /* Make sure that (a) the CCmode we have for the flags is strong
12549      enough for the reversed compare or (b) we have a valid FP compare.  */
12550   if (! ix86_comparison_operator (new_op1, VOIDmode))
12551     FAIL;
12552 })
12553
12554 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12555 ;; subsequent logical operations are used to imitate conditional moves.
12556 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12557 ;; it directly.  Further holding this value in pseudo register might bring
12558 ;; problem in implicit normalization in spill code.
12559 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12560 ;; instructions after reload by splitting the conditional move patterns.
12561
12562 (define_insn "*sse_setccsf"
12563   [(set (match_operand:SF 0 "register_operand" "=x")
12564         (match_operator:SF 1 "sse_comparison_operator"
12565           [(match_operand:SF 2 "register_operand" "0")
12566            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12567   "TARGET_SSE && reload_completed"
12568   "cmp%D1ss\t{%3, %0|%0, %3}"
12569   [(set_attr "type" "ssecmp")
12570    (set_attr "mode" "SF")])
12571
12572 (define_insn "*sse_setccdf"
12573   [(set (match_operand:DF 0 "register_operand" "=Y")
12574         (match_operator:DF 1 "sse_comparison_operator"
12575           [(match_operand:DF 2 "register_operand" "0")
12576            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12577   "TARGET_SSE2 && reload_completed"
12578   "cmp%D1sd\t{%3, %0|%0, %3}"
12579   [(set_attr "type" "ssecmp")
12580    (set_attr "mode" "DF")])
12581 \f
12582 ;; Basic conditional jump instructions.
12583 ;; We ignore the overflow flag for signed branch instructions.
12584
12585 ;; For all bCOND expanders, also expand the compare or test insn that
12586 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12587
12588 (define_expand "beq"
12589   [(set (pc)
12590         (if_then_else (match_dup 1)
12591                       (label_ref (match_operand 0 "" ""))
12592                       (pc)))]
12593   ""
12594   "ix86_expand_branch (EQ, operands[0]); DONE;")
12595
12596 (define_expand "bne"
12597   [(set (pc)
12598         (if_then_else (match_dup 1)
12599                       (label_ref (match_operand 0 "" ""))
12600                       (pc)))]
12601   ""
12602   "ix86_expand_branch (NE, operands[0]); DONE;")
12603
12604 (define_expand "bgt"
12605   [(set (pc)
12606         (if_then_else (match_dup 1)
12607                       (label_ref (match_operand 0 "" ""))
12608                       (pc)))]
12609   ""
12610   "ix86_expand_branch (GT, operands[0]); DONE;")
12611
12612 (define_expand "bgtu"
12613   [(set (pc)
12614         (if_then_else (match_dup 1)
12615                       (label_ref (match_operand 0 "" ""))
12616                       (pc)))]
12617   ""
12618   "ix86_expand_branch (GTU, operands[0]); DONE;")
12619
12620 (define_expand "blt"
12621   [(set (pc)
12622         (if_then_else (match_dup 1)
12623                       (label_ref (match_operand 0 "" ""))
12624                       (pc)))]
12625   ""
12626   "ix86_expand_branch (LT, operands[0]); DONE;")
12627
12628 (define_expand "bltu"
12629   [(set (pc)
12630         (if_then_else (match_dup 1)
12631                       (label_ref (match_operand 0 "" ""))
12632                       (pc)))]
12633   ""
12634   "ix86_expand_branch (LTU, operands[0]); DONE;")
12635
12636 (define_expand "bge"
12637   [(set (pc)
12638         (if_then_else (match_dup 1)
12639                       (label_ref (match_operand 0 "" ""))
12640                       (pc)))]
12641   ""
12642   "ix86_expand_branch (GE, operands[0]); DONE;")
12643
12644 (define_expand "bgeu"
12645   [(set (pc)
12646         (if_then_else (match_dup 1)
12647                       (label_ref (match_operand 0 "" ""))
12648                       (pc)))]
12649   ""
12650   "ix86_expand_branch (GEU, operands[0]); DONE;")
12651
12652 (define_expand "ble"
12653   [(set (pc)
12654         (if_then_else (match_dup 1)
12655                       (label_ref (match_operand 0 "" ""))
12656                       (pc)))]
12657   ""
12658   "ix86_expand_branch (LE, operands[0]); DONE;")
12659
12660 (define_expand "bleu"
12661   [(set (pc)
12662         (if_then_else (match_dup 1)
12663                       (label_ref (match_operand 0 "" ""))
12664                       (pc)))]
12665   ""
12666   "ix86_expand_branch (LEU, operands[0]); DONE;")
12667
12668 (define_expand "bunordered"
12669   [(set (pc)
12670         (if_then_else (match_dup 1)
12671                       (label_ref (match_operand 0 "" ""))
12672                       (pc)))]
12673   "TARGET_80387 || TARGET_SSE"
12674   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12675
12676 (define_expand "bordered"
12677   [(set (pc)
12678         (if_then_else (match_dup 1)
12679                       (label_ref (match_operand 0 "" ""))
12680                       (pc)))]
12681   "TARGET_80387 || TARGET_SSE"
12682   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12683
12684 (define_expand "buneq"
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 (UNEQ, operands[0]); DONE;")
12691
12692 (define_expand "bunge"
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 (UNGE, operands[0]); DONE;")
12699
12700 (define_expand "bungt"
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 (UNGT, operands[0]); DONE;")
12707
12708 (define_expand "bunle"
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 (UNLE, operands[0]); DONE;")
12715
12716 (define_expand "bunlt"
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 (UNLT, operands[0]); DONE;")
12723
12724 (define_expand "bltgt"
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 (LTGT, operands[0]); DONE;")
12731
12732 (define_insn "*jcc_1"
12733   [(set (pc)
12734         (if_then_else (match_operator 1 "ix86_comparison_operator"
12735                                       [(reg FLAGS_REG) (const_int 0)])
12736                       (label_ref (match_operand 0 "" ""))
12737                       (pc)))]
12738   ""
12739   "%+j%C1\t%l0"
12740   [(set_attr "type" "ibr")
12741    (set_attr "modrm" "0")
12742    (set (attr "length")
12743            (if_then_else (and (ge (minus (match_dup 0) (pc))
12744                                   (const_int -126))
12745                               (lt (minus (match_dup 0) (pc))
12746                                   (const_int 128)))
12747              (const_int 2)
12748              (const_int 6)))])
12749
12750 (define_insn "*jcc_2"
12751   [(set (pc)
12752         (if_then_else (match_operator 1 "ix86_comparison_operator"
12753                                       [(reg FLAGS_REG) (const_int 0)])
12754                       (pc)
12755                       (label_ref (match_operand 0 "" ""))))]
12756   ""
12757   "%+j%c1\t%l0"
12758   [(set_attr "type" "ibr")
12759    (set_attr "modrm" "0")
12760    (set (attr "length")
12761            (if_then_else (and (ge (minus (match_dup 0) (pc))
12762                                   (const_int -126))
12763                               (lt (minus (match_dup 0) (pc))
12764                                   (const_int 128)))
12765              (const_int 2)
12766              (const_int 6)))])
12767
12768 ;; In general it is not safe to assume too much about CCmode registers,
12769 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12770 ;; conditions this is safe on x86, so help combine not create
12771 ;;
12772 ;;      seta    %al
12773 ;;      testb   %al, %al
12774 ;;      je      Lfoo
12775
12776 (define_split 
12777   [(set (pc)
12778         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12779                                       [(reg FLAGS_REG) (const_int 0)])
12780                           (const_int 0))
12781                       (label_ref (match_operand 1 "" ""))
12782                       (pc)))]
12783   ""
12784   [(set (pc)
12785         (if_then_else (match_dup 0)
12786                       (label_ref (match_dup 1))
12787                       (pc)))]
12788 {
12789   PUT_MODE (operands[0], VOIDmode);
12790 })
12791   
12792 (define_split 
12793   [(set (pc)
12794         (if_then_else (eq (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   rtx new_op0 = copy_rtx (operands[0]);
12806   operands[0] = new_op0;
12807   PUT_MODE (new_op0, VOIDmode);
12808   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12809                                              GET_MODE (XEXP (new_op0, 0))));
12810
12811   /* Make sure that (a) the CCmode we have for the flags is strong
12812      enough for the reversed compare or (b) we have a valid FP compare.  */
12813   if (! ix86_comparison_operator (new_op0, VOIDmode))
12814     FAIL;
12815 })
12816
12817 ;; Define combination compare-and-branch fp compare instructions to use
12818 ;; during early optimization.  Splitting the operation apart early makes
12819 ;; for bad code when we want to reverse the operation.
12820
12821 (define_insn "*fp_jcc_1"
12822   [(set (pc)
12823         (if_then_else (match_operator 0 "comparison_operator"
12824                         [(match_operand 1 "register_operand" "f")
12825                          (match_operand 2 "register_operand" "f")])
12826           (label_ref (match_operand 3 "" ""))
12827           (pc)))
12828    (clobber (reg:CCFP FPSR_REG))
12829    (clobber (reg:CCFP FLAGS_REG))]
12830   "TARGET_CMOVE && TARGET_80387
12831    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12832    && FLOAT_MODE_P (GET_MODE (operands[1]))
12833    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12834    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12835   "#")
12836
12837 (define_insn "*fp_jcc_1_sse"
12838   [(set (pc)
12839         (if_then_else (match_operator 0 "comparison_operator"
12840                         [(match_operand 1 "register_operand" "f#x,x#f")
12841                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12842           (label_ref (match_operand 3 "" ""))
12843           (pc)))
12844    (clobber (reg:CCFP FPSR_REG))
12845    (clobber (reg:CCFP FLAGS_REG))]
12846   "TARGET_80387
12847    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12848    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12849    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12850   "#")
12851
12852 (define_insn "*fp_jcc_1_sse_only"
12853   [(set (pc)
12854         (if_then_else (match_operator 0 "comparison_operator"
12855                         [(match_operand 1 "register_operand" "x")
12856                          (match_operand 2 "nonimmediate_operand" "xm")])
12857           (label_ref (match_operand 3 "" ""))
12858           (pc)))
12859    (clobber (reg:CCFP FPSR_REG))
12860    (clobber (reg:CCFP FLAGS_REG))]
12861   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12862    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12863    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12864   "#")
12865
12866 (define_insn "*fp_jcc_2"
12867   [(set (pc)
12868         (if_then_else (match_operator 0 "comparison_operator"
12869                         [(match_operand 1 "register_operand" "f")
12870                          (match_operand 2 "register_operand" "f")])
12871           (pc)
12872           (label_ref (match_operand 3 "" ""))))
12873    (clobber (reg:CCFP FPSR_REG))
12874    (clobber (reg:CCFP FLAGS_REG))]
12875   "TARGET_CMOVE && TARGET_80387
12876    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12877    && 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_sse"
12883   [(set (pc)
12884         (if_then_else (match_operator 0 "comparison_operator"
12885                         [(match_operand 1 "register_operand" "f#x,x#f")
12886                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12887           (pc)
12888           (label_ref (match_operand 3 "" ""))))
12889    (clobber (reg:CCFP FPSR_REG))
12890    (clobber (reg:CCFP FLAGS_REG))]
12891   "TARGET_80387
12892    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12893    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12894    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12895   "#")
12896
12897 (define_insn "*fp_jcc_2_sse_only"
12898   [(set (pc)
12899         (if_then_else (match_operator 0 "comparison_operator"
12900                         [(match_operand 1 "register_operand" "x")
12901                          (match_operand 2 "nonimmediate_operand" "xm")])
12902           (pc)
12903           (label_ref (match_operand 3 "" ""))))
12904    (clobber (reg:CCFP FPSR_REG))
12905    (clobber (reg:CCFP FLAGS_REG))]
12906   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12907    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12908    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12909   "#")
12910
12911 (define_insn "*fp_jcc_3"
12912   [(set (pc)
12913         (if_then_else (match_operator 0 "comparison_operator"
12914                         [(match_operand 1 "register_operand" "f")
12915                          (match_operand 2 "nonimmediate_operand" "fm")])
12916           (label_ref (match_operand 3 "" ""))
12917           (pc)))
12918    (clobber (reg:CCFP FPSR_REG))
12919    (clobber (reg:CCFP FLAGS_REG))
12920    (clobber (match_scratch:HI 4 "=a"))]
12921   "TARGET_80387
12922    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12923    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12924    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12925    && SELECT_CC_MODE (GET_CODE (operands[0]),
12926                       operands[1], operands[2]) == CCFPmode
12927    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12928   "#")
12929
12930 (define_insn "*fp_jcc_4"
12931   [(set (pc)
12932         (if_then_else (match_operator 0 "comparison_operator"
12933                         [(match_operand 1 "register_operand" "f")
12934                          (match_operand 2 "nonimmediate_operand" "fm")])
12935           (pc)
12936           (label_ref (match_operand 3 "" ""))))
12937    (clobber (reg:CCFP FPSR_REG))
12938    (clobber (reg:CCFP FLAGS_REG))
12939    (clobber (match_scratch:HI 4 "=a"))]
12940   "TARGET_80387
12941    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12942    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12943    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12944    && SELECT_CC_MODE (GET_CODE (operands[0]),
12945                       operands[1], operands[2]) == CCFPmode
12946    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12947   "#")
12948
12949 (define_insn "*fp_jcc_5"
12950   [(set (pc)
12951         (if_then_else (match_operator 0 "comparison_operator"
12952                         [(match_operand 1 "register_operand" "f")
12953                          (match_operand 2 "register_operand" "f")])
12954           (label_ref (match_operand 3 "" ""))
12955           (pc)))
12956    (clobber (reg:CCFP FPSR_REG))
12957    (clobber (reg:CCFP FLAGS_REG))
12958    (clobber (match_scratch:HI 4 "=a"))]
12959   "TARGET_80387
12960    && FLOAT_MODE_P (GET_MODE (operands[1]))
12961    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12962    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12963   "#")
12964
12965 (define_insn "*fp_jcc_6"
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           (pc)
12971           (label_ref (match_operand 3 "" ""))))
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_7"
12982   [(set (pc)
12983         (if_then_else (match_operator 0 "comparison_operator"
12984                         [(match_operand 1 "register_operand" "f")
12985                          (match_operand 2 "const_double_operand" "C")])
12986           (label_ref (match_operand 3 "" ""))
12987           (pc)))
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    && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
12994    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12995    && SELECT_CC_MODE (GET_CODE (operands[0]),
12996                       operands[1], operands[2]) == CCFPmode
12997    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12998   "#")
12999
13000 ;; The order of operands in *fp_jcc_8 is forced by combine in
13001 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13002 ;; with a precedence over other operators and is always put in the first
13003 ;; place. Swap condition and operands to match ficom instruction.
13004
13005 (define_insn "*fp_jcc_8"
13006   [(set (pc)
13007         (if_then_else (match_operator 0 "comparison_operator"
13008                         [(match_operator 1 "float_operator"
13009                            [(match_operand:SI 2 "nonimmediate_operand" "m,?r")])
13010                            (match_operand 3 "register_operand" "f,f")])
13011           (label_ref (match_operand 4 "" ""))
13012           (pc)))
13013    (clobber (reg:CCFP FPSR_REG))
13014    (clobber (reg:CCFP FLAGS_REG))
13015    (clobber (match_scratch:HI 5 "=a,a"))]
13016   "TARGET_80387 && TARGET_USE_FIOP
13017    && FLOAT_MODE_P (GET_MODE (operands[3]))
13018    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13019    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13020    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13021    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13022   "#")
13023
13024 (define_split
13025   [(set (pc)
13026         (if_then_else (match_operator 0 "comparison_operator"
13027                         [(match_operand 1 "register_operand" "")
13028                          (match_operand 2 "nonimmediate_operand" "")])
13029           (match_operand 3 "" "")
13030           (match_operand 4 "" "")))
13031    (clobber (reg:CCFP FPSR_REG))
13032    (clobber (reg:CCFP FLAGS_REG))]
13033   "reload_completed"
13034   [(const_int 0)]
13035 {
13036   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13037                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13038   DONE;
13039 })
13040
13041 (define_split
13042   [(set (pc)
13043         (if_then_else (match_operator 0 "comparison_operator"
13044                         [(match_operand 1 "register_operand" "")
13045                          (match_operand 2 "general_operand" "")])
13046           (match_operand 3 "" "")
13047           (match_operand 4 "" "")))
13048    (clobber (reg:CCFP FPSR_REG))
13049    (clobber (reg:CCFP FLAGS_REG))
13050    (clobber (match_scratch:HI 5 "=a"))]
13051   "reload_completed"
13052   [(const_int 0)]
13053 {
13054   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13055                         operands[3], operands[4], operands[5], NULL_RTX);
13056   DONE;
13057 })
13058
13059 (define_split
13060   [(set (pc)
13061         (if_then_else (match_operator 0 "comparison_operator"
13062                         [(match_operator 1 "float_operator"
13063                            [(match_operand:SI 2 "memory_operand" "")])
13064                            (match_operand 3 "register_operand" "")])
13065           (match_operand 4 "" "")
13066           (match_operand 5 "" "")))
13067    (clobber (reg:CCFP FPSR_REG))
13068    (clobber (reg:CCFP FLAGS_REG))
13069    (clobber (match_scratch:HI 6 "=a"))]
13070   "reload_completed"
13071   [(const_int 0)]
13072 {
13073   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13074   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13075                         operands[3], operands[7],
13076                         operands[4], operands[5], operands[6], NULL_RTX);
13077   DONE;
13078 })
13079
13080 ;; %%% Kill this when reload knows how to do it.
13081 (define_split
13082   [(set (pc)
13083         (if_then_else (match_operator 0 "comparison_operator"
13084                         [(match_operator 1 "float_operator"
13085                            [(match_operand:SI 2 "register_operand" "")])
13086                            (match_operand 3 "register_operand" "")])
13087           (match_operand 4 "" "")
13088           (match_operand 5 "" "")))
13089    (clobber (reg:CCFP FPSR_REG))
13090    (clobber (reg:CCFP FLAGS_REG))
13091    (clobber (match_scratch:HI 6 "=a"))]
13092   "reload_completed"
13093   [(const_int 0)]
13094 {
13095   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13096   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13097   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13098                         operands[3], operands[7],
13099                         operands[4], operands[5], operands[6], operands[2]);
13100   DONE;
13101 })
13102 \f
13103 ;; Unconditional and other jump instructions
13104
13105 (define_insn "jump"
13106   [(set (pc)
13107         (label_ref (match_operand 0 "" "")))]
13108   ""
13109   "jmp\t%l0"
13110   [(set_attr "type" "ibr")
13111    (set (attr "length")
13112            (if_then_else (and (ge (minus (match_dup 0) (pc))
13113                                   (const_int -126))
13114                               (lt (minus (match_dup 0) (pc))
13115                                   (const_int 128)))
13116              (const_int 2)
13117              (const_int 5)))
13118    (set_attr "modrm" "0")])
13119
13120 (define_expand "indirect_jump"
13121   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13122   ""
13123   "")
13124
13125 (define_insn "*indirect_jump"
13126   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13127   "!TARGET_64BIT"
13128   "jmp\t%A0"
13129   [(set_attr "type" "ibr")
13130    (set_attr "length_immediate" "0")])
13131
13132 (define_insn "*indirect_jump_rtx64"
13133   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13134   "TARGET_64BIT"
13135   "jmp\t%A0"
13136   [(set_attr "type" "ibr")
13137    (set_attr "length_immediate" "0")])
13138
13139 (define_expand "tablejump"
13140   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13141               (use (label_ref (match_operand 1 "" "")))])]
13142   ""
13143 {
13144   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13145      relative.  Convert the relative address to an absolute address.  */
13146   if (flag_pic)
13147     {
13148       rtx op0, op1;
13149       enum rtx_code code;
13150
13151       if (TARGET_64BIT)
13152         {
13153           code = PLUS;
13154           op0 = operands[0];
13155           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13156         }
13157       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13158         {
13159           code = PLUS;
13160           op0 = operands[0];
13161           op1 = pic_offset_table_rtx;
13162         }
13163       else
13164         {
13165           code = MINUS;
13166           op0 = pic_offset_table_rtx;
13167           op1 = operands[0];
13168         }
13169
13170       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13171                                          OPTAB_DIRECT);
13172     }
13173 })
13174
13175 (define_insn "*tablejump_1"
13176   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13177    (use (label_ref (match_operand 1 "" "")))]
13178   "!TARGET_64BIT"
13179   "jmp\t%A0"
13180   [(set_attr "type" "ibr")
13181    (set_attr "length_immediate" "0")])
13182
13183 (define_insn "*tablejump_1_rtx64"
13184   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13185    (use (label_ref (match_operand 1 "" "")))]
13186   "TARGET_64BIT"
13187   "jmp\t%A0"
13188   [(set_attr "type" "ibr")
13189    (set_attr "length_immediate" "0")])
13190 \f
13191 ;; Loop instruction
13192 ;;
13193 ;; This is all complicated by the fact that since this is a jump insn
13194 ;; we must handle our own reloads.
13195
13196 (define_expand "doloop_end"
13197   [(use (match_operand 0 "" ""))        ; loop pseudo
13198    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13199    (use (match_operand 2 "" ""))        ; max iterations
13200    (use (match_operand 3 "" ""))        ; loop level 
13201    (use (match_operand 4 "" ""))]       ; label
13202   "!TARGET_64BIT && TARGET_USE_LOOP"
13203   "                                 
13204 {
13205   /* Only use cloop on innermost loops.  */
13206   if (INTVAL (operands[3]) > 1)
13207     FAIL;
13208   if (GET_MODE (operands[0]) != SImode)
13209     FAIL;
13210   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13211                                            operands[0]));
13212   DONE;
13213 }")
13214
13215 (define_insn "doloop_end_internal"
13216   [(set (pc)
13217         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13218                           (const_int 1))
13219                       (label_ref (match_operand 0 "" ""))
13220                       (pc)))
13221    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13222         (plus:SI (match_dup 1)
13223                  (const_int -1)))
13224    (clobber (match_scratch:SI 3 "=X,X,r"))
13225    (clobber (reg:CC FLAGS_REG))]
13226   "!TARGET_64BIT && TARGET_USE_LOOP
13227    && (reload_in_progress || reload_completed
13228        || register_operand (operands[2], VOIDmode))"
13229 {
13230   if (which_alternative != 0)
13231     return "#";
13232   if (get_attr_length (insn) == 2)
13233     return "%+loop\t%l0";
13234   else
13235     return "dec{l}\t%1\;%+jne\t%l0";
13236 }
13237   [(set (attr "length")
13238         (if_then_else (and (eq_attr "alternative" "0")
13239                            (and (ge (minus (match_dup 0) (pc))
13240                                     (const_int -126))
13241                                 (lt (minus (match_dup 0) (pc))
13242                                     (const_int 128))))
13243                       (const_int 2)
13244                       (const_int 16)))
13245    ;; We don't know the type before shorten branches.  Optimistically expect
13246    ;; the loop instruction to match.
13247    (set (attr "type") (const_string "ibr"))])
13248
13249 (define_split
13250   [(set (pc)
13251         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13252                           (const_int 1))
13253                       (match_operand 0 "" "")
13254                       (pc)))
13255    (set (match_dup 1)
13256         (plus:SI (match_dup 1)
13257                  (const_int -1)))
13258    (clobber (match_scratch:SI 2 ""))
13259    (clobber (reg:CC FLAGS_REG))]
13260   "!TARGET_64BIT && TARGET_USE_LOOP
13261    && reload_completed
13262    && REGNO (operands[1]) != 2"
13263   [(parallel [(set (reg:CCZ FLAGS_REG)
13264                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13265                                  (const_int 0)))
13266               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13267    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13268                            (match_dup 0)
13269                            (pc)))]
13270   "")
13271   
13272 (define_split
13273   [(set (pc)
13274         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13275                           (const_int 1))
13276                       (match_operand 0 "" "")
13277                       (pc)))
13278    (set (match_operand:SI 2 "nonimmediate_operand" "")
13279         (plus:SI (match_dup 1)
13280                  (const_int -1)))
13281    (clobber (match_scratch:SI 3 ""))
13282    (clobber (reg:CC FLAGS_REG))]
13283   "!TARGET_64BIT && TARGET_USE_LOOP
13284    && reload_completed
13285    && (! REG_P (operands[2])
13286        || ! rtx_equal_p (operands[1], operands[2]))"
13287   [(set (match_dup 3) (match_dup 1))
13288    (parallel [(set (reg:CCZ FLAGS_REG)
13289                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13290                                 (const_int 0)))
13291               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13292    (set (match_dup 2) (match_dup 3))
13293    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13294                            (match_dup 0)
13295                            (pc)))]
13296   "")
13297
13298 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13299
13300 (define_peephole2
13301   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13302    (set (match_operand:QI 1 "register_operand" "")
13303         (match_operator:QI 2 "ix86_comparison_operator"
13304           [(reg FLAGS_REG) (const_int 0)]))
13305    (set (match_operand 3 "q_regs_operand" "")
13306         (zero_extend (match_dup 1)))]
13307   "(peep2_reg_dead_p (3, operands[1])
13308     || operands_match_p (operands[1], operands[3]))
13309    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13310   [(set (match_dup 4) (match_dup 0))
13311    (set (strict_low_part (match_dup 5))
13312         (match_dup 2))]
13313 {
13314   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13315   operands[5] = gen_lowpart (QImode, operands[3]);
13316   ix86_expand_clear (operands[3]);
13317 })
13318
13319 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13320
13321 (define_peephole2
13322   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13323    (set (match_operand:QI 1 "register_operand" "")
13324         (match_operator:QI 2 "ix86_comparison_operator"
13325           [(reg FLAGS_REG) (const_int 0)]))
13326    (parallel [(set (match_operand 3 "q_regs_operand" "")
13327                    (zero_extend (match_dup 1)))
13328               (clobber (reg:CC FLAGS_REG))])]
13329   "(peep2_reg_dead_p (3, operands[1])
13330     || operands_match_p (operands[1], operands[3]))
13331    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13332   [(set (match_dup 4) (match_dup 0))
13333    (set (strict_low_part (match_dup 5))
13334         (match_dup 2))]
13335 {
13336   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13337   operands[5] = gen_lowpart (QImode, operands[3]);
13338   ix86_expand_clear (operands[3]);
13339 })
13340 \f
13341 ;; Call instructions.
13342
13343 ;; The predicates normally associated with named expanders are not properly
13344 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13345 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13346
13347 ;; Call subroutine returning no value.
13348
13349 (define_expand "call_pop"
13350   [(parallel [(call (match_operand:QI 0 "" "")
13351                     (match_operand:SI 1 "" ""))
13352               (set (reg:SI SP_REG)
13353                    (plus:SI (reg:SI SP_REG)
13354                             (match_operand:SI 3 "" "")))])]
13355   "!TARGET_64BIT"
13356 {
13357   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13358   DONE;
13359 })
13360
13361 (define_insn "*call_pop_0"
13362   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13363          (match_operand:SI 1 "" ""))
13364    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13365                             (match_operand:SI 2 "immediate_operand" "")))]
13366   "!TARGET_64BIT"
13367 {
13368   if (SIBLING_CALL_P (insn))
13369     return "jmp\t%P0";
13370   else
13371     return "call\t%P0";
13372 }
13373   [(set_attr "type" "call")])
13374   
13375 (define_insn "*call_pop_1"
13376   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13377          (match_operand:SI 1 "" ""))
13378    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13379                             (match_operand:SI 2 "immediate_operand" "i")))]
13380   "!TARGET_64BIT"
13381 {
13382   if (constant_call_address_operand (operands[0], Pmode))
13383     {
13384       if (SIBLING_CALL_P (insn))
13385         return "jmp\t%P0";
13386       else
13387         return "call\t%P0";
13388     }
13389   if (SIBLING_CALL_P (insn))
13390     return "jmp\t%A0";
13391   else
13392     return "call\t%A0";
13393 }
13394   [(set_attr "type" "call")])
13395
13396 (define_expand "call"
13397   [(call (match_operand:QI 0 "" "")
13398          (match_operand 1 "" ""))
13399    (use (match_operand 2 "" ""))]
13400   ""
13401 {
13402   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13403   DONE;
13404 })
13405
13406 (define_expand "sibcall"
13407   [(call (match_operand:QI 0 "" "")
13408          (match_operand 1 "" ""))
13409    (use (match_operand 2 "" ""))]
13410   ""
13411 {
13412   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13413   DONE;
13414 })
13415
13416 (define_insn "*call_0"
13417   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13418          (match_operand 1 "" ""))]
13419   ""
13420 {
13421   if (SIBLING_CALL_P (insn))
13422     return "jmp\t%P0";
13423   else
13424     return "call\t%P0";
13425 }
13426   [(set_attr "type" "call")])
13427
13428 (define_insn "*call_1"
13429   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13430          (match_operand 1 "" ""))]
13431   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13432 {
13433   if (constant_call_address_operand (operands[0], Pmode))
13434     return "call\t%P0";
13435   return "call\t%A0";
13436 }
13437   [(set_attr "type" "call")])
13438
13439 (define_insn "*sibcall_1"
13440   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13441          (match_operand 1 "" ""))]
13442   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13443 {
13444   if (constant_call_address_operand (operands[0], Pmode))
13445     return "jmp\t%P0";
13446   return "jmp\t%A0";
13447 }
13448   [(set_attr "type" "call")])
13449
13450 (define_insn "*call_1_rex64"
13451   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13452          (match_operand 1 "" ""))]
13453   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13454 {
13455   if (constant_call_address_operand (operands[0], Pmode))
13456     return "call\t%P0";
13457   return "call\t%A0";
13458 }
13459   [(set_attr "type" "call")])
13460
13461 (define_insn "*sibcall_1_rex64"
13462   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13463          (match_operand 1 "" ""))]
13464   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13465   "jmp\t%P0"
13466   [(set_attr "type" "call")])
13467
13468 (define_insn "*sibcall_1_rex64_v"
13469   [(call (mem:QI (reg:DI 40))
13470          (match_operand 0 "" ""))]
13471   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13472   "jmp\t*%%r11"
13473   [(set_attr "type" "call")])
13474
13475
13476 ;; Call subroutine, returning value in operand 0
13477
13478 (define_expand "call_value_pop"
13479   [(parallel [(set (match_operand 0 "" "")
13480                    (call (match_operand:QI 1 "" "")
13481                          (match_operand:SI 2 "" "")))
13482               (set (reg:SI SP_REG)
13483                    (plus:SI (reg:SI SP_REG)
13484                             (match_operand:SI 4 "" "")))])]
13485   "!TARGET_64BIT"
13486 {
13487   ix86_expand_call (operands[0], operands[1], operands[2],
13488                     operands[3], operands[4], 0);
13489   DONE;
13490 })
13491
13492 (define_expand "call_value"
13493   [(set (match_operand 0 "" "")
13494         (call (match_operand:QI 1 "" "")
13495               (match_operand:SI 2 "" "")))
13496    (use (match_operand:SI 3 "" ""))]
13497   ;; Operand 2 not used on the i386.
13498   ""
13499 {
13500   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13501   DONE;
13502 })
13503
13504 (define_expand "sibcall_value"
13505   [(set (match_operand 0 "" "")
13506         (call (match_operand:QI 1 "" "")
13507               (match_operand:SI 2 "" "")))
13508    (use (match_operand:SI 3 "" ""))]
13509   ;; Operand 2 not used on the i386.
13510   ""
13511 {
13512   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13513   DONE;
13514 })
13515
13516 ;; Call subroutine returning any type.
13517
13518 (define_expand "untyped_call"
13519   [(parallel [(call (match_operand 0 "" "")
13520                     (const_int 0))
13521               (match_operand 1 "" "")
13522               (match_operand 2 "" "")])]
13523   ""
13524 {
13525   int i;
13526
13527   /* In order to give reg-stack an easier job in validating two
13528      coprocessor registers as containing a possible return value,
13529      simply pretend the untyped call returns a complex long double
13530      value.  */
13531
13532   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13533                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13534                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13535                     NULL, 0);
13536
13537   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13538     {
13539       rtx set = XVECEXP (operands[2], 0, i);
13540       emit_move_insn (SET_DEST (set), SET_SRC (set));
13541     }
13542
13543   /* The optimizer does not know that the call sets the function value
13544      registers we stored in the result block.  We avoid problems by
13545      claiming that all hard registers are used and clobbered at this
13546      point.  */
13547   emit_insn (gen_blockage (const0_rtx));
13548
13549   DONE;
13550 })
13551 \f
13552 ;; Prologue and epilogue instructions
13553
13554 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13555 ;; all of memory.  This blocks insns from being moved across this point.
13556
13557 (define_insn "blockage"
13558   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13559   ""
13560   ""
13561   [(set_attr "length" "0")])
13562
13563 ;; Insn emitted into the body of a function to return from a function.
13564 ;; This is only done if the function's epilogue is known to be simple.
13565 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13566
13567 (define_expand "return"
13568   [(return)]
13569   "ix86_can_use_return_insn_p ()"
13570 {
13571   if (current_function_pops_args)
13572     {
13573       rtx popc = GEN_INT (current_function_pops_args);
13574       emit_jump_insn (gen_return_pop_internal (popc));
13575       DONE;
13576     }
13577 })
13578
13579 (define_insn "return_internal"
13580   [(return)]
13581   "reload_completed"
13582   "ret"
13583   [(set_attr "length" "1")
13584    (set_attr "length_immediate" "0")
13585    (set_attr "modrm" "0")])
13586
13587 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13588 ;; instruction Athlon and K8 have.
13589
13590 (define_insn "return_internal_long"
13591   [(return)
13592    (unspec [(const_int 0)] UNSPEC_REP)]
13593   "reload_completed"
13594   "rep {;} ret"
13595   [(set_attr "length" "1")
13596    (set_attr "length_immediate" "0")
13597    (set_attr "prefix_rep" "1")
13598    (set_attr "modrm" "0")])
13599
13600 (define_insn "return_pop_internal"
13601   [(return)
13602    (use (match_operand:SI 0 "const_int_operand" ""))]
13603   "reload_completed"
13604   "ret\t%0"
13605   [(set_attr "length" "3")
13606    (set_attr "length_immediate" "2")
13607    (set_attr "modrm" "0")])
13608
13609 (define_insn "return_indirect_internal"
13610   [(return)
13611    (use (match_operand:SI 0 "register_operand" "r"))]
13612   "reload_completed"
13613   "jmp\t%A0"
13614   [(set_attr "type" "ibr")
13615    (set_attr "length_immediate" "0")])
13616
13617 (define_insn "nop"
13618   [(const_int 0)]
13619   ""
13620   "nop"
13621   [(set_attr "length" "1")
13622    (set_attr "length_immediate" "0")
13623    (set_attr "modrm" "0")])
13624
13625 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13626 ;; branch prediction penalty for the third jump in a 16-byte
13627 ;; block on K8.
13628
13629 (define_insn "align"
13630   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13631   ""
13632 {
13633 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13634   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13635 #else
13636   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13637      The align insn is used to avoid 3 jump instructions in the row to improve
13638      branch prediction and the benefits hardly outweight the cost of extra 8
13639      nops on the average inserted by full alignment pseudo operation.  */
13640 #endif
13641   return "";
13642 }
13643   [(set_attr "length" "16")])
13644
13645 (define_expand "prologue"
13646   [(const_int 1)]
13647   ""
13648   "ix86_expand_prologue (); DONE;")
13649
13650 (define_insn "set_got"
13651   [(set (match_operand:SI 0 "register_operand" "=r")
13652         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13653    (clobber (reg:CC FLAGS_REG))]
13654   "!TARGET_64BIT"
13655   { return output_set_got (operands[0]); }
13656   [(set_attr "type" "multi")
13657    (set_attr "length" "12")])
13658
13659 (define_expand "epilogue"
13660   [(const_int 1)]
13661   ""
13662   "ix86_expand_epilogue (1); DONE;")
13663
13664 (define_expand "sibcall_epilogue"
13665   [(const_int 1)]
13666   ""
13667   "ix86_expand_epilogue (0); DONE;")
13668
13669 (define_expand "eh_return"
13670   [(use (match_operand 0 "register_operand" ""))]
13671   ""
13672 {
13673   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13674
13675   /* Tricky bit: we write the address of the handler to which we will
13676      be returning into someone else's stack frame, one word below the
13677      stack address we wish to restore.  */
13678   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13679   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13680   tmp = gen_rtx_MEM (Pmode, tmp);
13681   emit_move_insn (tmp, ra);
13682
13683   if (Pmode == SImode)
13684     emit_jump_insn (gen_eh_return_si (sa));
13685   else
13686     emit_jump_insn (gen_eh_return_di (sa));
13687   emit_barrier ();
13688   DONE;
13689 })
13690
13691 (define_insn_and_split "eh_return_si"
13692   [(set (pc) 
13693         (unspec [(match_operand:SI 0 "register_operand" "c")]
13694                  UNSPEC_EH_RETURN))]
13695   "!TARGET_64BIT"
13696   "#"
13697   "reload_completed"
13698   [(const_int 1)]
13699   "ix86_expand_epilogue (2); DONE;")
13700
13701 (define_insn_and_split "eh_return_di"
13702   [(set (pc) 
13703         (unspec [(match_operand:DI 0 "register_operand" "c")]
13704                  UNSPEC_EH_RETURN))]
13705   "TARGET_64BIT"
13706   "#"
13707   "reload_completed"
13708   [(const_int 1)]
13709   "ix86_expand_epilogue (2); DONE;")
13710
13711 (define_insn "leave"
13712   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13713    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13714    (clobber (mem:BLK (scratch)))]
13715   "!TARGET_64BIT"
13716   "leave"
13717   [(set_attr "type" "leave")])
13718
13719 (define_insn "leave_rex64"
13720   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13721    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13722    (clobber (mem:BLK (scratch)))]
13723   "TARGET_64BIT"
13724   "leave"
13725   [(set_attr "type" "leave")])
13726 \f
13727 (define_expand "ffssi2"
13728   [(parallel
13729      [(set (match_operand:SI 0 "register_operand" "") 
13730            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13731       (clobber (match_scratch:SI 2 ""))
13732       (clobber (reg:CC FLAGS_REG))])]
13733   ""
13734   "")
13735
13736 (define_insn_and_split "*ffs_cmove"
13737   [(set (match_operand:SI 0 "register_operand" "=r") 
13738         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13739    (clobber (match_scratch:SI 2 "=&r"))
13740    (clobber (reg:CC FLAGS_REG))]
13741   "TARGET_CMOVE"
13742   "#"
13743   "&& reload_completed"
13744   [(set (match_dup 2) (const_int -1))
13745    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13746               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13747    (set (match_dup 0) (if_then_else:SI
13748                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13749                         (match_dup 2)
13750                         (match_dup 0)))
13751    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13752               (clobber (reg:CC FLAGS_REG))])]
13753   "")
13754
13755 (define_insn_and_split "*ffs_no_cmove"
13756   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13757         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13758    (clobber (match_scratch:SI 2 "=&q"))
13759    (clobber (reg:CC FLAGS_REG))]
13760   ""
13761   "#"
13762   "reload_completed"
13763   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13764               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13765    (set (strict_low_part (match_dup 3))
13766         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13767    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13768               (clobber (reg:CC FLAGS_REG))])
13769    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13770               (clobber (reg:CC FLAGS_REG))])
13771    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13772               (clobber (reg:CC FLAGS_REG))])]
13773 {
13774   operands[3] = gen_lowpart (QImode, operands[2]);
13775   ix86_expand_clear (operands[2]);
13776 })
13777
13778 (define_insn "*ffssi_1"
13779   [(set (reg:CCZ FLAGS_REG)
13780         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13781                      (const_int 0)))
13782    (set (match_operand:SI 0 "register_operand" "=r")
13783         (ctz:SI (match_dup 1)))]
13784   ""
13785   "bsf{l}\t{%1, %0|%0, %1}"
13786   [(set_attr "prefix_0f" "1")])
13787
13788 (define_expand "ffsdi2"
13789   [(parallel
13790      [(set (match_operand:DI 0 "register_operand" "") 
13791            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13792       (clobber (match_scratch:DI 2 ""))
13793       (clobber (reg:CC FLAGS_REG))])]
13794   "TARGET_64BIT && TARGET_CMOVE"
13795   "")
13796
13797 (define_insn_and_split "*ffs_rex64"
13798   [(set (match_operand:DI 0 "register_operand" "=r") 
13799         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13800    (clobber (match_scratch:DI 2 "=&r"))
13801    (clobber (reg:CC FLAGS_REG))]
13802   "TARGET_64BIT && TARGET_CMOVE"
13803   "#"
13804   "&& reload_completed"
13805   [(set (match_dup 2) (const_int -1))
13806    (parallel [(set (reg:CCZ FLAGS_REG)
13807                    (compare:CCZ (match_dup 1) (const_int 0)))
13808               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13809    (set (match_dup 0) (if_then_else:DI
13810                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13811                         (match_dup 2)
13812                         (match_dup 0)))
13813    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13814               (clobber (reg:CC FLAGS_REG))])]
13815   "")
13816
13817 (define_insn "*ffsdi_1"
13818   [(set (reg:CCZ FLAGS_REG)
13819         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13820                      (const_int 0)))
13821    (set (match_operand:DI 0 "register_operand" "=r")
13822         (ctz:DI (match_dup 1)))]
13823   "TARGET_64BIT"
13824   "bsf{q}\t{%1, %0|%0, %1}"
13825   [(set_attr "prefix_0f" "1")])
13826
13827 (define_insn "ctzsi2"
13828   [(set (match_operand:SI 0 "register_operand" "=r")
13829         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13830    (clobber (reg:CC FLAGS_REG))]
13831   ""
13832   "bsf{l}\t{%1, %0|%0, %1}"
13833   [(set_attr "prefix_0f" "1")])
13834
13835 (define_insn "ctzdi2"
13836   [(set (match_operand:DI 0 "register_operand" "=r")
13837         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13838    (clobber (reg:CC FLAGS_REG))]
13839   "TARGET_64BIT"
13840   "bsf{q}\t{%1, %0|%0, %1}"
13841   [(set_attr "prefix_0f" "1")])
13842
13843 (define_expand "clzsi2"
13844   [(parallel
13845      [(set (match_operand:SI 0 "register_operand" "")
13846            (minus:SI (const_int 31)
13847                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13848       (clobber (reg:CC FLAGS_REG))])
13849    (parallel
13850      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13851       (clobber (reg:CC FLAGS_REG))])]
13852   ""
13853   "")
13854
13855 (define_insn "*bsr"
13856   [(set (match_operand:SI 0 "register_operand" "=r")
13857         (minus:SI (const_int 31)
13858                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13859    (clobber (reg:CC FLAGS_REG))]
13860   ""
13861   "bsr{l}\t{%1, %0|%0, %1}"
13862   [(set_attr "prefix_0f" "1")])
13863
13864 (define_expand "clzdi2"
13865   [(parallel
13866      [(set (match_operand:DI 0 "register_operand" "")
13867            (minus:DI (const_int 63)
13868                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13869       (clobber (reg:CC FLAGS_REG))])
13870    (parallel
13871      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13872       (clobber (reg:CC FLAGS_REG))])]
13873   "TARGET_64BIT"
13874   "")
13875
13876 (define_insn "*bsr_rex64"
13877   [(set (match_operand:DI 0 "register_operand" "=r")
13878         (minus:DI (const_int 63)
13879                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13880    (clobber (reg:CC FLAGS_REG))]
13881   "TARGET_64BIT"
13882   "bsr{q}\t{%1, %0|%0, %1}"
13883   [(set_attr "prefix_0f" "1")])
13884 \f
13885 ;; Thread-local storage patterns for ELF.
13886 ;;
13887 ;; Note that these code sequences must appear exactly as shown
13888 ;; in order to allow linker relaxation.
13889
13890 (define_insn "*tls_global_dynamic_32_gnu"
13891   [(set (match_operand:SI 0 "register_operand" "=a")
13892         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13893                     (match_operand:SI 2 "tls_symbolic_operand" "")
13894                     (match_operand:SI 3 "call_insn_operand" "")]
13895                     UNSPEC_TLS_GD))
13896    (clobber (match_scratch:SI 4 "=d"))
13897    (clobber (match_scratch:SI 5 "=c"))
13898    (clobber (reg:CC FLAGS_REG))]
13899   "!TARGET_64BIT && TARGET_GNU_TLS"
13900   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13901   [(set_attr "type" "multi")
13902    (set_attr "length" "12")])
13903
13904 (define_insn "*tls_global_dynamic_32_sun"
13905   [(set (match_operand:SI 0 "register_operand" "=a")
13906         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13907                     (match_operand:SI 2 "tls_symbolic_operand" "")
13908                     (match_operand:SI 3 "call_insn_operand" "")]
13909                     UNSPEC_TLS_GD))
13910    (clobber (match_scratch:SI 4 "=d"))
13911    (clobber (match_scratch:SI 5 "=c"))
13912    (clobber (reg:CC FLAGS_REG))]
13913   "!TARGET_64BIT && TARGET_SUN_TLS"
13914   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13915         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13916   [(set_attr "type" "multi")
13917    (set_attr "length" "14")])
13918
13919 (define_expand "tls_global_dynamic_32"
13920   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13921                    (unspec:SI
13922                     [(match_dup 2)
13923                      (match_operand:SI 1 "tls_symbolic_operand" "")
13924                      (match_dup 3)]
13925                     UNSPEC_TLS_GD))
13926               (clobber (match_scratch:SI 4 ""))
13927               (clobber (match_scratch:SI 5 ""))
13928               (clobber (reg:CC FLAGS_REG))])]
13929   ""
13930 {
13931   if (flag_pic)
13932     operands[2] = pic_offset_table_rtx;
13933   else
13934     {
13935       operands[2] = gen_reg_rtx (Pmode);
13936       emit_insn (gen_set_got (operands[2]));
13937     }
13938   operands[3] = ix86_tls_get_addr ();
13939 })
13940
13941 (define_insn "*tls_global_dynamic_64"
13942   [(set (match_operand:DI 0 "register_operand" "=a")
13943         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13944                       (match_operand:DI 3 "" "")))
13945    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13946               UNSPEC_TLS_GD)]
13947   "TARGET_64BIT"
13948   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13949   [(set_attr "type" "multi")
13950    (set_attr "length" "16")])
13951
13952 (define_expand "tls_global_dynamic_64"
13953   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13954                    (call (mem:QI (match_dup 2)) (const_int 0)))
13955               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13956                          UNSPEC_TLS_GD)])]
13957   ""
13958 {
13959   operands[2] = ix86_tls_get_addr ();
13960 })
13961
13962 (define_insn "*tls_local_dynamic_base_32_gnu"
13963   [(set (match_operand:SI 0 "register_operand" "=a")
13964         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13965                     (match_operand:SI 2 "call_insn_operand" "")]
13966                    UNSPEC_TLS_LD_BASE))
13967    (clobber (match_scratch:SI 3 "=d"))
13968    (clobber (match_scratch:SI 4 "=c"))
13969    (clobber (reg:CC FLAGS_REG))]
13970   "!TARGET_64BIT && TARGET_GNU_TLS"
13971   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13972   [(set_attr "type" "multi")
13973    (set_attr "length" "11")])
13974
13975 (define_insn "*tls_local_dynamic_base_32_sun"
13976   [(set (match_operand:SI 0 "register_operand" "=a")
13977         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13978                     (match_operand:SI 2 "call_insn_operand" "")]
13979                    UNSPEC_TLS_LD_BASE))
13980    (clobber (match_scratch:SI 3 "=d"))
13981    (clobber (match_scratch:SI 4 "=c"))
13982    (clobber (reg:CC FLAGS_REG))]
13983   "!TARGET_64BIT && TARGET_SUN_TLS"
13984   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13985         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13986   [(set_attr "type" "multi")
13987    (set_attr "length" "13")])
13988
13989 (define_expand "tls_local_dynamic_base_32"
13990   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13991                    (unspec:SI [(match_dup 1) (match_dup 2)]
13992                               UNSPEC_TLS_LD_BASE))
13993               (clobber (match_scratch:SI 3 ""))
13994               (clobber (match_scratch:SI 4 ""))
13995               (clobber (reg:CC FLAGS_REG))])]
13996   ""
13997 {
13998   if (flag_pic)
13999     operands[1] = pic_offset_table_rtx;
14000   else
14001     {
14002       operands[1] = gen_reg_rtx (Pmode);
14003       emit_insn (gen_set_got (operands[1]));
14004     }
14005   operands[2] = ix86_tls_get_addr ();
14006 })
14007
14008 (define_insn "*tls_local_dynamic_base_64"
14009   [(set (match_operand:DI 0 "register_operand" "=a")
14010         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14011                       (match_operand:DI 2 "" "")))
14012    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14013   "TARGET_64BIT"
14014   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14015   [(set_attr "type" "multi")
14016    (set_attr "length" "12")])
14017
14018 (define_expand "tls_local_dynamic_base_64"
14019   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14020                    (call (mem:QI (match_dup 1)) (const_int 0)))
14021               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14022   ""
14023 {
14024   operands[1] = ix86_tls_get_addr ();
14025 })
14026
14027 ;; Local dynamic of a single variable is a lose.  Show combine how
14028 ;; to convert that back to global dynamic.
14029
14030 (define_insn_and_split "*tls_local_dynamic_32_once"
14031   [(set (match_operand:SI 0 "register_operand" "=a")
14032         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14033                              (match_operand:SI 2 "call_insn_operand" "")]
14034                             UNSPEC_TLS_LD_BASE)
14035                  (const:SI (unspec:SI
14036                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14037                             UNSPEC_DTPOFF))))
14038    (clobber (match_scratch:SI 4 "=d"))
14039    (clobber (match_scratch:SI 5 "=c"))
14040    (clobber (reg:CC FLAGS_REG))]
14041   ""
14042   "#"
14043   ""
14044   [(parallel [(set (match_dup 0)
14045                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14046                               UNSPEC_TLS_GD))
14047               (clobber (match_dup 4))
14048               (clobber (match_dup 5))
14049               (clobber (reg:CC FLAGS_REG))])]
14050   "")
14051
14052 ;; Load and add the thread base pointer from %gs:0.
14053
14054 (define_insn "*load_tp_si"
14055   [(set (match_operand:SI 0 "register_operand" "=r")
14056         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14057   "!TARGET_64BIT"
14058   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14059   [(set_attr "type" "imov")
14060    (set_attr "modrm" "0")
14061    (set_attr "length" "7")
14062    (set_attr "memory" "load")
14063    (set_attr "imm_disp" "false")])
14064
14065 (define_insn "*add_tp_si"
14066   [(set (match_operand:SI 0 "register_operand" "=r")
14067         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14068                  (match_operand:SI 1 "register_operand" "0")))
14069    (clobber (reg:CC FLAGS_REG))]
14070   "!TARGET_64BIT"
14071   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14072   [(set_attr "type" "alu")
14073    (set_attr "modrm" "0")
14074    (set_attr "length" "7")
14075    (set_attr "memory" "load")
14076    (set_attr "imm_disp" "false")])
14077
14078 (define_insn "*load_tp_di"
14079   [(set (match_operand:DI 0 "register_operand" "=r")
14080         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14081   "TARGET_64BIT"
14082   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14083   [(set_attr "type" "imov")
14084    (set_attr "modrm" "0")
14085    (set_attr "length" "7")
14086    (set_attr "memory" "load")
14087    (set_attr "imm_disp" "false")])
14088
14089 (define_insn "*add_tp_di"
14090   [(set (match_operand:DI 0 "register_operand" "=r")
14091         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14092                  (match_operand:DI 1 "register_operand" "0")))
14093    (clobber (reg:CC FLAGS_REG))]
14094   "TARGET_64BIT"
14095   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14096   [(set_attr "type" "alu")
14097    (set_attr "modrm" "0")
14098    (set_attr "length" "7")
14099    (set_attr "memory" "load")
14100    (set_attr "imm_disp" "false")])
14101 \f
14102 ;; These patterns match the binary 387 instructions for addM3, subM3,
14103 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14104 ;; SFmode.  The first is the normal insn, the second the same insn but
14105 ;; with one operand a conversion, and the third the same insn but with
14106 ;; the other operand a conversion.  The conversion may be SFmode or
14107 ;; SImode if the target mode DFmode, but only SImode if the target mode
14108 ;; is SFmode.
14109
14110 ;; Gcc is slightly more smart about handling normal two address instructions
14111 ;; so use special patterns for add and mull.
14112
14113 (define_insn "*fop_sf_comm_mixed"
14114   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14115         (match_operator:SF 3 "binary_fp_operator"
14116                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14117                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14118   "TARGET_MIX_SSE_I387
14119    && COMMUTATIVE_ARITH_P (operands[3])
14120    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14121   "* return output_387_binary_op (insn, operands);"
14122   [(set (attr "type") 
14123         (if_then_else (eq_attr "alternative" "1")
14124            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14125               (const_string "ssemul")
14126               (const_string "sseadd"))
14127            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14128               (const_string "fmul")
14129               (const_string "fop"))))
14130    (set_attr "mode" "SF")])
14131
14132 (define_insn "*fop_sf_comm_sse"
14133   [(set (match_operand:SF 0 "register_operand" "=x")
14134         (match_operator:SF 3 "binary_fp_operator"
14135                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14136                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14137   "TARGET_SSE_MATH
14138    && COMMUTATIVE_ARITH_P (operands[3])
14139    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14140   "* return output_387_binary_op (insn, operands);"
14141   [(set (attr "type") 
14142         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14143            (const_string "ssemul")
14144            (const_string "sseadd")))
14145    (set_attr "mode" "SF")])
14146
14147 (define_insn "*fop_sf_comm_i387"
14148   [(set (match_operand:SF 0 "register_operand" "=f")
14149         (match_operator:SF 3 "binary_fp_operator"
14150                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14151                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14152   "TARGET_80387
14153    && COMMUTATIVE_ARITH_P (operands[3])
14154    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14155   "* return output_387_binary_op (insn, operands);"
14156   [(set (attr "type") 
14157         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14158            (const_string "fmul")
14159            (const_string "fop")))
14160    (set_attr "mode" "SF")])
14161
14162 (define_insn "*fop_sf_1_mixed"
14163   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14164         (match_operator:SF 3 "binary_fp_operator"
14165                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14166                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14167   "TARGET_MIX_SSE_I387
14168    && !COMMUTATIVE_ARITH_P (operands[3])
14169    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14170   "* return output_387_binary_op (insn, operands);"
14171   [(set (attr "type") 
14172         (cond [(and (eq_attr "alternative" "2")
14173                     (match_operand:SF 3 "mult_operator" ""))
14174                  (const_string "ssemul")
14175                (and (eq_attr "alternative" "2")
14176                     (match_operand:SF 3 "div_operator" ""))
14177                  (const_string "ssediv")
14178                (eq_attr "alternative" "2")
14179                  (const_string "sseadd")
14180                (match_operand:SF 3 "mult_operator" "") 
14181                  (const_string "fmul")
14182                (match_operand:SF 3 "div_operator" "") 
14183                  (const_string "fdiv")
14184               ]
14185               (const_string "fop")))
14186    (set_attr "mode" "SF")])
14187
14188 (define_insn "*fop_sf_1_sse"
14189   [(set (match_operand:SF 0 "register_operand" "=x")
14190         (match_operator:SF 3 "binary_fp_operator"
14191                         [(match_operand:SF 1 "register_operand" "0")
14192                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14193   "TARGET_SSE_MATH
14194    && !COMMUTATIVE_ARITH_P (operands[3])"
14195   "* return output_387_binary_op (insn, operands);"
14196   [(set (attr "type") 
14197         (cond [(match_operand:SF 3 "mult_operator" "")
14198                  (const_string "ssemul")
14199                (match_operand:SF 3 "div_operator" "")
14200                  (const_string "ssediv")
14201               ]
14202               (const_string "sseadd")))
14203    (set_attr "mode" "SF")])
14204
14205 (define_insn "*fop_sf_1_i387"
14206   [(set (match_operand:SF 0 "register_operand" "=f,f")
14207         (match_operator:SF 3 "binary_fp_operator"
14208                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14209                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14210   "TARGET_80387
14211    && !COMMUTATIVE_ARITH_P (operands[3])
14212    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14213   "* return output_387_binary_op (insn, operands);"
14214   [(set (attr "type") 
14215         (cond [(match_operand:SF 3 "mult_operator" "") 
14216                  (const_string "fmul")
14217                (match_operand:SF 3 "div_operator" "") 
14218                  (const_string "fdiv")
14219               ]
14220               (const_string "fop")))
14221    (set_attr "mode" "SF")])
14222
14223
14224 ;; ??? Add SSE splitters for these!
14225 (define_insn "*fop_sf_2_i387"
14226   [(set (match_operand:SF 0 "register_operand" "=f,f")
14227         (match_operator:SF 3 "binary_fp_operator"
14228           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14229            (match_operand:SF 2 "register_operand" "0,0")]))]
14230   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14231   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14232   [(set (attr "type") 
14233         (cond [(match_operand:SF 3 "mult_operator" "") 
14234                  (const_string "fmul")
14235                (match_operand:SF 3 "div_operator" "") 
14236                  (const_string "fdiv")
14237               ]
14238               (const_string "fop")))
14239    (set_attr "fp_int_src" "true")
14240    (set_attr "mode" "SI")])
14241
14242 (define_insn "*fop_sf_3_i387"
14243   [(set (match_operand:SF 0 "register_operand" "=f,f")
14244         (match_operator:SF 3 "binary_fp_operator"
14245           [(match_operand:SF 1 "register_operand" "0,0")
14246            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14247   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14248   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14249   [(set (attr "type") 
14250         (cond [(match_operand:SF 3 "mult_operator" "") 
14251                  (const_string "fmul")
14252                (match_operand:SF 3 "div_operator" "") 
14253                  (const_string "fdiv")
14254               ]
14255               (const_string "fop")))
14256    (set_attr "fp_int_src" "true")
14257    (set_attr "mode" "SI")])
14258
14259 (define_insn "*fop_df_comm_mixed"
14260   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14261         (match_operator:DF 3 "binary_fp_operator"
14262                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14263                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14264   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14265    && COMMUTATIVE_ARITH_P (operands[3])
14266    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14267   "* return output_387_binary_op (insn, operands);"
14268   [(set (attr "type") 
14269         (if_then_else (eq_attr "alternative" "1")
14270            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14271               (const_string "ssemul")
14272               (const_string "sseadd"))
14273            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14274               (const_string "fmul")
14275               (const_string "fop"))))
14276    (set_attr "mode" "DF")])
14277
14278 (define_insn "*fop_df_comm_sse"
14279   [(set (match_operand:DF 0 "register_operand" "=Y")
14280         (match_operator:DF 3 "binary_fp_operator"
14281                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14282                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14283   "TARGET_SSE2 && TARGET_SSE_MATH
14284    && COMMUTATIVE_ARITH_P (operands[3])
14285    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14286   "* return output_387_binary_op (insn, operands);"
14287   [(set (attr "type") 
14288         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14289            (const_string "ssemul")
14290            (const_string "sseadd")))
14291    (set_attr "mode" "DF")])
14292
14293 (define_insn "*fop_df_comm_i387"
14294   [(set (match_operand:DF 0 "register_operand" "=f")
14295         (match_operator:DF 3 "binary_fp_operator"
14296                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14297                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14298   "TARGET_80387
14299    && COMMUTATIVE_ARITH_P (operands[3])
14300    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14301   "* return output_387_binary_op (insn, operands);"
14302   [(set (attr "type") 
14303         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14304            (const_string "fmul")
14305            (const_string "fop")))
14306    (set_attr "mode" "DF")])
14307
14308 (define_insn "*fop_df_1_mixed"
14309   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14310         (match_operator:DF 3 "binary_fp_operator"
14311                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14312                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14313   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14314    && !COMMUTATIVE_ARITH_P (operands[3])
14315    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14316   "* return output_387_binary_op (insn, operands);"
14317   [(set (attr "type") 
14318         (cond [(and (eq_attr "alternative" "2")
14319                     (match_operand:SF 3 "mult_operator" ""))
14320                  (const_string "ssemul")
14321                (and (eq_attr "alternative" "2")
14322                     (match_operand:SF 3 "div_operator" ""))
14323                  (const_string "ssediv")
14324                (eq_attr "alternative" "2")
14325                  (const_string "sseadd")
14326                (match_operand:DF 3 "mult_operator" "") 
14327                  (const_string "fmul")
14328                (match_operand:DF 3 "div_operator" "") 
14329                  (const_string "fdiv")
14330               ]
14331               (const_string "fop")))
14332    (set_attr "mode" "DF")])
14333
14334 (define_insn "*fop_df_1_sse"
14335   [(set (match_operand:DF 0 "register_operand" "=Y")
14336         (match_operator:DF 3 "binary_fp_operator"
14337                         [(match_operand:DF 1 "register_operand" "0")
14338                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14339   "TARGET_SSE2 && TARGET_SSE_MATH
14340    && !COMMUTATIVE_ARITH_P (operands[3])"
14341   "* return output_387_binary_op (insn, operands);"
14342   [(set_attr "mode" "DF")
14343    (set (attr "type") 
14344         (cond [(match_operand:SF 3 "mult_operator" "")
14345                  (const_string "ssemul")
14346                (match_operand:SF 3 "div_operator" "")
14347                  (const_string "ssediv")
14348               ]
14349               (const_string "sseadd")))])
14350
14351 (define_insn "*fop_df_1_i387"
14352   [(set (match_operand:DF 0 "register_operand" "=f,f")
14353         (match_operator:DF 3 "binary_fp_operator"
14354                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14355                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14356   "TARGET_80387
14357    && !COMMUTATIVE_ARITH_P (operands[3])
14358    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14359   "* return output_387_binary_op (insn, operands);"
14360   [(set (attr "type") 
14361         (cond [(match_operand:DF 3 "mult_operator" "") 
14362                  (const_string "fmul")
14363                (match_operand:DF 3 "div_operator" "")
14364                  (const_string "fdiv")
14365               ]
14366               (const_string "fop")))
14367    (set_attr "mode" "DF")])
14368
14369 ;; ??? Add SSE splitters for these!
14370 (define_insn "*fop_df_2_i387"
14371   [(set (match_operand:DF 0 "register_operand" "=f,f")
14372         (match_operator:DF 3 "binary_fp_operator"
14373            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14374             (match_operand:DF 2 "register_operand" "0,0")]))]
14375   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14376   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14377   [(set (attr "type") 
14378         (cond [(match_operand:DF 3 "mult_operator" "") 
14379                  (const_string "fmul")
14380                (match_operand:DF 3 "div_operator" "") 
14381                  (const_string "fdiv")
14382               ]
14383               (const_string "fop")))
14384    (set_attr "fp_int_src" "true")
14385    (set_attr "mode" "SI")])
14386
14387 (define_insn "*fop_df_3_i387"
14388   [(set (match_operand:DF 0 "register_operand" "=f,f")
14389         (match_operator:DF 3 "binary_fp_operator"
14390            [(match_operand:DF 1 "register_operand" "0,0")
14391             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14392   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14393   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14394   [(set (attr "type") 
14395         (cond [(match_operand:DF 3 "mult_operator" "") 
14396                  (const_string "fmul")
14397                (match_operand:DF 3 "div_operator" "") 
14398                  (const_string "fdiv")
14399               ]
14400               (const_string "fop")))
14401    (set_attr "fp_int_src" "true")
14402    (set_attr "mode" "SI")])
14403
14404 (define_insn "*fop_df_4_i387"
14405   [(set (match_operand:DF 0 "register_operand" "=f,f")
14406         (match_operator:DF 3 "binary_fp_operator"
14407            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14408             (match_operand:DF 2 "register_operand" "0,f")]))]
14409   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14410    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14411   "* return output_387_binary_op (insn, operands);"
14412   [(set (attr "type") 
14413         (cond [(match_operand:DF 3 "mult_operator" "") 
14414                  (const_string "fmul")
14415                (match_operand:DF 3 "div_operator" "") 
14416                  (const_string "fdiv")
14417               ]
14418               (const_string "fop")))
14419    (set_attr "mode" "SF")])
14420
14421 (define_insn "*fop_df_5_i387"
14422   [(set (match_operand:DF 0 "register_operand" "=f,f")
14423         (match_operator:DF 3 "binary_fp_operator"
14424           [(match_operand:DF 1 "register_operand" "0,f")
14425            (float_extend:DF
14426             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14427   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14428   "* return output_387_binary_op (insn, operands);"
14429   [(set (attr "type") 
14430         (cond [(match_operand:DF 3 "mult_operator" "") 
14431                  (const_string "fmul")
14432                (match_operand:DF 3 "div_operator" "") 
14433                  (const_string "fdiv")
14434               ]
14435               (const_string "fop")))
14436    (set_attr "mode" "SF")])
14437
14438 (define_insn "*fop_df_6_i387"
14439   [(set (match_operand:DF 0 "register_operand" "=f,f")
14440         (match_operator:DF 3 "binary_fp_operator"
14441           [(float_extend:DF
14442             (match_operand:SF 1 "register_operand" "0,f"))
14443            (float_extend:DF
14444             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14445   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14446   "* return output_387_binary_op (insn, operands);"
14447   [(set (attr "type") 
14448         (cond [(match_operand:DF 3 "mult_operator" "") 
14449                  (const_string "fmul")
14450                (match_operand:DF 3 "div_operator" "") 
14451                  (const_string "fdiv")
14452               ]
14453               (const_string "fop")))
14454    (set_attr "mode" "SF")])
14455
14456 (define_insn "*fop_xf_comm_i387"
14457   [(set (match_operand:XF 0 "register_operand" "=f")
14458         (match_operator:XF 3 "binary_fp_operator"
14459                         [(match_operand:XF 1 "register_operand" "%0")
14460                          (match_operand:XF 2 "register_operand" "f")]))]
14461   "TARGET_80387
14462    && COMMUTATIVE_ARITH_P (operands[3])"
14463   "* return output_387_binary_op (insn, operands);"
14464   [(set (attr "type") 
14465         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14466            (const_string "fmul")
14467            (const_string "fop")))
14468    (set_attr "mode" "XF")])
14469
14470 (define_insn "*fop_xf_1_i387"
14471   [(set (match_operand:XF 0 "register_operand" "=f,f")
14472         (match_operator:XF 3 "binary_fp_operator"
14473                         [(match_operand:XF 1 "register_operand" "0,f")
14474                          (match_operand:XF 2 "register_operand" "f,0")]))]
14475   "TARGET_80387
14476    && !COMMUTATIVE_ARITH_P (operands[3])"
14477   "* return output_387_binary_op (insn, operands);"
14478   [(set (attr "type") 
14479         (cond [(match_operand:XF 3 "mult_operator" "") 
14480                  (const_string "fmul")
14481                (match_operand:XF 3 "div_operator" "") 
14482                  (const_string "fdiv")
14483               ]
14484               (const_string "fop")))
14485    (set_attr "mode" "XF")])
14486
14487 (define_insn "*fop_xf_2_i387"
14488   [(set (match_operand:XF 0 "register_operand" "=f,f")
14489         (match_operator:XF 3 "binary_fp_operator"
14490            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14491             (match_operand:XF 2 "register_operand" "0,0")]))]
14492   "TARGET_80387 && TARGET_USE_FIOP"
14493   "* return which_alternative ? \"#\" : 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 "fp_int_src" "true")
14502    (set_attr "mode" "SI")])
14503
14504 (define_insn "*fop_xf_3_i387"
14505   [(set (match_operand:XF 0 "register_operand" "=f,f")
14506         (match_operator:XF 3 "binary_fp_operator"
14507           [(match_operand:XF 1 "register_operand" "0,0")
14508            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14509   "TARGET_80387 && TARGET_USE_FIOP"
14510   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14511   [(set (attr "type") 
14512         (cond [(match_operand:XF 3 "mult_operator" "") 
14513                  (const_string "fmul")
14514                (match_operand:XF 3 "div_operator" "") 
14515                  (const_string "fdiv")
14516               ]
14517               (const_string "fop")))
14518    (set_attr "fp_int_src" "true")
14519    (set_attr "mode" "SI")])
14520
14521 (define_insn "*fop_xf_4_i387"
14522   [(set (match_operand:XF 0 "register_operand" "=f,f")
14523         (match_operator:XF 3 "binary_fp_operator"
14524            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14525             (match_operand:XF 2 "register_operand" "0,f")]))]
14526   "TARGET_80387"
14527   "* return output_387_binary_op (insn, operands);"
14528   [(set (attr "type") 
14529         (cond [(match_operand:XF 3 "mult_operator" "") 
14530                  (const_string "fmul")
14531                (match_operand:XF 3 "div_operator" "") 
14532                  (const_string "fdiv")
14533               ]
14534               (const_string "fop")))
14535    (set_attr "mode" "SF")])
14536
14537 (define_insn "*fop_xf_5_i387"
14538   [(set (match_operand:XF 0 "register_operand" "=f,f")
14539         (match_operator:XF 3 "binary_fp_operator"
14540           [(match_operand:XF 1 "register_operand" "0,f")
14541            (float_extend:XF
14542             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14543   "TARGET_80387"
14544   "* return output_387_binary_op (insn, operands);"
14545   [(set (attr "type") 
14546         (cond [(match_operand:XF 3 "mult_operator" "") 
14547                  (const_string "fmul")
14548                (match_operand:XF 3 "div_operator" "") 
14549                  (const_string "fdiv")
14550               ]
14551               (const_string "fop")))
14552    (set_attr "mode" "SF")])
14553
14554 (define_insn "*fop_xf_6_i387"
14555   [(set (match_operand:XF 0 "register_operand" "=f,f")
14556         (match_operator:XF 3 "binary_fp_operator"
14557           [(float_extend:XF
14558             (match_operand 1 "register_operand" "0,f"))
14559            (float_extend:XF
14560             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14561   "TARGET_80387"
14562   "* return output_387_binary_op (insn, operands);"
14563   [(set (attr "type") 
14564         (cond [(match_operand:XF 3 "mult_operator" "") 
14565                  (const_string "fmul")
14566                (match_operand:XF 3 "div_operator" "") 
14567                  (const_string "fdiv")
14568               ]
14569               (const_string "fop")))
14570    (set_attr "mode" "SF")])
14571
14572 (define_split
14573   [(set (match_operand 0 "register_operand" "")
14574         (match_operator 3 "binary_fp_operator"
14575            [(float (match_operand:SI 1 "register_operand" ""))
14576             (match_operand 2 "register_operand" "")]))]
14577   "TARGET_80387 && reload_completed
14578    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14579   [(const_int 0)]
14580
14581   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14582   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14583   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14584                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14585                                           GET_MODE (operands[3]),
14586                                           operands[4],
14587                                           operands[2])));
14588   ix86_free_from_memory (GET_MODE (operands[1]));
14589   DONE;
14590 })
14591
14592 (define_split
14593   [(set (match_operand 0 "register_operand" "")
14594         (match_operator 3 "binary_fp_operator"
14595            [(match_operand 1 "register_operand" "")
14596             (float (match_operand:SI 2 "register_operand" ""))]))]
14597   "TARGET_80387 && reload_completed
14598    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14599   [(const_int 0)]
14600 {
14601   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14602   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14603   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14604                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14605                                           GET_MODE (operands[3]),
14606                                           operands[1],
14607                                           operands[4])));
14608   ix86_free_from_memory (GET_MODE (operands[2]));
14609   DONE;
14610 })
14611 \f
14612 ;; FPU special functions.
14613
14614 (define_expand "sqrtsf2"
14615   [(set (match_operand:SF 0 "register_operand" "")
14616         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14617   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14618 {
14619   if (!TARGET_SSE_MATH)
14620     operands[1] = force_reg (SFmode, operands[1]);
14621 })
14622
14623 (define_insn "*sqrtsf2_mixed"
14624   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14625         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14626   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14627   "@
14628    fsqrt
14629    sqrtss\t{%1, %0|%0, %1}"
14630   [(set_attr "type" "fpspc,sse")
14631    (set_attr "mode" "SF,SF")
14632    (set_attr "athlon_decode" "direct,*")])
14633
14634 (define_insn "*sqrtsf2_sse"
14635   [(set (match_operand:SF 0 "register_operand" "=x")
14636         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14637   "TARGET_SSE_MATH"
14638   "sqrtss\t{%1, %0|%0, %1}"
14639   [(set_attr "type" "sse")
14640    (set_attr "mode" "SF")
14641    (set_attr "athlon_decode" "*")])
14642
14643 (define_insn "*sqrtsf2_i387"
14644   [(set (match_operand:SF 0 "register_operand" "=f")
14645         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14646   "TARGET_USE_FANCY_MATH_387"
14647   "fsqrt"
14648   [(set_attr "type" "fpspc")
14649    (set_attr "mode" "SF")
14650    (set_attr "athlon_decode" "direct")])
14651
14652 (define_expand "sqrtdf2"
14653   [(set (match_operand:DF 0 "register_operand" "")
14654         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14655   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14656 {
14657   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14658     operands[1] = force_reg (DFmode, operands[1]);
14659 })
14660
14661 (define_insn "*sqrtdf2_mixed"
14662   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14663         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14664   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14665   "@
14666    fsqrt
14667    sqrtsd\t{%1, %0|%0, %1}"
14668   [(set_attr "type" "fpspc,sse")
14669    (set_attr "mode" "DF,DF")
14670    (set_attr "athlon_decode" "direct,*")])
14671
14672 (define_insn "*sqrtdf2_sse"
14673   [(set (match_operand:DF 0 "register_operand" "=Y")
14674         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14675   "TARGET_SSE2 && TARGET_SSE_MATH"
14676   "sqrtsd\t{%1, %0|%0, %1}"
14677   [(set_attr "type" "sse")
14678    (set_attr "mode" "DF")
14679    (set_attr "athlon_decode" "*")])
14680
14681 (define_insn "*sqrtdf2_i387"
14682   [(set (match_operand:DF 0 "register_operand" "=f")
14683         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14684   "TARGET_USE_FANCY_MATH_387"
14685   "fsqrt"
14686   [(set_attr "type" "fpspc")
14687    (set_attr "mode" "DF")
14688    (set_attr "athlon_decode" "direct")])
14689
14690 (define_insn "*sqrtextendsfdf2_i387"
14691   [(set (match_operand:DF 0 "register_operand" "=f")
14692         (sqrt:DF (float_extend:DF
14693                   (match_operand:SF 1 "register_operand" "0"))))]
14694   "TARGET_USE_FANCY_MATH_387
14695    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14696   "fsqrt"
14697   [(set_attr "type" "fpspc")
14698    (set_attr "mode" "DF")
14699    (set_attr "athlon_decode" "direct")])
14700
14701 (define_insn "sqrtxf2"
14702   [(set (match_operand:XF 0 "register_operand" "=f")
14703         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14704   "TARGET_USE_FANCY_MATH_387 
14705    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14706   "fsqrt"
14707   [(set_attr "type" "fpspc")
14708    (set_attr "mode" "XF")
14709    (set_attr "athlon_decode" "direct")])
14710
14711 (define_insn "*sqrtextendsfxf2_i387"
14712   [(set (match_operand:XF 0 "register_operand" "=f")
14713         (sqrt:XF (float_extend:XF
14714                   (match_operand:SF 1 "register_operand" "0"))))]
14715   "TARGET_USE_FANCY_MATH_387"
14716   "fsqrt"
14717   [(set_attr "type" "fpspc")
14718    (set_attr "mode" "XF")
14719    (set_attr "athlon_decode" "direct")])
14720
14721 (define_insn "*sqrtextenddfxf2_i387"
14722   [(set (match_operand:XF 0 "register_operand" "=f")
14723         (sqrt:XF (float_extend:XF
14724                   (match_operand:DF 1 "register_operand" "0"))))]
14725   "TARGET_USE_FANCY_MATH_387"
14726   "fsqrt"
14727   [(set_attr "type" "fpspc")
14728    (set_attr "mode" "XF")
14729    (set_attr "athlon_decode" "direct")])
14730
14731 (define_insn "fpremxf4"
14732   [(set (match_operand:XF 0 "register_operand" "=f")
14733         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14734                     (match_operand:XF 3 "register_operand" "1")]
14735                    UNSPEC_FPREM_F))
14736    (set (match_operand:XF 1 "register_operand" "=u")
14737         (unspec:XF [(match_dup 2) (match_dup 3)]
14738                    UNSPEC_FPREM_U))
14739    (set (reg:CCFP FPSR_REG)
14740         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14741   "TARGET_USE_FANCY_MATH_387
14742    && flag_unsafe_math_optimizations"
14743   "fprem"
14744   [(set_attr "type" "fpspc")
14745    (set_attr "mode" "XF")])
14746
14747 (define_expand "fmodsf3"
14748   [(use (match_operand:SF 0 "register_operand" ""))
14749    (use (match_operand:SF 1 "register_operand" ""))
14750    (use (match_operand:SF 2 "register_operand" ""))]
14751   "TARGET_USE_FANCY_MATH_387
14752    && flag_unsafe_math_optimizations"
14753 {
14754   rtx label = gen_label_rtx ();
14755
14756   rtx op1 = gen_reg_rtx (XFmode);
14757   rtx op2 = gen_reg_rtx (XFmode);
14758
14759   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14760   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14761
14762   emit_label (label);
14763
14764   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14765   ix86_emit_fp_unordered_jump (label);
14766
14767   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14768   DONE;
14769 })
14770
14771 (define_expand "fmoddf3"
14772   [(use (match_operand:DF 0 "register_operand" ""))
14773    (use (match_operand:DF 1 "register_operand" ""))
14774    (use (match_operand:DF 2 "register_operand" ""))]
14775   "TARGET_USE_FANCY_MATH_387
14776    && flag_unsafe_math_optimizations"
14777 {
14778   rtx label = gen_label_rtx ();
14779
14780   rtx op1 = gen_reg_rtx (XFmode);
14781   rtx op2 = gen_reg_rtx (XFmode);
14782
14783   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14784   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14785
14786   emit_label (label);
14787
14788   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14789   ix86_emit_fp_unordered_jump (label);
14790
14791   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14792   DONE;
14793 })
14794
14795 (define_expand "fmodxf3"
14796   [(use (match_operand:XF 0 "register_operand" ""))
14797    (use (match_operand:XF 1 "register_operand" ""))
14798    (use (match_operand:XF 2 "register_operand" ""))]
14799   "TARGET_USE_FANCY_MATH_387
14800    && flag_unsafe_math_optimizations"
14801 {
14802   rtx label = gen_label_rtx ();
14803
14804   emit_label (label);
14805
14806   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14807                            operands[1], operands[2]));
14808   ix86_emit_fp_unordered_jump (label);
14809
14810   emit_move_insn (operands[0], operands[1]);
14811   DONE;
14812 })
14813
14814 (define_insn "fprem1xf4"
14815   [(set (match_operand:XF 0 "register_operand" "=f")
14816         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14817                     (match_operand:XF 3 "register_operand" "1")]
14818                    UNSPEC_FPREM1_F))
14819    (set (match_operand:XF 1 "register_operand" "=u")
14820         (unspec:XF [(match_dup 2) (match_dup 3)]
14821                    UNSPEC_FPREM1_U))
14822    (set (reg:CCFP FPSR_REG)
14823         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14824   "TARGET_USE_FANCY_MATH_387
14825    && flag_unsafe_math_optimizations"
14826   "fprem1"
14827   [(set_attr "type" "fpspc")
14828    (set_attr "mode" "XF")])
14829
14830 (define_expand "dremsf3"
14831   [(use (match_operand:SF 0 "register_operand" ""))
14832    (use (match_operand:SF 1 "register_operand" ""))
14833    (use (match_operand:SF 2 "register_operand" ""))]
14834   "TARGET_USE_FANCY_MATH_387
14835    && flag_unsafe_math_optimizations"
14836 {
14837   rtx label = gen_label_rtx ();
14838
14839   rtx op1 = gen_reg_rtx (XFmode);
14840   rtx op2 = gen_reg_rtx (XFmode);
14841
14842   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14843   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14844
14845   emit_label (label);
14846
14847   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14848   ix86_emit_fp_unordered_jump (label);
14849
14850   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14851   DONE;
14852 })
14853
14854 (define_expand "dremdf3"
14855   [(use (match_operand:DF 0 "register_operand" ""))
14856    (use (match_operand:DF 1 "register_operand" ""))
14857    (use (match_operand:DF 2 "register_operand" ""))]
14858   "TARGET_USE_FANCY_MATH_387
14859    && flag_unsafe_math_optimizations"
14860 {
14861   rtx label = gen_label_rtx ();
14862
14863   rtx op1 = gen_reg_rtx (XFmode);
14864   rtx op2 = gen_reg_rtx (XFmode);
14865
14866   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14867   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14868
14869   emit_label (label);
14870
14871   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14872   ix86_emit_fp_unordered_jump (label);
14873
14874   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14875   DONE;
14876 })
14877
14878 (define_expand "dremxf3"
14879   [(use (match_operand:XF 0 "register_operand" ""))
14880    (use (match_operand:XF 1 "register_operand" ""))
14881    (use (match_operand:XF 2 "register_operand" ""))]
14882   "TARGET_USE_FANCY_MATH_387
14883    && flag_unsafe_math_optimizations"
14884 {
14885   rtx label = gen_label_rtx ();
14886
14887   emit_label (label);
14888
14889   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14890                             operands[1], operands[2]));
14891   ix86_emit_fp_unordered_jump (label);
14892
14893   emit_move_insn (operands[0], operands[1]);
14894   DONE;
14895 })
14896
14897 (define_insn "*sindf2"
14898   [(set (match_operand:DF 0 "register_operand" "=f")
14899         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14900   "TARGET_USE_FANCY_MATH_387
14901    && flag_unsafe_math_optimizations"
14902   "fsin"
14903   [(set_attr "type" "fpspc")
14904    (set_attr "mode" "DF")])
14905
14906 (define_insn "*sinsf2"
14907   [(set (match_operand:SF 0 "register_operand" "=f")
14908         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14909   "TARGET_USE_FANCY_MATH_387
14910    && flag_unsafe_math_optimizations"
14911   "fsin"
14912   [(set_attr "type" "fpspc")
14913    (set_attr "mode" "SF")])
14914
14915 (define_insn "*sinextendsfdf2"
14916   [(set (match_operand:DF 0 "register_operand" "=f")
14917         (unspec:DF [(float_extend:DF
14918                      (match_operand:SF 1 "register_operand" "0"))]
14919                    UNSPEC_SIN))]
14920   "TARGET_USE_FANCY_MATH_387
14921    && flag_unsafe_math_optimizations"
14922   "fsin"
14923   [(set_attr "type" "fpspc")
14924    (set_attr "mode" "DF")])
14925
14926 (define_insn "*sinxf2"
14927   [(set (match_operand:XF 0 "register_operand" "=f")
14928         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14929   "TARGET_USE_FANCY_MATH_387
14930    && flag_unsafe_math_optimizations"
14931   "fsin"
14932   [(set_attr "type" "fpspc")
14933    (set_attr "mode" "XF")])
14934
14935 (define_insn "*cosdf2"
14936   [(set (match_operand:DF 0 "register_operand" "=f")
14937         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14938   "TARGET_USE_FANCY_MATH_387
14939    && flag_unsafe_math_optimizations"
14940   "fcos"
14941   [(set_attr "type" "fpspc")
14942    (set_attr "mode" "DF")])
14943
14944 (define_insn "*cossf2"
14945   [(set (match_operand:SF 0 "register_operand" "=f")
14946         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14947   "TARGET_USE_FANCY_MATH_387
14948    && flag_unsafe_math_optimizations"
14949   "fcos"
14950   [(set_attr "type" "fpspc")
14951    (set_attr "mode" "SF")])
14952
14953 (define_insn "*cosextendsfdf2"
14954   [(set (match_operand:DF 0 "register_operand" "=f")
14955         (unspec:DF [(float_extend:DF
14956                      (match_operand:SF 1 "register_operand" "0"))]
14957                    UNSPEC_COS))]
14958   "TARGET_USE_FANCY_MATH_387
14959    && flag_unsafe_math_optimizations"
14960   "fcos"
14961   [(set_attr "type" "fpspc")
14962    (set_attr "mode" "DF")])
14963
14964 (define_insn "*cosxf2"
14965   [(set (match_operand:XF 0 "register_operand" "=f")
14966         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14967   "TARGET_USE_FANCY_MATH_387
14968    && flag_unsafe_math_optimizations"
14969   "fcos"
14970   [(set_attr "type" "fpspc")
14971    (set_attr "mode" "XF")])
14972
14973 ;; With sincos pattern defined, sin and cos builtin function will be
14974 ;; expanded to sincos pattern with one of its outputs left unused. 
14975 ;; Cse pass  will detected, if two sincos patterns can be combined,
14976 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14977 ;; depending on the unused output.
14978
14979 (define_insn "sincosdf3"
14980   [(set (match_operand:DF 0 "register_operand" "=f")
14981         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14982                    UNSPEC_SINCOS_COS))
14983    (set (match_operand:DF 1 "register_operand" "=u")
14984         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14985   "TARGET_USE_FANCY_MATH_387
14986    && flag_unsafe_math_optimizations"
14987   "fsincos"
14988   [(set_attr "type" "fpspc")
14989    (set_attr "mode" "DF")])
14990
14991 (define_split
14992   [(set (match_operand:DF 0 "register_operand" "")
14993         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14994                    UNSPEC_SINCOS_COS))
14995    (set (match_operand:DF 1 "register_operand" "")
14996         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14997   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14998    && !reload_completed && !reload_in_progress"
14999   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15000   "")
15001
15002 (define_split
15003   [(set (match_operand:DF 0 "register_operand" "")
15004         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15005                    UNSPEC_SINCOS_COS))
15006    (set (match_operand:DF 1 "register_operand" "")
15007         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15008   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15009    && !reload_completed && !reload_in_progress"
15010   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15011   "")
15012
15013 (define_insn "sincossf3"
15014   [(set (match_operand:SF 0 "register_operand" "=f")
15015         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15016                    UNSPEC_SINCOS_COS))
15017    (set (match_operand:SF 1 "register_operand" "=u")
15018         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15019   "TARGET_USE_FANCY_MATH_387
15020    && flag_unsafe_math_optimizations"
15021   "fsincos"
15022   [(set_attr "type" "fpspc")
15023    (set_attr "mode" "SF")])
15024
15025 (define_split
15026   [(set (match_operand:SF 0 "register_operand" "")
15027         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15028                    UNSPEC_SINCOS_COS))
15029    (set (match_operand:SF 1 "register_operand" "")
15030         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15031   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15032    && !reload_completed && !reload_in_progress"
15033   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15034   "")
15035
15036 (define_split
15037   [(set (match_operand:SF 0 "register_operand" "")
15038         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15039                    UNSPEC_SINCOS_COS))
15040    (set (match_operand:SF 1 "register_operand" "")
15041         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15042   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15043    && !reload_completed && !reload_in_progress"
15044   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15045   "")
15046
15047 (define_insn "*sincosextendsfdf3"
15048   [(set (match_operand:DF 0 "register_operand" "=f")
15049         (unspec:DF [(float_extend:DF
15050                      (match_operand:SF 2 "register_operand" "0"))]
15051                    UNSPEC_SINCOS_COS))
15052    (set (match_operand:DF 1 "register_operand" "=u")
15053         (unspec:DF [(float_extend:DF
15054                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15055   "TARGET_USE_FANCY_MATH_387
15056    && flag_unsafe_math_optimizations"
15057   "fsincos"
15058   [(set_attr "type" "fpspc")
15059    (set_attr "mode" "DF")])
15060
15061 (define_split
15062   [(set (match_operand:DF 0 "register_operand" "")
15063         (unspec:DF [(float_extend:DF
15064                      (match_operand:SF 2 "register_operand" ""))]
15065                    UNSPEC_SINCOS_COS))
15066    (set (match_operand:DF 1 "register_operand" "")
15067         (unspec:DF [(float_extend:DF
15068                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15069   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15070    && !reload_completed && !reload_in_progress"
15071   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15072                                    (match_dup 2))] UNSPEC_SIN))]
15073   "")
15074
15075 (define_split
15076   [(set (match_operand:DF 0 "register_operand" "")
15077         (unspec:DF [(float_extend:DF
15078                      (match_operand:SF 2 "register_operand" ""))]
15079                    UNSPEC_SINCOS_COS))
15080    (set (match_operand:DF 1 "register_operand" "")
15081         (unspec:DF [(float_extend:DF
15082                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15083   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15084    && !reload_completed && !reload_in_progress"
15085   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15086                                    (match_dup 2))] UNSPEC_COS))]
15087   "")
15088
15089 (define_insn "sincosxf3"
15090   [(set (match_operand:XF 0 "register_operand" "=f")
15091         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15092                    UNSPEC_SINCOS_COS))
15093    (set (match_operand:XF 1 "register_operand" "=u")
15094         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15095   "TARGET_USE_FANCY_MATH_387
15096    && flag_unsafe_math_optimizations"
15097   "fsincos"
15098   [(set_attr "type" "fpspc")
15099    (set_attr "mode" "XF")])
15100
15101 (define_split
15102   [(set (match_operand:XF 0 "register_operand" "")
15103         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15104                    UNSPEC_SINCOS_COS))
15105    (set (match_operand:XF 1 "register_operand" "")
15106         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15107   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15108    && !reload_completed && !reload_in_progress"
15109   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15110   "")
15111
15112 (define_split
15113   [(set (match_operand:XF 0 "register_operand" "")
15114         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15115                    UNSPEC_SINCOS_COS))
15116    (set (match_operand:XF 1 "register_operand" "")
15117         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15118   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15119    && !reload_completed && !reload_in_progress"
15120   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15121   "")
15122
15123 (define_insn "*tandf3_1"
15124   [(set (match_operand:DF 0 "register_operand" "=f")
15125         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15126                    UNSPEC_TAN_ONE))
15127    (set (match_operand:DF 1 "register_operand" "=u")
15128         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15129   "TARGET_USE_FANCY_MATH_387
15130    && flag_unsafe_math_optimizations"
15131   "fptan"
15132   [(set_attr "type" "fpspc")
15133    (set_attr "mode" "DF")])
15134
15135 ;; optimize sequence: fptan
15136 ;;                    fstp    %st(0)
15137 ;;                    fld1
15138 ;; into fptan insn.
15139
15140 (define_peephole2
15141   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15142                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15143                              UNSPEC_TAN_ONE))
15144              (set (match_operand:DF 1 "register_operand" "")
15145                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15146    (set (match_dup 0)
15147         (match_operand:DF 3 "immediate_operand" ""))]
15148   "standard_80387_constant_p (operands[3]) == 2"
15149   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15150              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15151   "")
15152
15153 (define_expand "tandf2"
15154   [(parallel [(set (match_dup 2)
15155                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15156                               UNSPEC_TAN_ONE))
15157               (set (match_operand:DF 0 "register_operand" "")
15158                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15159   "TARGET_USE_FANCY_MATH_387
15160    && flag_unsafe_math_optimizations"
15161 {
15162   operands[2] = gen_reg_rtx (DFmode);
15163 })
15164
15165 (define_insn "*tansf3_1"
15166   [(set (match_operand:SF 0 "register_operand" "=f")
15167         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15168                    UNSPEC_TAN_ONE))
15169    (set (match_operand:SF 1 "register_operand" "=u")
15170         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15171   "TARGET_USE_FANCY_MATH_387
15172    && flag_unsafe_math_optimizations"
15173   "fptan"
15174   [(set_attr "type" "fpspc")
15175    (set_attr "mode" "SF")])
15176
15177 ;; optimize sequence: fptan
15178 ;;                    fstp    %st(0)
15179 ;;                    fld1
15180 ;; into fptan insn.
15181
15182 (define_peephole2
15183   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15184                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15185                              UNSPEC_TAN_ONE))
15186              (set (match_operand:SF 1 "register_operand" "")
15187                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15188    (set (match_dup 0)
15189         (match_operand:SF 3 "immediate_operand" ""))]
15190   "standard_80387_constant_p (operands[3]) == 2"
15191   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15192              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15193   "")
15194
15195 (define_expand "tansf2"
15196   [(parallel [(set (match_dup 2)
15197                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15198                               UNSPEC_TAN_ONE))
15199               (set (match_operand:SF 0 "register_operand" "")
15200                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15201   "TARGET_USE_FANCY_MATH_387
15202    && flag_unsafe_math_optimizations"
15203 {
15204   operands[2] = gen_reg_rtx (SFmode);
15205 })
15206
15207 (define_insn "*tanxf3_1"
15208   [(set (match_operand:XF 0 "register_operand" "=f")
15209         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15210                    UNSPEC_TAN_ONE))
15211    (set (match_operand:XF 1 "register_operand" "=u")
15212         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15213   "TARGET_USE_FANCY_MATH_387
15214    && flag_unsafe_math_optimizations"
15215   "fptan"
15216   [(set_attr "type" "fpspc")
15217    (set_attr "mode" "XF")])
15218
15219 ;; optimize sequence: fptan
15220 ;;                    fstp    %st(0)
15221 ;;                    fld1
15222 ;; into fptan insn.
15223
15224 (define_peephole2
15225   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15226                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15227                              UNSPEC_TAN_ONE))
15228              (set (match_operand:XF 1 "register_operand" "")
15229                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15230    (set (match_dup 0)
15231         (match_operand:XF 3 "immediate_operand" ""))]
15232   "standard_80387_constant_p (operands[3]) == 2"
15233   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15234              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15235   "")
15236
15237 (define_expand "tanxf2"
15238   [(parallel [(set (match_dup 2)
15239                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15240                               UNSPEC_TAN_ONE))
15241               (set (match_operand:XF 0 "register_operand" "")
15242                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15243   "TARGET_USE_FANCY_MATH_387
15244    && flag_unsafe_math_optimizations"
15245 {
15246   operands[2] = gen_reg_rtx (XFmode);
15247 })
15248
15249 (define_insn "atan2df3_1"
15250   [(set (match_operand:DF 0 "register_operand" "=f")
15251         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15252                     (match_operand:DF 1 "register_operand" "u")]
15253                    UNSPEC_FPATAN))
15254    (clobber (match_scratch:DF 3 "=1"))]
15255   "TARGET_USE_FANCY_MATH_387
15256    && flag_unsafe_math_optimizations"
15257   "fpatan"
15258   [(set_attr "type" "fpspc")
15259    (set_attr "mode" "DF")])
15260
15261 (define_expand "atan2df3"
15262   [(use (match_operand:DF 0 "register_operand" "=f"))
15263    (use (match_operand:DF 2 "register_operand" "0"))
15264    (use (match_operand:DF 1 "register_operand" "u"))]
15265   "TARGET_USE_FANCY_MATH_387
15266    && flag_unsafe_math_optimizations"
15267 {
15268   rtx copy = gen_reg_rtx (DFmode);
15269   emit_move_insn (copy, operands[1]);
15270   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15271   DONE;
15272 })
15273
15274 (define_expand "atandf2"
15275   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15276                    (unspec:DF [(match_dup 2)
15277                                (match_operand:DF 1 "register_operand" "")]
15278                     UNSPEC_FPATAN))
15279               (clobber (match_scratch:DF 3 ""))])]
15280   "TARGET_USE_FANCY_MATH_387
15281    && flag_unsafe_math_optimizations"
15282 {
15283   operands[2] = gen_reg_rtx (DFmode);
15284   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15285 })
15286
15287 (define_insn "atan2sf3_1"
15288   [(set (match_operand:SF 0 "register_operand" "=f")
15289         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15290                     (match_operand:SF 1 "register_operand" "u")]
15291                    UNSPEC_FPATAN))
15292    (clobber (match_scratch:SF 3 "=1"))]
15293   "TARGET_USE_FANCY_MATH_387
15294    && flag_unsafe_math_optimizations"
15295   "fpatan"
15296   [(set_attr "type" "fpspc")
15297    (set_attr "mode" "SF")])
15298
15299 (define_expand "atan2sf3"
15300   [(use (match_operand:SF 0 "register_operand" "=f"))
15301    (use (match_operand:SF 2 "register_operand" "0"))
15302    (use (match_operand:SF 1 "register_operand" "u"))]
15303   "TARGET_USE_FANCY_MATH_387
15304    && flag_unsafe_math_optimizations"
15305 {
15306   rtx copy = gen_reg_rtx (SFmode);
15307   emit_move_insn (copy, operands[1]);
15308   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15309   DONE;
15310 })
15311
15312 (define_expand "atansf2"
15313   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15314                    (unspec:SF [(match_dup 2)
15315                                (match_operand:SF 1 "register_operand" "")]
15316                     UNSPEC_FPATAN))
15317               (clobber (match_scratch:SF 3 ""))])]
15318   "TARGET_USE_FANCY_MATH_387
15319    && flag_unsafe_math_optimizations"
15320 {
15321   operands[2] = gen_reg_rtx (SFmode);
15322   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15323 })
15324
15325 (define_insn "atan2xf3_1"
15326   [(set (match_operand:XF 0 "register_operand" "=f")
15327         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15328                     (match_operand:XF 1 "register_operand" "u")]
15329                    UNSPEC_FPATAN))
15330    (clobber (match_scratch:XF 3 "=1"))]
15331   "TARGET_USE_FANCY_MATH_387
15332    && flag_unsafe_math_optimizations"
15333   "fpatan"
15334   [(set_attr "type" "fpspc")
15335    (set_attr "mode" "XF")])
15336
15337 (define_expand "atan2xf3"
15338   [(use (match_operand:XF 0 "register_operand" "=f"))
15339    (use (match_operand:XF 2 "register_operand" "0"))
15340    (use (match_operand:XF 1 "register_operand" "u"))]
15341   "TARGET_USE_FANCY_MATH_387
15342    && flag_unsafe_math_optimizations"
15343 {
15344   rtx copy = gen_reg_rtx (XFmode);
15345   emit_move_insn (copy, operands[1]);
15346   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15347   DONE;
15348 })
15349
15350 (define_expand "atanxf2"
15351   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15352                    (unspec:XF [(match_dup 2)
15353                                (match_operand:XF 1 "register_operand" "")]
15354                     UNSPEC_FPATAN))
15355               (clobber (match_scratch:XF 3 ""))])]
15356   "TARGET_USE_FANCY_MATH_387
15357    && flag_unsafe_math_optimizations"
15358 {
15359   operands[2] = gen_reg_rtx (XFmode);
15360   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15361 })
15362
15363 (define_expand "asindf2"
15364   [(set (match_dup 2)
15365         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15366    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15367    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15368    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15369    (parallel [(set (match_dup 7)
15370                    (unspec:XF [(match_dup 6) (match_dup 2)]
15371                               UNSPEC_FPATAN))
15372               (clobber (match_scratch:XF 8 ""))])
15373    (set (match_operand:DF 0 "register_operand" "")
15374         (float_truncate:DF (match_dup 7)))]
15375   "TARGET_USE_FANCY_MATH_387
15376    && flag_unsafe_math_optimizations"
15377 {
15378   int i;
15379
15380   for (i=2; i<8; i++)
15381     operands[i] = gen_reg_rtx (XFmode);
15382
15383   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15384 })
15385
15386 (define_expand "asinsf2"
15387   [(set (match_dup 2)
15388         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15389    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15390    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15391    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15392    (parallel [(set (match_dup 7)
15393                    (unspec:XF [(match_dup 6) (match_dup 2)]
15394                               UNSPEC_FPATAN))
15395               (clobber (match_scratch:XF 8 ""))])
15396    (set (match_operand:SF 0 "register_operand" "")
15397         (float_truncate:SF (match_dup 7)))]
15398   "TARGET_USE_FANCY_MATH_387
15399    && flag_unsafe_math_optimizations"
15400 {
15401   int i;
15402
15403   for (i=2; i<8; i++)
15404     operands[i] = gen_reg_rtx (XFmode);
15405
15406   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15407 })
15408
15409 (define_expand "asinxf2"
15410   [(set (match_dup 2)
15411         (mult:XF (match_operand:XF 1 "register_operand" "")
15412                  (match_dup 1)))
15413    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15414    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15415    (parallel [(set (match_operand:XF 0 "register_operand" "")
15416                    (unspec:XF [(match_dup 5) (match_dup 1)]
15417                               UNSPEC_FPATAN))
15418               (clobber (match_scratch:XF 6 ""))])]
15419   "TARGET_USE_FANCY_MATH_387
15420    && flag_unsafe_math_optimizations"
15421 {
15422   int i;
15423
15424   for (i=2; i<6; i++)
15425     operands[i] = gen_reg_rtx (XFmode);
15426
15427   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15428 })
15429
15430 (define_expand "acosdf2"
15431   [(set (match_dup 2)
15432         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15433    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15434    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15435    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15436    (parallel [(set (match_dup 7)
15437                    (unspec:XF [(match_dup 2) (match_dup 6)]
15438                               UNSPEC_FPATAN))
15439               (clobber (match_scratch:XF 8 ""))])
15440    (set (match_operand:DF 0 "register_operand" "")
15441         (float_truncate:DF (match_dup 7)))]
15442   "TARGET_USE_FANCY_MATH_387
15443    && flag_unsafe_math_optimizations"
15444 {
15445   int i;
15446
15447   for (i=2; i<8; i++)
15448     operands[i] = gen_reg_rtx (XFmode);
15449
15450   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15451 })
15452
15453 (define_expand "acossf2"
15454   [(set (match_dup 2)
15455         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15456    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15457    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15458    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15459    (parallel [(set (match_dup 7)
15460                    (unspec:XF [(match_dup 2) (match_dup 6)]
15461                               UNSPEC_FPATAN))
15462               (clobber (match_scratch:XF 8 ""))])
15463    (set (match_operand:SF 0 "register_operand" "")
15464         (float_truncate:SF (match_dup 7)))]
15465   "TARGET_USE_FANCY_MATH_387
15466    && flag_unsafe_math_optimizations"
15467 {
15468   int i;
15469
15470   for (i=2; i<8; i++)
15471     operands[i] = gen_reg_rtx (XFmode);
15472
15473   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15474 })
15475
15476 (define_expand "acosxf2"
15477   [(set (match_dup 2)
15478         (mult:XF (match_operand:XF 1 "register_operand" "")
15479                  (match_dup 1)))
15480    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15481    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15482    (parallel [(set (match_operand:XF 0 "register_operand" "")
15483                    (unspec:XF [(match_dup 1) (match_dup 5)]
15484                               UNSPEC_FPATAN))
15485               (clobber (match_scratch:XF 6 ""))])]
15486   "TARGET_USE_FANCY_MATH_387
15487    && flag_unsafe_math_optimizations"
15488 {
15489   int i;
15490
15491   for (i=2; i<6; i++)
15492     operands[i] = gen_reg_rtx (XFmode);
15493
15494   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15495 })
15496
15497 (define_insn "fyl2x_xf3"
15498   [(set (match_operand:XF 0 "register_operand" "=f")
15499         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15500                     (match_operand:XF 1 "register_operand" "u")]
15501                    UNSPEC_FYL2X))
15502    (clobber (match_scratch:XF 3 "=1"))]
15503   "TARGET_USE_FANCY_MATH_387
15504    && flag_unsafe_math_optimizations"
15505   "fyl2x"
15506   [(set_attr "type" "fpspc")
15507    (set_attr "mode" "XF")])
15508
15509 (define_expand "logsf2"
15510   [(set (match_dup 2)
15511         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15512    (parallel [(set (match_dup 4)
15513                    (unspec:XF [(match_dup 2)
15514                                (match_dup 3)] UNSPEC_FYL2X))
15515               (clobber (match_scratch:XF 5 ""))])
15516    (set (match_operand:SF 0 "register_operand" "")
15517         (float_truncate:SF (match_dup 4)))]
15518   "TARGET_USE_FANCY_MATH_387
15519    && flag_unsafe_math_optimizations"
15520 {
15521   rtx temp;
15522
15523   operands[2] = gen_reg_rtx (XFmode);
15524   operands[3] = gen_reg_rtx (XFmode);
15525   operands[4] = gen_reg_rtx (XFmode);
15526
15527   temp = standard_80387_constant_rtx (4); /* fldln2 */
15528   emit_move_insn (operands[3], temp);
15529 })
15530
15531 (define_expand "logdf2"
15532   [(set (match_dup 2)
15533         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15534    (parallel [(set (match_dup 4)
15535                    (unspec:XF [(match_dup 2)
15536                                (match_dup 3)] UNSPEC_FYL2X))
15537               (clobber (match_scratch:XF 5 ""))])
15538    (set (match_operand:DF 0 "register_operand" "")
15539         (float_truncate:DF (match_dup 4)))]
15540   "TARGET_USE_FANCY_MATH_387
15541    && flag_unsafe_math_optimizations"
15542 {
15543   rtx temp;
15544
15545   operands[2] = gen_reg_rtx (XFmode);
15546   operands[3] = gen_reg_rtx (XFmode);
15547   operands[4] = gen_reg_rtx (XFmode);
15548
15549   temp = standard_80387_constant_rtx (4); /* fldln2 */
15550   emit_move_insn (operands[3], temp);
15551 })
15552
15553 (define_expand "logxf2"
15554   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15555                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15556                                (match_dup 2)] UNSPEC_FYL2X))
15557               (clobber (match_scratch:XF 3 ""))])]
15558   "TARGET_USE_FANCY_MATH_387
15559    && flag_unsafe_math_optimizations"
15560 {
15561   rtx temp;
15562
15563   operands[2] = gen_reg_rtx (XFmode);
15564   temp = standard_80387_constant_rtx (4); /* fldln2 */
15565   emit_move_insn (operands[2], temp);
15566 })
15567
15568 (define_expand "log10sf2"
15569   [(set (match_dup 2)
15570         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15571    (parallel [(set (match_dup 4)
15572                    (unspec:XF [(match_dup 2)
15573                                (match_dup 3)] UNSPEC_FYL2X))
15574               (clobber (match_scratch:XF 5 ""))])
15575    (set (match_operand:SF 0 "register_operand" "")
15576         (float_truncate:SF (match_dup 4)))]
15577   "TARGET_USE_FANCY_MATH_387
15578    && flag_unsafe_math_optimizations"
15579 {
15580   rtx temp;
15581
15582   operands[2] = gen_reg_rtx (XFmode);
15583   operands[3] = gen_reg_rtx (XFmode);
15584   operands[4] = gen_reg_rtx (XFmode);
15585
15586   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15587   emit_move_insn (operands[3], temp);
15588 })
15589
15590 (define_expand "log10df2"
15591   [(set (match_dup 2)
15592         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15593    (parallel [(set (match_dup 4)
15594                    (unspec:XF [(match_dup 2)
15595                                (match_dup 3)] UNSPEC_FYL2X))
15596               (clobber (match_scratch:XF 5 ""))])
15597    (set (match_operand:DF 0 "register_operand" "")
15598         (float_truncate:DF (match_dup 4)))]
15599   "TARGET_USE_FANCY_MATH_387
15600    && flag_unsafe_math_optimizations"
15601 {
15602   rtx temp;
15603
15604   operands[2] = gen_reg_rtx (XFmode);
15605   operands[3] = gen_reg_rtx (XFmode);
15606   operands[4] = gen_reg_rtx (XFmode);
15607
15608   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15609   emit_move_insn (operands[3], temp);
15610 })
15611
15612 (define_expand "log10xf2"
15613   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15614                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15615                                (match_dup 2)] UNSPEC_FYL2X))
15616               (clobber (match_scratch:XF 3 ""))])]
15617   "TARGET_USE_FANCY_MATH_387
15618    && flag_unsafe_math_optimizations"
15619 {
15620   rtx temp;
15621
15622   operands[2] = gen_reg_rtx (XFmode);
15623   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15624   emit_move_insn (operands[2], temp);
15625 })
15626
15627 (define_expand "log2sf2"
15628   [(set (match_dup 2)
15629         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15630    (parallel [(set (match_dup 4)
15631                    (unspec:XF [(match_dup 2)
15632                                (match_dup 3)] UNSPEC_FYL2X))
15633               (clobber (match_scratch:XF 5 ""))])
15634    (set (match_operand:SF 0 "register_operand" "")
15635         (float_truncate:SF (match_dup 4)))]
15636   "TARGET_USE_FANCY_MATH_387
15637    && flag_unsafe_math_optimizations"
15638 {
15639   operands[2] = gen_reg_rtx (XFmode);
15640   operands[3] = gen_reg_rtx (XFmode);
15641   operands[4] = gen_reg_rtx (XFmode);
15642
15643   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15644 })
15645
15646 (define_expand "log2df2"
15647   [(set (match_dup 2)
15648         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15649    (parallel [(set (match_dup 4)
15650                    (unspec:XF [(match_dup 2)
15651                                (match_dup 3)] UNSPEC_FYL2X))
15652               (clobber (match_scratch:XF 5 ""))])
15653    (set (match_operand:DF 0 "register_operand" "")
15654         (float_truncate:DF (match_dup 4)))]
15655   "TARGET_USE_FANCY_MATH_387
15656    && flag_unsafe_math_optimizations"
15657 {
15658   operands[2] = gen_reg_rtx (XFmode);
15659   operands[3] = gen_reg_rtx (XFmode);
15660   operands[4] = gen_reg_rtx (XFmode);
15661
15662   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15663 })
15664
15665 (define_expand "log2xf2"
15666   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15667                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15668                                (match_dup 2)] UNSPEC_FYL2X))
15669               (clobber (match_scratch:XF 3 ""))])]
15670   "TARGET_USE_FANCY_MATH_387
15671    && flag_unsafe_math_optimizations"
15672 {
15673   operands[2] = gen_reg_rtx (XFmode);
15674   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15675 })
15676
15677 (define_insn "fyl2xp1_xf3"
15678   [(set (match_operand:XF 0 "register_operand" "=f")
15679         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15680                     (match_operand:XF 1 "register_operand" "u")]
15681                    UNSPEC_FYL2XP1))
15682    (clobber (match_scratch:XF 3 "=1"))]
15683   "TARGET_USE_FANCY_MATH_387
15684    && flag_unsafe_math_optimizations"
15685   "fyl2xp1"
15686   [(set_attr "type" "fpspc")
15687    (set_attr "mode" "XF")])
15688
15689 (define_expand "log1psf2"
15690   [(use (match_operand:XF 0 "register_operand" ""))
15691    (use (match_operand:XF 1 "register_operand" ""))]
15692   "TARGET_USE_FANCY_MATH_387
15693    && flag_unsafe_math_optimizations"
15694 {
15695   rtx op0 = gen_reg_rtx (XFmode);
15696   rtx op1 = gen_reg_rtx (XFmode);
15697
15698   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15699   ix86_emit_i387_log1p (op0, op1);
15700   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15701   DONE;
15702 })
15703
15704 (define_expand "log1pdf2"
15705   [(use (match_operand:XF 0 "register_operand" ""))
15706    (use (match_operand:XF 1 "register_operand" ""))]
15707   "TARGET_USE_FANCY_MATH_387
15708    && flag_unsafe_math_optimizations"
15709 {
15710   rtx op0 = gen_reg_rtx (XFmode);
15711   rtx op1 = gen_reg_rtx (XFmode);
15712
15713   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15714   ix86_emit_i387_log1p (op0, op1);
15715   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15716   DONE;
15717 })
15718
15719 (define_expand "log1pxf2"
15720   [(use (match_operand:XF 0 "register_operand" ""))
15721    (use (match_operand:XF 1 "register_operand" ""))]
15722   "TARGET_USE_FANCY_MATH_387
15723    && flag_unsafe_math_optimizations"
15724 {
15725   ix86_emit_i387_log1p (operands[0], operands[1]);
15726   DONE;
15727 })
15728
15729 (define_insn "*fxtractxf3"
15730   [(set (match_operand:XF 0 "register_operand" "=f")
15731         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15732                    UNSPEC_XTRACT_FRACT))
15733    (set (match_operand:XF 1 "register_operand" "=u")
15734         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15735   "TARGET_USE_FANCY_MATH_387
15736    && flag_unsafe_math_optimizations"
15737   "fxtract"
15738   [(set_attr "type" "fpspc")
15739    (set_attr "mode" "XF")])
15740
15741 (define_expand "logbsf2"
15742   [(set (match_dup 2)
15743         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15744    (parallel [(set (match_dup 3)
15745                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15746               (set (match_dup 4)
15747                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15748    (set (match_operand:SF 0 "register_operand" "")
15749         (float_truncate:SF (match_dup 4)))]
15750   "TARGET_USE_FANCY_MATH_387
15751    && flag_unsafe_math_optimizations"
15752 {
15753   operands[2] = gen_reg_rtx (XFmode);
15754   operands[3] = gen_reg_rtx (XFmode);
15755   operands[4] = gen_reg_rtx (XFmode);
15756 })
15757
15758 (define_expand "logbdf2"
15759   [(set (match_dup 2)
15760         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15761    (parallel [(set (match_dup 3)
15762                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15763               (set (match_dup 4)
15764                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15765    (set (match_operand:DF 0 "register_operand" "")
15766         (float_truncate:DF (match_dup 4)))]
15767   "TARGET_USE_FANCY_MATH_387
15768    && flag_unsafe_math_optimizations"
15769 {
15770   operands[2] = gen_reg_rtx (XFmode);
15771   operands[3] = gen_reg_rtx (XFmode);
15772   operands[4] = gen_reg_rtx (XFmode);
15773 })
15774
15775 (define_expand "logbxf2"
15776   [(parallel [(set (match_dup 2)
15777                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15778                               UNSPEC_XTRACT_FRACT))
15779               (set (match_operand:XF 0 "register_operand" "")
15780                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15781   "TARGET_USE_FANCY_MATH_387
15782    && flag_unsafe_math_optimizations"
15783 {
15784   operands[2] = gen_reg_rtx (XFmode);
15785 })
15786
15787 (define_expand "ilogbsi2"
15788   [(parallel [(set (match_dup 2)
15789                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15790                               UNSPEC_XTRACT_FRACT))
15791               (set (match_operand:XF 3 "register_operand" "")
15792                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15793    (parallel [(set (match_operand:SI 0 "register_operand" "")
15794                    (fix:SI (match_dup 3)))
15795               (clobber (reg:CC FLAGS_REG))])]
15796   "TARGET_USE_FANCY_MATH_387
15797    && flag_unsafe_math_optimizations"
15798 {
15799   operands[2] = gen_reg_rtx (XFmode);
15800   operands[3] = gen_reg_rtx (XFmode);
15801 })
15802
15803 (define_insn "*f2xm1xf2"
15804   [(set (match_operand:XF 0 "register_operand" "=f")
15805         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15806          UNSPEC_F2XM1))]
15807   "TARGET_USE_FANCY_MATH_387
15808    && flag_unsafe_math_optimizations"
15809   "f2xm1"
15810   [(set_attr "type" "fpspc")
15811    (set_attr "mode" "XF")])
15812
15813 (define_insn "*fscalexf4"
15814   [(set (match_operand:XF 0 "register_operand" "=f")
15815         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15816                     (match_operand:XF 3 "register_operand" "1")]
15817                    UNSPEC_FSCALE_FRACT))
15818    (set (match_operand:XF 1 "register_operand" "=u")
15819         (unspec:XF [(match_dup 2) (match_dup 3)]
15820                    UNSPEC_FSCALE_EXP))]
15821   "TARGET_USE_FANCY_MATH_387
15822    && flag_unsafe_math_optimizations"
15823   "fscale"
15824   [(set_attr "type" "fpspc")
15825    (set_attr "mode" "XF")])
15826
15827 (define_expand "expsf2"
15828   [(set (match_dup 2)
15829         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15830    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15831    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15832    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15833    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15834    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15835    (parallel [(set (match_dup 10)
15836                    (unspec:XF [(match_dup 9) (match_dup 5)]
15837                               UNSPEC_FSCALE_FRACT))
15838               (set (match_dup 11)
15839                    (unspec:XF [(match_dup 9) (match_dup 5)]
15840                               UNSPEC_FSCALE_EXP))])
15841    (set (match_operand:SF 0 "register_operand" "")
15842         (float_truncate:SF (match_dup 10)))]
15843   "TARGET_USE_FANCY_MATH_387
15844    && flag_unsafe_math_optimizations"
15845 {
15846   rtx temp;
15847   int i;
15848
15849   for (i=2; i<12; i++)
15850     operands[i] = gen_reg_rtx (XFmode);
15851   temp = standard_80387_constant_rtx (5); /* fldl2e */
15852   emit_move_insn (operands[3], temp);
15853   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15854 })
15855
15856 (define_expand "expdf2"
15857   [(set (match_dup 2)
15858         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15859    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15860    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15861    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15862    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15863    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15864    (parallel [(set (match_dup 10)
15865                    (unspec:XF [(match_dup 9) (match_dup 5)]
15866                               UNSPEC_FSCALE_FRACT))
15867               (set (match_dup 11)
15868                    (unspec:XF [(match_dup 9) (match_dup 5)]
15869                               UNSPEC_FSCALE_EXP))])
15870    (set (match_operand:DF 0 "register_operand" "")
15871         (float_truncate:DF (match_dup 10)))]
15872   "TARGET_USE_FANCY_MATH_387
15873    && flag_unsafe_math_optimizations"
15874 {
15875   rtx temp;
15876   int i;
15877
15878   for (i=2; i<12; i++)
15879     operands[i] = gen_reg_rtx (XFmode);
15880   temp = standard_80387_constant_rtx (5); /* fldl2e */
15881   emit_move_insn (operands[3], temp);
15882   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15883 })
15884
15885 (define_expand "expxf2"
15886   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15887                                (match_dup 2)))
15888    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15889    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15890    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15891    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15892    (parallel [(set (match_operand:XF 0 "register_operand" "")
15893                    (unspec:XF [(match_dup 8) (match_dup 4)]
15894                               UNSPEC_FSCALE_FRACT))
15895               (set (match_dup 9)
15896                    (unspec:XF [(match_dup 8) (match_dup 4)]
15897                               UNSPEC_FSCALE_EXP))])]
15898   "TARGET_USE_FANCY_MATH_387
15899    && flag_unsafe_math_optimizations"
15900 {
15901   rtx temp;
15902   int i;
15903
15904   for (i=2; i<10; i++)
15905     operands[i] = gen_reg_rtx (XFmode);
15906   temp = standard_80387_constant_rtx (5); /* fldl2e */
15907   emit_move_insn (operands[2], temp);
15908   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15909 })
15910
15911 (define_expand "exp10sf2"
15912   [(set (match_dup 2)
15913         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15914    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15915    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15916    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15917    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15918    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15919    (parallel [(set (match_dup 10)
15920                    (unspec:XF [(match_dup 9) (match_dup 5)]
15921                               UNSPEC_FSCALE_FRACT))
15922               (set (match_dup 11)
15923                    (unspec:XF [(match_dup 9) (match_dup 5)]
15924                               UNSPEC_FSCALE_EXP))])
15925    (set (match_operand:SF 0 "register_operand" "")
15926         (float_truncate:SF (match_dup 10)))]
15927   "TARGET_USE_FANCY_MATH_387
15928    && flag_unsafe_math_optimizations"
15929 {
15930   rtx temp;
15931   int i;
15932
15933   for (i=2; i<12; i++)
15934     operands[i] = gen_reg_rtx (XFmode);
15935   temp = standard_80387_constant_rtx (6); /* fldl2t */
15936   emit_move_insn (operands[3], temp);
15937   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15938 })
15939
15940 (define_expand "exp10df2"
15941   [(set (match_dup 2)
15942         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15943    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15944    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15945    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15946    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15947    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15948    (parallel [(set (match_dup 10)
15949                    (unspec:XF [(match_dup 9) (match_dup 5)]
15950                               UNSPEC_FSCALE_FRACT))
15951               (set (match_dup 11)
15952                    (unspec:XF [(match_dup 9) (match_dup 5)]
15953                               UNSPEC_FSCALE_EXP))])
15954    (set (match_operand:DF 0 "register_operand" "")
15955         (float_truncate:DF (match_dup 10)))]
15956   "TARGET_USE_FANCY_MATH_387
15957    && flag_unsafe_math_optimizations"
15958 {
15959   rtx temp;
15960   int i;
15961
15962   for (i=2; i<12; i++)
15963     operands[i] = gen_reg_rtx (XFmode);
15964   temp = standard_80387_constant_rtx (6); /* fldl2t */
15965   emit_move_insn (operands[3], temp);
15966   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15967 })
15968
15969 (define_expand "exp10xf2"
15970   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15971                                (match_dup 2)))
15972    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15973    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15974    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15975    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15976    (parallel [(set (match_operand:XF 0 "register_operand" "")
15977                    (unspec:XF [(match_dup 8) (match_dup 4)]
15978                               UNSPEC_FSCALE_FRACT))
15979               (set (match_dup 9)
15980                    (unspec:XF [(match_dup 8) (match_dup 4)]
15981                               UNSPEC_FSCALE_EXP))])]
15982   "TARGET_USE_FANCY_MATH_387
15983    && flag_unsafe_math_optimizations"
15984 {
15985   rtx temp;
15986   int i;
15987
15988   for (i=2; i<10; i++)
15989     operands[i] = gen_reg_rtx (XFmode);
15990   temp = standard_80387_constant_rtx (6); /* fldl2t */
15991   emit_move_insn (operands[2], temp);
15992   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15993 })
15994
15995 (define_expand "exp2sf2"
15996   [(set (match_dup 2)
15997         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15998    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15999    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16000    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16001    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16002    (parallel [(set (match_dup 8)
16003                    (unspec:XF [(match_dup 7) (match_dup 3)]
16004                               UNSPEC_FSCALE_FRACT))
16005               (set (match_dup 9)
16006                    (unspec:XF [(match_dup 7) (match_dup 3)]
16007                               UNSPEC_FSCALE_EXP))])
16008    (set (match_operand:SF 0 "register_operand" "")
16009         (float_truncate:SF (match_dup 8)))]
16010   "TARGET_USE_FANCY_MATH_387
16011    && flag_unsafe_math_optimizations"
16012 {
16013   int i;
16014
16015   for (i=2; i<10; i++)
16016     operands[i] = gen_reg_rtx (XFmode);
16017   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16018 })
16019
16020 (define_expand "exp2df2"
16021   [(set (match_dup 2)
16022         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16023    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16024    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16025    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16026    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16027    (parallel [(set (match_dup 8)
16028                    (unspec:XF [(match_dup 7) (match_dup 3)]
16029                               UNSPEC_FSCALE_FRACT))
16030               (set (match_dup 9)
16031                    (unspec:XF [(match_dup 7) (match_dup 3)]
16032                               UNSPEC_FSCALE_EXP))])
16033    (set (match_operand:DF 0 "register_operand" "")
16034         (float_truncate:DF (match_dup 8)))]
16035   "TARGET_USE_FANCY_MATH_387
16036    && flag_unsafe_math_optimizations"
16037 {
16038   int i;
16039
16040   for (i=2; i<10; i++)
16041     operands[i] = gen_reg_rtx (XFmode);
16042   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16043 })
16044
16045 (define_expand "exp2xf2"
16046   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16047    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16048    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16049    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16050    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16051    (parallel [(set (match_operand:XF 0 "register_operand" "")
16052                    (unspec:XF [(match_dup 7) (match_dup 3)]
16053                               UNSPEC_FSCALE_FRACT))
16054               (set (match_dup 8)
16055                    (unspec:XF [(match_dup 7) (match_dup 3)]
16056                               UNSPEC_FSCALE_EXP))])]
16057   "TARGET_USE_FANCY_MATH_387
16058    && flag_unsafe_math_optimizations"
16059 {
16060   int i;
16061
16062   for (i=2; i<9; i++)
16063     operands[i] = gen_reg_rtx (XFmode);
16064   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16065 })
16066
16067 (define_expand "expm1df2"
16068   [(set (match_dup 2)
16069         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16070    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16071    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16072    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16073    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16074    (parallel [(set (match_dup 8)
16075                    (unspec:XF [(match_dup 7) (match_dup 5)]
16076                               UNSPEC_FSCALE_FRACT))
16077                    (set (match_dup 9)
16078                    (unspec:XF [(match_dup 7) (match_dup 5)]
16079                               UNSPEC_FSCALE_EXP))])
16080    (parallel [(set (match_dup 11)
16081                    (unspec:XF [(match_dup 10) (match_dup 9)]
16082                               UNSPEC_FSCALE_FRACT))
16083               (set (match_dup 12)
16084                    (unspec:XF [(match_dup 10) (match_dup 9)]
16085                               UNSPEC_FSCALE_EXP))])
16086    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16087    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16088    (set (match_operand:DF 0 "register_operand" "")
16089         (float_truncate:DF (match_dup 14)))]
16090   "TARGET_USE_FANCY_MATH_387
16091    && flag_unsafe_math_optimizations"
16092 {
16093   rtx temp;
16094   int i;
16095
16096   for (i=2; i<15; i++)
16097     operands[i] = gen_reg_rtx (XFmode);
16098   temp = standard_80387_constant_rtx (5); /* fldl2e */
16099   emit_move_insn (operands[3], temp);
16100   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16101 })
16102
16103 (define_expand "expm1sf2"
16104   [(set (match_dup 2)
16105         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16106    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16107    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16108    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16109    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16110    (parallel [(set (match_dup 8)
16111                    (unspec:XF [(match_dup 7) (match_dup 5)]
16112                               UNSPEC_FSCALE_FRACT))
16113                    (set (match_dup 9)
16114                    (unspec:XF [(match_dup 7) (match_dup 5)]
16115                               UNSPEC_FSCALE_EXP))])
16116    (parallel [(set (match_dup 11)
16117                    (unspec:XF [(match_dup 10) (match_dup 9)]
16118                               UNSPEC_FSCALE_FRACT))
16119               (set (match_dup 12)
16120                    (unspec:XF [(match_dup 10) (match_dup 9)]
16121                               UNSPEC_FSCALE_EXP))])
16122    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16123    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16124    (set (match_operand:SF 0 "register_operand" "")
16125         (float_truncate:SF (match_dup 14)))]
16126   "TARGET_USE_FANCY_MATH_387
16127    && flag_unsafe_math_optimizations"
16128 {
16129   rtx temp;
16130   int i;
16131
16132   for (i=2; i<15; i++)
16133     operands[i] = gen_reg_rtx (XFmode);
16134   temp = standard_80387_constant_rtx (5); /* fldl2e */
16135   emit_move_insn (operands[3], temp);
16136   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16137 })
16138
16139 (define_expand "expm1xf2"
16140   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16141                                (match_dup 2)))
16142    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16143    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16144    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16145    (parallel [(set (match_dup 7)
16146                    (unspec:XF [(match_dup 6) (match_dup 4)]
16147                               UNSPEC_FSCALE_FRACT))
16148                    (set (match_dup 8)
16149                    (unspec:XF [(match_dup 6) (match_dup 4)]
16150                               UNSPEC_FSCALE_EXP))])
16151    (parallel [(set (match_dup 10)
16152                    (unspec:XF [(match_dup 9) (match_dup 8)]
16153                               UNSPEC_FSCALE_FRACT))
16154               (set (match_dup 11)
16155                    (unspec:XF [(match_dup 9) (match_dup 8)]
16156                               UNSPEC_FSCALE_EXP))])
16157    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16158    (set (match_operand:XF 0 "register_operand" "")
16159         (plus:XF (match_dup 12) (match_dup 7)))]
16160   "TARGET_USE_FANCY_MATH_387
16161    && flag_unsafe_math_optimizations"
16162 {
16163   rtx temp;
16164   int i;
16165
16166   for (i=2; i<13; i++)
16167     operands[i] = gen_reg_rtx (XFmode);
16168   temp = standard_80387_constant_rtx (5); /* fldl2e */
16169   emit_move_insn (operands[2], temp);
16170   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16171 })
16172 \f
16173
16174 (define_insn "frndintxf2"
16175   [(set (match_operand:XF 0 "register_operand" "=f")
16176         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16177          UNSPEC_FRNDINT))]
16178   "TARGET_USE_FANCY_MATH_387
16179    && flag_unsafe_math_optimizations"
16180   "frndint"
16181   [(set_attr "type" "fpspc")
16182    (set_attr "mode" "XF")])
16183
16184 (define_expand "rintdf2"
16185   [(use (match_operand:DF 0 "register_operand" ""))
16186    (use (match_operand:DF 1 "register_operand" ""))]
16187   "TARGET_USE_FANCY_MATH_387
16188    && flag_unsafe_math_optimizations"
16189 {
16190   rtx op0 = gen_reg_rtx (XFmode);
16191   rtx op1 = gen_reg_rtx (XFmode);
16192
16193   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16194   emit_insn (gen_frndintxf2 (op0, op1));
16195
16196   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16197   DONE;
16198 })
16199
16200 (define_expand "rintsf2"
16201   [(use (match_operand:SF 0 "register_operand" ""))
16202    (use (match_operand:SF 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_extendsfxf2 (op1, operands[1]));
16210   emit_insn (gen_frndintxf2 (op0, op1));
16211
16212   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16213   DONE;
16214 })
16215
16216 (define_expand "rintxf2"
16217   [(use (match_operand:XF 0 "register_operand" ""))
16218    (use (match_operand:XF 1 "register_operand" ""))]
16219   "TARGET_USE_FANCY_MATH_387
16220    && flag_unsafe_math_optimizations"
16221 {
16222   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16223   DONE;
16224 })
16225
16226 (define_insn "frndintxf2_floor"
16227   [(set (match_operand:XF 0 "register_operand" "=f")
16228         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16229          UNSPEC_FRNDINT_FLOOR))
16230    (use (match_operand:HI 2 "memory_operand" "m"))
16231    (use (match_operand:HI 3 "memory_operand" "m"))]
16232   "TARGET_USE_FANCY_MATH_387
16233    && flag_unsafe_math_optimizations"
16234   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16235   [(set_attr "type" "frndint")
16236    (set_attr "i387_cw" "floor")
16237    (set_attr "mode" "XF")])
16238
16239 (define_expand "floordf2"
16240   [(use (match_operand:DF 0 "register_operand" ""))
16241    (use (match_operand:DF 1 "register_operand" ""))]
16242   "TARGET_USE_FANCY_MATH_387
16243    && flag_unsafe_math_optimizations"
16244 {
16245   rtx op0 = gen_reg_rtx (XFmode);
16246   rtx op1 = gen_reg_rtx (XFmode);
16247   rtx op2 = assign_386_stack_local (HImode, 1);
16248   rtx op3 = assign_386_stack_local (HImode, 2);
16249         
16250   ix86_optimize_mode_switching = 1;
16251
16252   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16253   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16254
16255   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16256   DONE;
16257 })
16258
16259 (define_expand "floorsf2"
16260   [(use (match_operand:SF 0 "register_operand" ""))
16261    (use (match_operand:SF 1 "register_operand" ""))]
16262   "TARGET_USE_FANCY_MATH_387
16263    && flag_unsafe_math_optimizations"
16264 {
16265   rtx op0 = gen_reg_rtx (XFmode);
16266   rtx op1 = gen_reg_rtx (XFmode);
16267   rtx op2 = assign_386_stack_local (HImode, 1);
16268   rtx op3 = assign_386_stack_local (HImode, 2);
16269         
16270   ix86_optimize_mode_switching = 1;
16271
16272   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16273   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16274
16275   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16276   DONE;
16277 })
16278
16279 (define_expand "floorxf2"
16280   [(use (match_operand:XF 0 "register_operand" ""))
16281    (use (match_operand:XF 1 "register_operand" ""))]
16282   "TARGET_USE_FANCY_MATH_387
16283    && flag_unsafe_math_optimizations"
16284 {
16285   rtx op2 = assign_386_stack_local (HImode, 1);
16286   rtx op3 = assign_386_stack_local (HImode, 2);
16287         
16288   ix86_optimize_mode_switching = 1;
16289
16290   emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16291   DONE;
16292 })
16293
16294 (define_insn "frndintxf2_ceil"
16295   [(set (match_operand:XF 0 "register_operand" "=f")
16296         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16297          UNSPEC_FRNDINT_CEIL))
16298    (use (match_operand:HI 2 "memory_operand" "m"))
16299    (use (match_operand:HI 3 "memory_operand" "m"))]
16300   "TARGET_USE_FANCY_MATH_387
16301    && flag_unsafe_math_optimizations"
16302   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16303   [(set_attr "type" "frndint")
16304    (set_attr "i387_cw" "ceil")
16305    (set_attr "mode" "XF")])
16306
16307 (define_expand "ceildf2"
16308   [(use (match_operand:DF 0 "register_operand" ""))
16309    (use (match_operand:DF 1 "register_operand" ""))]
16310   "TARGET_USE_FANCY_MATH_387
16311    && flag_unsafe_math_optimizations"
16312 {
16313   rtx op0 = gen_reg_rtx (XFmode);
16314   rtx op1 = gen_reg_rtx (XFmode);
16315   rtx op2 = assign_386_stack_local (HImode, 1);
16316   rtx op3 = assign_386_stack_local (HImode, 2);
16317         
16318   ix86_optimize_mode_switching = 1;
16319
16320   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16321   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16322
16323   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16324   DONE;
16325 })
16326
16327 (define_expand "ceilsf2"
16328   [(use (match_operand:SF 0 "register_operand" ""))
16329    (use (match_operand:SF 1 "register_operand" ""))]
16330   "TARGET_USE_FANCY_MATH_387
16331    && flag_unsafe_math_optimizations"
16332 {
16333   rtx op0 = gen_reg_rtx (XFmode);
16334   rtx op1 = gen_reg_rtx (XFmode);
16335   rtx op2 = assign_386_stack_local (HImode, 1);
16336   rtx op3 = assign_386_stack_local (HImode, 2);
16337         
16338   ix86_optimize_mode_switching = 1;
16339
16340   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16341   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16342
16343   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16344   DONE;
16345 })
16346
16347 (define_expand "ceilxf2"
16348   [(use (match_operand:XF 0 "register_operand" ""))
16349    (use (match_operand:XF 1 "register_operand" ""))]
16350   "TARGET_USE_FANCY_MATH_387
16351    && flag_unsafe_math_optimizations"
16352 {
16353   rtx op2 = assign_386_stack_local (HImode, 1);
16354   rtx op3 = assign_386_stack_local (HImode, 2);
16355         
16356   ix86_optimize_mode_switching = 1;
16357
16358   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16359   DONE;
16360 })
16361
16362 (define_insn "frndintxf2_trunc"
16363   [(set (match_operand:XF 0 "register_operand" "=f")
16364         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16365          UNSPEC_FRNDINT_TRUNC))
16366    (use (match_operand:HI 2 "memory_operand" "m"))
16367    (use (match_operand:HI 3 "memory_operand" "m"))]
16368   "TARGET_USE_FANCY_MATH_387
16369    && flag_unsafe_math_optimizations"
16370   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16371   [(set_attr "type" "frndint")
16372    (set_attr "i387_cw" "trunc")
16373    (set_attr "mode" "XF")])
16374
16375 (define_expand "btruncdf2"
16376   [(use (match_operand:DF 0 "register_operand" ""))
16377    (use (match_operand:DF 1 "register_operand" ""))]
16378   "TARGET_USE_FANCY_MATH_387
16379    && flag_unsafe_math_optimizations"
16380 {
16381   rtx op0 = gen_reg_rtx (XFmode);
16382   rtx op1 = gen_reg_rtx (XFmode);
16383   rtx op2 = assign_386_stack_local (HImode, 1);
16384   rtx op3 = assign_386_stack_local (HImode, 2);
16385         
16386   ix86_optimize_mode_switching = 1;
16387
16388   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16389   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16390
16391   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16392   DONE;
16393 })
16394
16395 (define_expand "btruncsf2"
16396   [(use (match_operand:SF 0 "register_operand" ""))
16397    (use (match_operand:SF 1 "register_operand" ""))]
16398   "TARGET_USE_FANCY_MATH_387
16399    && flag_unsafe_math_optimizations"
16400 {
16401   rtx op0 = gen_reg_rtx (XFmode);
16402   rtx op1 = gen_reg_rtx (XFmode);
16403   rtx op2 = assign_386_stack_local (HImode, 1);
16404   rtx op3 = assign_386_stack_local (HImode, 2);
16405         
16406   ix86_optimize_mode_switching = 1;
16407
16408   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16409   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16410
16411   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16412   DONE;
16413 })
16414
16415 (define_expand "btruncxf2"
16416   [(use (match_operand:XF 0 "register_operand" ""))
16417    (use (match_operand:XF 1 "register_operand" ""))]
16418   "TARGET_USE_FANCY_MATH_387
16419    && flag_unsafe_math_optimizations"
16420 {
16421   rtx op2 = assign_386_stack_local (HImode, 1);
16422   rtx op3 = assign_386_stack_local (HImode, 2);
16423         
16424   ix86_optimize_mode_switching = 1;
16425
16426   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16427   DONE;
16428 })
16429
16430 (define_insn "frndintxf2_mask_pm"
16431   [(set (match_operand:XF 0 "register_operand" "=f")
16432         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16433          UNSPEC_FRNDINT_MASK_PM))
16434    (use (match_operand:HI 2 "memory_operand" "m"))
16435    (use (match_operand:HI 3 "memory_operand" "m"))]
16436   "TARGET_USE_FANCY_MATH_387
16437    && flag_unsafe_math_optimizations"
16438   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16439   [(set_attr "type" "frndint")
16440    (set_attr "i387_cw" "mask_pm")
16441    (set_attr "mode" "XF")])
16442
16443 (define_expand "nearbyintdf2"
16444   [(use (match_operand:DF 0 "register_operand" ""))
16445    (use (match_operand:DF 1 "register_operand" ""))]
16446   "TARGET_USE_FANCY_MATH_387
16447    && flag_unsafe_math_optimizations"
16448 {
16449   rtx op0 = gen_reg_rtx (XFmode);
16450   rtx op1 = gen_reg_rtx (XFmode);
16451   rtx op2 = assign_386_stack_local (HImode, 1);
16452   rtx op3 = assign_386_stack_local (HImode, 2);
16453         
16454   ix86_optimize_mode_switching = 1;
16455
16456   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16457   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16458
16459   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16460   DONE;
16461 })
16462
16463 (define_expand "nearbyintsf2"
16464   [(use (match_operand:SF 0 "register_operand" ""))
16465    (use (match_operand:SF 1 "register_operand" ""))]
16466   "TARGET_USE_FANCY_MATH_387
16467    && flag_unsafe_math_optimizations"
16468 {
16469   rtx op0 = gen_reg_rtx (XFmode);
16470   rtx op1 = gen_reg_rtx (XFmode);
16471   rtx op2 = assign_386_stack_local (HImode, 1);
16472   rtx op3 = assign_386_stack_local (HImode, 2);
16473         
16474   ix86_optimize_mode_switching = 1;
16475
16476   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16477   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16478
16479   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16480   DONE;
16481 })
16482
16483 (define_expand "nearbyintxf2"
16484   [(use (match_operand:XF 0 "register_operand" ""))
16485    (use (match_operand:XF 1 "register_operand" ""))]
16486   "TARGET_USE_FANCY_MATH_387
16487    && flag_unsafe_math_optimizations"
16488 {
16489   rtx op2 = assign_386_stack_local (HImode, 1);
16490   rtx op3 = assign_386_stack_local (HImode, 2);
16491         
16492   ix86_optimize_mode_switching = 1;
16493
16494   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16495                                      op2, op3));
16496   DONE;
16497 })
16498
16499 \f
16500 ;; Block operation instructions
16501
16502 (define_insn "cld"
16503  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16504  ""
16505  "cld"
16506   [(set_attr "type" "cld")])
16507
16508 (define_expand "movmemsi"
16509   [(use (match_operand:BLK 0 "memory_operand" ""))
16510    (use (match_operand:BLK 1 "memory_operand" ""))
16511    (use (match_operand:SI 2 "nonmemory_operand" ""))
16512    (use (match_operand:SI 3 "const_int_operand" ""))]
16513   "! optimize_size"
16514 {
16515  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16516    DONE;
16517  else
16518    FAIL;
16519 })
16520
16521 (define_expand "movmemdi"
16522   [(use (match_operand:BLK 0 "memory_operand" ""))
16523    (use (match_operand:BLK 1 "memory_operand" ""))
16524    (use (match_operand:DI 2 "nonmemory_operand" ""))
16525    (use (match_operand:DI 3 "const_int_operand" ""))]
16526   "TARGET_64BIT"
16527 {
16528  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16529    DONE;
16530  else
16531    FAIL;
16532 })
16533
16534 ;; Most CPUs don't like single string operations
16535 ;; Handle this case here to simplify previous expander.
16536
16537 (define_expand "strmov"
16538   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16539    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16540    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16541               (clobber (reg:CC FLAGS_REG))])
16542    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16543               (clobber (reg:CC FLAGS_REG))])]
16544   ""
16545 {
16546   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16547
16548   /* If .md ever supports :P for Pmode, these can be directly
16549      in the pattern above.  */
16550   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16551   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16552
16553   if (TARGET_SINGLE_STRINGOP || optimize_size)
16554     {
16555       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16556                                       operands[2], operands[3],
16557                                       operands[5], operands[6]));
16558       DONE;
16559     }
16560
16561   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16562 })
16563
16564 (define_expand "strmov_singleop"
16565   [(parallel [(set (match_operand 1 "memory_operand" "")
16566                    (match_operand 3 "memory_operand" ""))
16567               (set (match_operand 0 "register_operand" "")
16568                    (match_operand 4 "" ""))
16569               (set (match_operand 2 "register_operand" "")
16570                    (match_operand 5 "" ""))
16571               (use (reg:SI DIRFLAG_REG))])]
16572   "TARGET_SINGLE_STRINGOP || optimize_size"
16573   "")
16574
16575 (define_insn "*strmovdi_rex_1"
16576   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16577         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16578    (set (match_operand:DI 0 "register_operand" "=D")
16579         (plus:DI (match_dup 2)
16580                  (const_int 8)))
16581    (set (match_operand:DI 1 "register_operand" "=S")
16582         (plus:DI (match_dup 3)
16583                  (const_int 8)))
16584    (use (reg:SI DIRFLAG_REG))]
16585   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16586   "movsq"
16587   [(set_attr "type" "str")
16588    (set_attr "mode" "DI")
16589    (set_attr "memory" "both")])
16590
16591 (define_insn "*strmovsi_1"
16592   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16593         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16594    (set (match_operand:SI 0 "register_operand" "=D")
16595         (plus:SI (match_dup 2)
16596                  (const_int 4)))
16597    (set (match_operand:SI 1 "register_operand" "=S")
16598         (plus:SI (match_dup 3)
16599                  (const_int 4)))
16600    (use (reg:SI DIRFLAG_REG))]
16601   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16602   "{movsl|movsd}"
16603   [(set_attr "type" "str")
16604    (set_attr "mode" "SI")
16605    (set_attr "memory" "both")])
16606
16607 (define_insn "*strmovsi_rex_1"
16608   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16609         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16610    (set (match_operand:DI 0 "register_operand" "=D")
16611         (plus:DI (match_dup 2)
16612                  (const_int 4)))
16613    (set (match_operand:DI 1 "register_operand" "=S")
16614         (plus:DI (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 "*strmovhi_1"
16624   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16625         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16626    (set (match_operand:SI 0 "register_operand" "=D")
16627         (plus:SI (match_dup 2)
16628                  (const_int 2)))
16629    (set (match_operand:SI 1 "register_operand" "=S")
16630         (plus:SI (match_dup 3)
16631                  (const_int 2)))
16632    (use (reg:SI DIRFLAG_REG))]
16633   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16634   "movsw"
16635   [(set_attr "type" "str")
16636    (set_attr "memory" "both")
16637    (set_attr "mode" "HI")])
16638
16639 (define_insn "*strmovhi_rex_1"
16640   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16641         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16642    (set (match_operand:DI 0 "register_operand" "=D")
16643         (plus:DI (match_dup 2)
16644                  (const_int 2)))
16645    (set (match_operand:DI 1 "register_operand" "=S")
16646         (plus:DI (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 "*strmovqi_1"
16656   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16657         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16658    (set (match_operand:SI 0 "register_operand" "=D")
16659         (plus:SI (match_dup 2)
16660                  (const_int 1)))
16661    (set (match_operand:SI 1 "register_operand" "=S")
16662         (plus:SI (match_dup 3)
16663                  (const_int 1)))
16664    (use (reg:SI DIRFLAG_REG))]
16665   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16666   "movsb"
16667   [(set_attr "type" "str")
16668    (set_attr "memory" "both")
16669    (set_attr "mode" "QI")])
16670
16671 (define_insn "*strmovqi_rex_1"
16672   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16673         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16674    (set (match_operand:DI 0 "register_operand" "=D")
16675         (plus:DI (match_dup 2)
16676                  (const_int 1)))
16677    (set (match_operand:DI 1 "register_operand" "=S")
16678         (plus:DI (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_expand "rep_mov"
16688   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16689               (set (match_operand 0 "register_operand" "")
16690                    (match_operand 5 "" ""))
16691               (set (match_operand 2 "register_operand" "")
16692                    (match_operand 6 "" ""))
16693               (set (match_operand 1 "memory_operand" "")
16694                    (match_operand 3 "memory_operand" ""))
16695               (use (match_dup 4))
16696               (use (reg:SI DIRFLAG_REG))])]
16697   ""
16698   "")
16699
16700 (define_insn "*rep_movdi_rex64"
16701   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16702    (set (match_operand:DI 0 "register_operand" "=D") 
16703         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16704                             (const_int 3))
16705                  (match_operand:DI 3 "register_operand" "0")))
16706    (set (match_operand:DI 1 "register_operand" "=S") 
16707         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16708                  (match_operand:DI 4 "register_operand" "1")))
16709    (set (mem:BLK (match_dup 3))
16710         (mem:BLK (match_dup 4)))
16711    (use (match_dup 5))
16712    (use (reg:SI DIRFLAG_REG))]
16713   "TARGET_64BIT"
16714   "{rep\;movsq|rep movsq}"
16715   [(set_attr "type" "str")
16716    (set_attr "prefix_rep" "1")
16717    (set_attr "memory" "both")
16718    (set_attr "mode" "DI")])
16719
16720 (define_insn "*rep_movsi"
16721   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16722    (set (match_operand:SI 0 "register_operand" "=D") 
16723         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16724                             (const_int 2))
16725                  (match_operand:SI 3 "register_operand" "0")))
16726    (set (match_operand:SI 1 "register_operand" "=S") 
16727         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16728                  (match_operand:SI 4 "register_operand" "1")))
16729    (set (mem:BLK (match_dup 3))
16730         (mem:BLK (match_dup 4)))
16731    (use (match_dup 5))
16732    (use (reg:SI DIRFLAG_REG))]
16733   "!TARGET_64BIT"
16734   "{rep\;movsl|rep movsd}"
16735   [(set_attr "type" "str")
16736    (set_attr "prefix_rep" "1")
16737    (set_attr "memory" "both")
16738    (set_attr "mode" "SI")])
16739
16740 (define_insn "*rep_movsi_rex64"
16741   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16742    (set (match_operand:DI 0 "register_operand" "=D") 
16743         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16744                             (const_int 2))
16745                  (match_operand:DI 3 "register_operand" "0")))
16746    (set (match_operand:DI 1 "register_operand" "=S") 
16747         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16748                  (match_operand:DI 4 "register_operand" "1")))
16749    (set (mem:BLK (match_dup 3))
16750         (mem:BLK (match_dup 4)))
16751    (use (match_dup 5))
16752    (use (reg:SI DIRFLAG_REG))]
16753   "TARGET_64BIT"
16754   "{rep\;movsl|rep movsd}"
16755   [(set_attr "type" "str")
16756    (set_attr "prefix_rep" "1")
16757    (set_attr "memory" "both")
16758    (set_attr "mode" "SI")])
16759
16760 (define_insn "*rep_movqi"
16761   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16762    (set (match_operand:SI 0 "register_operand" "=D") 
16763         (plus:SI (match_operand:SI 3 "register_operand" "0")
16764                  (match_operand:SI 5 "register_operand" "2")))
16765    (set (match_operand:SI 1 "register_operand" "=S") 
16766         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16767    (set (mem:BLK (match_dup 3))
16768         (mem:BLK (match_dup 4)))
16769    (use (match_dup 5))
16770    (use (reg:SI DIRFLAG_REG))]
16771   "!TARGET_64BIT"
16772   "{rep\;movsb|rep movsb}"
16773   [(set_attr "type" "str")
16774    (set_attr "prefix_rep" "1")
16775    (set_attr "memory" "both")
16776    (set_attr "mode" "SI")])
16777
16778 (define_insn "*rep_movqi_rex64"
16779   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16780    (set (match_operand:DI 0 "register_operand" "=D") 
16781         (plus:DI (match_operand:DI 3 "register_operand" "0")
16782                  (match_operand:DI 5 "register_operand" "2")))
16783    (set (match_operand:DI 1 "register_operand" "=S") 
16784         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16785    (set (mem:BLK (match_dup 3))
16786         (mem:BLK (match_dup 4)))
16787    (use (match_dup 5))
16788    (use (reg:SI DIRFLAG_REG))]
16789   "TARGET_64BIT"
16790   "{rep\;movsb|rep movsb}"
16791   [(set_attr "type" "str")
16792    (set_attr "prefix_rep" "1")
16793    (set_attr "memory" "both")
16794    (set_attr "mode" "SI")])
16795
16796 (define_expand "clrmemsi"
16797    [(use (match_operand:BLK 0 "memory_operand" ""))
16798     (use (match_operand:SI 1 "nonmemory_operand" ""))
16799     (use (match_operand 2 "const_int_operand" ""))]
16800   ""
16801 {
16802  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16803    DONE;
16804  else
16805    FAIL;
16806 })
16807
16808 (define_expand "clrmemdi"
16809    [(use (match_operand:BLK 0 "memory_operand" ""))
16810     (use (match_operand:DI 1 "nonmemory_operand" ""))
16811     (use (match_operand 2 "const_int_operand" ""))]
16812   "TARGET_64BIT"
16813 {
16814  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16815    DONE;
16816  else
16817    FAIL;
16818 })
16819
16820 ;; Most CPUs don't like single string operations
16821 ;; Handle this case here to simplify previous expander.
16822
16823 (define_expand "strset"
16824   [(set (match_operand 1 "memory_operand" "")
16825         (match_operand 2 "register_operand" ""))
16826    (parallel [(set (match_operand 0 "register_operand" "")
16827                    (match_dup 3))
16828               (clobber (reg:CC FLAGS_REG))])]
16829   ""
16830 {
16831   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16832     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16833
16834   /* If .md ever supports :P for Pmode, this can be directly
16835      in the pattern above.  */
16836   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16837                               GEN_INT (GET_MODE_SIZE (GET_MODE
16838                                                       (operands[2]))));
16839   if (TARGET_SINGLE_STRINGOP || optimize_size)
16840     {
16841       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16842                                       operands[3]));
16843       DONE;
16844     }
16845 })
16846
16847 (define_expand "strset_singleop"
16848   [(parallel [(set (match_operand 1 "memory_operand" "")
16849                    (match_operand 2 "register_operand" ""))
16850               (set (match_operand 0 "register_operand" "")
16851                    (match_operand 3 "" ""))
16852               (use (reg:SI DIRFLAG_REG))])]
16853   "TARGET_SINGLE_STRINGOP || optimize_size"
16854   "")
16855
16856 (define_insn "*strsetdi_rex_1"
16857   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16858         (match_operand:DI 2 "register_operand" "a"))
16859    (set (match_operand:DI 0 "register_operand" "=D")
16860         (plus:DI (match_dup 1)
16861                  (const_int 8)))
16862    (use (reg:SI DIRFLAG_REG))]
16863   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16864   "stosq"
16865   [(set_attr "type" "str")
16866    (set_attr "memory" "store")
16867    (set_attr "mode" "DI")])
16868
16869 (define_insn "*strsetsi_1"
16870   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16871         (match_operand:SI 2 "register_operand" "a"))
16872    (set (match_operand:SI 0 "register_operand" "=D")
16873         (plus:SI (match_dup 1)
16874                  (const_int 4)))
16875    (use (reg:SI DIRFLAG_REG))]
16876   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16877   "{stosl|stosd}"
16878   [(set_attr "type" "str")
16879    (set_attr "memory" "store")
16880    (set_attr "mode" "SI")])
16881
16882 (define_insn "*strsetsi_rex_1"
16883   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16884         (match_operand:SI 2 "register_operand" "a"))
16885    (set (match_operand:DI 0 "register_operand" "=D")
16886         (plus:DI (match_dup 1)
16887                  (const_int 4)))
16888    (use (reg:SI DIRFLAG_REG))]
16889   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16890   "{stosl|stosd}"
16891   [(set_attr "type" "str")
16892    (set_attr "memory" "store")
16893    (set_attr "mode" "SI")])
16894
16895 (define_insn "*strsethi_1"
16896   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16897         (match_operand:HI 2 "register_operand" "a"))
16898    (set (match_operand:SI 0 "register_operand" "=D")
16899         (plus:SI (match_dup 1)
16900                  (const_int 2)))
16901    (use (reg:SI DIRFLAG_REG))]
16902   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16903   "stosw"
16904   [(set_attr "type" "str")
16905    (set_attr "memory" "store")
16906    (set_attr "mode" "HI")])
16907
16908 (define_insn "*strsethi_rex_1"
16909   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16910         (match_operand:HI 2 "register_operand" "a"))
16911    (set (match_operand:DI 0 "register_operand" "=D")
16912         (plus:DI (match_dup 1)
16913                  (const_int 2)))
16914    (use (reg:SI DIRFLAG_REG))]
16915   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16916   "stosw"
16917   [(set_attr "type" "str")
16918    (set_attr "memory" "store")
16919    (set_attr "mode" "HI")])
16920
16921 (define_insn "*strsetqi_1"
16922   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16923         (match_operand:QI 2 "register_operand" "a"))
16924    (set (match_operand:SI 0 "register_operand" "=D")
16925         (plus:SI (match_dup 1)
16926                  (const_int 1)))
16927    (use (reg:SI DIRFLAG_REG))]
16928   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16929   "stosb"
16930   [(set_attr "type" "str")
16931    (set_attr "memory" "store")
16932    (set_attr "mode" "QI")])
16933
16934 (define_insn "*strsetqi_rex_1"
16935   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16936         (match_operand:QI 2 "register_operand" "a"))
16937    (set (match_operand:DI 0 "register_operand" "=D")
16938         (plus:DI (match_dup 1)
16939                  (const_int 1)))
16940    (use (reg:SI DIRFLAG_REG))]
16941   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16942   "stosb"
16943   [(set_attr "type" "str")
16944    (set_attr "memory" "store")
16945    (set_attr "mode" "QI")])
16946
16947 (define_expand "rep_stos"
16948   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16949               (set (match_operand 0 "register_operand" "")
16950                    (match_operand 4 "" ""))
16951               (set (match_operand 2 "memory_operand" "") (const_int 0))
16952               (use (match_operand 3 "register_operand" ""))
16953               (use (match_dup 1))
16954               (use (reg:SI DIRFLAG_REG))])]
16955   ""
16956   "")
16957
16958 (define_insn "*rep_stosdi_rex64"
16959   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16960    (set (match_operand:DI 0 "register_operand" "=D") 
16961         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16962                             (const_int 3))
16963                  (match_operand:DI 3 "register_operand" "0")))
16964    (set (mem:BLK (match_dup 3))
16965         (const_int 0))
16966    (use (match_operand:DI 2 "register_operand" "a"))
16967    (use (match_dup 4))
16968    (use (reg:SI DIRFLAG_REG))]
16969   "TARGET_64BIT"
16970   "{rep\;stosq|rep stosq}"
16971   [(set_attr "type" "str")
16972    (set_attr "prefix_rep" "1")
16973    (set_attr "memory" "store")
16974    (set_attr "mode" "DI")])
16975
16976 (define_insn "*rep_stossi"
16977   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16978    (set (match_operand:SI 0 "register_operand" "=D") 
16979         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16980                             (const_int 2))
16981                  (match_operand:SI 3 "register_operand" "0")))
16982    (set (mem:BLK (match_dup 3))
16983         (const_int 0))
16984    (use (match_operand:SI 2 "register_operand" "a"))
16985    (use (match_dup 4))
16986    (use (reg:SI DIRFLAG_REG))]
16987   "!TARGET_64BIT"
16988   "{rep\;stosl|rep stosd}"
16989   [(set_attr "type" "str")
16990    (set_attr "prefix_rep" "1")
16991    (set_attr "memory" "store")
16992    (set_attr "mode" "SI")])
16993
16994 (define_insn "*rep_stossi_rex64"
16995   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16996    (set (match_operand:DI 0 "register_operand" "=D") 
16997         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16998                             (const_int 2))
16999                  (match_operand:DI 3 "register_operand" "0")))
17000    (set (mem:BLK (match_dup 3))
17001         (const_int 0))
17002    (use (match_operand:SI 2 "register_operand" "a"))
17003    (use (match_dup 4))
17004    (use (reg:SI DIRFLAG_REG))]
17005   "TARGET_64BIT"
17006   "{rep\;stosl|rep stosd}"
17007   [(set_attr "type" "str")
17008    (set_attr "prefix_rep" "1")
17009    (set_attr "memory" "store")
17010    (set_attr "mode" "SI")])
17011
17012 (define_insn "*rep_stosqi"
17013   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17014    (set (match_operand:SI 0 "register_operand" "=D") 
17015         (plus:SI (match_operand:SI 3 "register_operand" "0")
17016                  (match_operand:SI 4 "register_operand" "1")))
17017    (set (mem:BLK (match_dup 3))
17018         (const_int 0))
17019    (use (match_operand:QI 2 "register_operand" "a"))
17020    (use (match_dup 4))
17021    (use (reg:SI DIRFLAG_REG))]
17022   "!TARGET_64BIT"
17023   "{rep\;stosb|rep stosb}"
17024   [(set_attr "type" "str")
17025    (set_attr "prefix_rep" "1")
17026    (set_attr "memory" "store")
17027    (set_attr "mode" "QI")])
17028
17029 (define_insn "*rep_stosqi_rex64"
17030   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17031    (set (match_operand:DI 0 "register_operand" "=D") 
17032         (plus:DI (match_operand:DI 3 "register_operand" "0")
17033                  (match_operand:DI 4 "register_operand" "1")))
17034    (set (mem:BLK (match_dup 3))
17035         (const_int 0))
17036    (use (match_operand:QI 2 "register_operand" "a"))
17037    (use (match_dup 4))
17038    (use (reg:SI DIRFLAG_REG))]
17039   "TARGET_64BIT"
17040   "{rep\;stosb|rep stosb}"
17041   [(set_attr "type" "str")
17042    (set_attr "prefix_rep" "1")
17043    (set_attr "memory" "store")
17044    (set_attr "mode" "QI")])
17045
17046 (define_expand "cmpstrsi"
17047   [(set (match_operand:SI 0 "register_operand" "")
17048         (compare:SI (match_operand:BLK 1 "general_operand" "")
17049                     (match_operand:BLK 2 "general_operand" "")))
17050    (use (match_operand 3 "general_operand" ""))
17051    (use (match_operand 4 "immediate_operand" ""))]
17052   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17053 {
17054   rtx addr1, addr2, out, outlow, count, countreg, align;
17055
17056   /* Can't use this if the user has appropriated esi or edi.  */
17057   if (global_regs[4] || global_regs[5])
17058     FAIL;
17059
17060   out = operands[0];
17061   if (GET_CODE (out) != REG)
17062     out = gen_reg_rtx (SImode);
17063
17064   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17065   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17066   if (addr1 != XEXP (operands[1], 0))
17067     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17068   if (addr2 != XEXP (operands[2], 0))
17069     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17070
17071   count = operands[3];
17072   countreg = ix86_zero_extend_to_Pmode (count);
17073
17074   /* %%% Iff we are testing strict equality, we can use known alignment
17075      to good advantage.  This may be possible with combine, particularly
17076      once cc0 is dead.  */
17077   align = operands[4];
17078
17079   emit_insn (gen_cld ());
17080   if (GET_CODE (count) == CONST_INT)
17081     {
17082       if (INTVAL (count) == 0)
17083         {
17084           emit_move_insn (operands[0], const0_rtx);
17085           DONE;
17086         }
17087       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17088                                     operands[1], operands[2]));
17089     }
17090   else
17091     {
17092       if (TARGET_64BIT)
17093         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17094       else
17095         emit_insn (gen_cmpsi_1 (countreg, countreg));
17096       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17097                                  operands[1], operands[2]));
17098     }
17099
17100   outlow = gen_lowpart (QImode, out);
17101   emit_insn (gen_cmpintqi (outlow));
17102   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17103
17104   if (operands[0] != out)
17105     emit_move_insn (operands[0], out);
17106
17107   DONE;
17108 })
17109
17110 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17111
17112 (define_expand "cmpintqi"
17113   [(set (match_dup 1)
17114         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17115    (set (match_dup 2)
17116         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17117    (parallel [(set (match_operand:QI 0 "register_operand" "")
17118                    (minus:QI (match_dup 1)
17119                              (match_dup 2)))
17120               (clobber (reg:CC FLAGS_REG))])]
17121   ""
17122   "operands[1] = gen_reg_rtx (QImode);
17123    operands[2] = gen_reg_rtx (QImode);")
17124
17125 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17126 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17127
17128 (define_expand "cmpstrqi_nz_1"
17129   [(parallel [(set (reg:CC FLAGS_REG)
17130                    (compare:CC (match_operand 4 "memory_operand" "")
17131                                (match_operand 5 "memory_operand" "")))
17132               (use (match_operand 2 "register_operand" ""))
17133               (use (match_operand:SI 3 "immediate_operand" ""))
17134               (use (reg:SI DIRFLAG_REG))
17135               (clobber (match_operand 0 "register_operand" ""))
17136               (clobber (match_operand 1 "register_operand" ""))
17137               (clobber (match_dup 2))])]
17138   ""
17139   "")
17140
17141 (define_insn "*cmpstrqi_nz_1"
17142   [(set (reg:CC FLAGS_REG)
17143         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17144                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17145    (use (match_operand:SI 6 "register_operand" "2"))
17146    (use (match_operand:SI 3 "immediate_operand" "i"))
17147    (use (reg:SI DIRFLAG_REG))
17148    (clobber (match_operand:SI 0 "register_operand" "=S"))
17149    (clobber (match_operand:SI 1 "register_operand" "=D"))
17150    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17151   "!TARGET_64BIT"
17152   "repz{\;| }cmpsb"
17153   [(set_attr "type" "str")
17154    (set_attr "mode" "QI")
17155    (set_attr "prefix_rep" "1")])
17156
17157 (define_insn "*cmpstrqi_nz_rex_1"
17158   [(set (reg:CC FLAGS_REG)
17159         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17160                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17161    (use (match_operand:DI 6 "register_operand" "2"))
17162    (use (match_operand:SI 3 "immediate_operand" "i"))
17163    (use (reg:SI DIRFLAG_REG))
17164    (clobber (match_operand:DI 0 "register_operand" "=S"))
17165    (clobber (match_operand:DI 1 "register_operand" "=D"))
17166    (clobber (match_operand:DI 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 ;; The same, but the count is not known to not be zero.
17174
17175 (define_expand "cmpstrqi_1"
17176   [(parallel [(set (reg:CC FLAGS_REG)
17177                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17178                                      (const_int 0))
17179                   (compare:CC (match_operand 4 "memory_operand" "")
17180                               (match_operand 5 "memory_operand" ""))
17181                   (const_int 0)))
17182               (use (match_operand:SI 3 "immediate_operand" ""))
17183               (use (reg:CC FLAGS_REG))
17184               (use (reg:SI DIRFLAG_REG))
17185               (clobber (match_operand 0 "register_operand" ""))
17186               (clobber (match_operand 1 "register_operand" ""))
17187               (clobber (match_dup 2))])]
17188   ""
17189   "")
17190
17191 (define_insn "*cmpstrqi_1"
17192   [(set (reg:CC FLAGS_REG)
17193         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17194                              (const_int 0))
17195           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17196                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17197           (const_int 0)))
17198    (use (match_operand:SI 3 "immediate_operand" "i"))
17199    (use (reg:CC FLAGS_REG))
17200    (use (reg:SI DIRFLAG_REG))
17201    (clobber (match_operand:SI 0 "register_operand" "=S"))
17202    (clobber (match_operand:SI 1 "register_operand" "=D"))
17203    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17204   "!TARGET_64BIT"
17205   "repz{\;| }cmpsb"
17206   [(set_attr "type" "str")
17207    (set_attr "mode" "QI")
17208    (set_attr "prefix_rep" "1")])
17209
17210 (define_insn "*cmpstrqi_rex_1"
17211   [(set (reg:CC FLAGS_REG)
17212         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17213                              (const_int 0))
17214           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17215                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17216           (const_int 0)))
17217    (use (match_operand:SI 3 "immediate_operand" "i"))
17218    (use (reg:CC FLAGS_REG))
17219    (use (reg:SI DIRFLAG_REG))
17220    (clobber (match_operand:DI 0 "register_operand" "=S"))
17221    (clobber (match_operand:DI 1 "register_operand" "=D"))
17222    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17223   "TARGET_64BIT"
17224   "repz{\;| }cmpsb"
17225   [(set_attr "type" "str")
17226    (set_attr "mode" "QI")
17227    (set_attr "prefix_rep" "1")])
17228
17229 (define_expand "strlensi"
17230   [(set (match_operand:SI 0 "register_operand" "")
17231         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17232                     (match_operand:QI 2 "immediate_operand" "")
17233                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17234   ""
17235 {
17236  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17237    DONE;
17238  else
17239    FAIL;
17240 })
17241
17242 (define_expand "strlendi"
17243   [(set (match_operand:DI 0 "register_operand" "")
17244         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17245                     (match_operand:QI 2 "immediate_operand" "")
17246                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17247   ""
17248 {
17249  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17250    DONE;
17251  else
17252    FAIL;
17253 })
17254
17255 (define_expand "strlenqi_1"
17256   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17257               (use (reg:SI DIRFLAG_REG))
17258               (clobber (match_operand 1 "register_operand" ""))
17259               (clobber (reg:CC FLAGS_REG))])]
17260   ""
17261   "")
17262
17263 (define_insn "*strlenqi_1"
17264   [(set (match_operand:SI 0 "register_operand" "=&c")
17265         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17266                     (match_operand:QI 2 "register_operand" "a")
17267                     (match_operand:SI 3 "immediate_operand" "i")
17268                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17269    (use (reg:SI DIRFLAG_REG))
17270    (clobber (match_operand:SI 1 "register_operand" "=D"))
17271    (clobber (reg:CC FLAGS_REG))]
17272   "!TARGET_64BIT"
17273   "repnz{\;| }scasb"
17274   [(set_attr "type" "str")
17275    (set_attr "mode" "QI")
17276    (set_attr "prefix_rep" "1")])
17277
17278 (define_insn "*strlenqi_rex_1"
17279   [(set (match_operand:DI 0 "register_operand" "=&c")
17280         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17281                     (match_operand:QI 2 "register_operand" "a")
17282                     (match_operand:DI 3 "immediate_operand" "i")
17283                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17284    (use (reg:SI DIRFLAG_REG))
17285    (clobber (match_operand:DI 1 "register_operand" "=D"))
17286    (clobber (reg:CC FLAGS_REG))]
17287   "TARGET_64BIT"
17288   "repnz{\;| }scasb"
17289   [(set_attr "type" "str")
17290    (set_attr "mode" "QI")
17291    (set_attr "prefix_rep" "1")])
17292
17293 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17294 ;; handled in combine, but it is not currently up to the task.
17295 ;; When used for their truth value, the cmpstr* expanders generate
17296 ;; code like this:
17297 ;;
17298 ;;   repz cmpsb
17299 ;;   seta       %al
17300 ;;   setb       %dl
17301 ;;   cmpb       %al, %dl
17302 ;;   jcc        label
17303 ;;
17304 ;; The intermediate three instructions are unnecessary.
17305
17306 ;; This one handles cmpstr*_nz_1...
17307 (define_peephole2
17308   [(parallel[
17309      (set (reg:CC FLAGS_REG)
17310           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17311                       (mem:BLK (match_operand 5 "register_operand" ""))))
17312      (use (match_operand 6 "register_operand" ""))
17313      (use (match_operand:SI 3 "immediate_operand" ""))
17314      (use (reg:SI DIRFLAG_REG))
17315      (clobber (match_operand 0 "register_operand" ""))
17316      (clobber (match_operand 1 "register_operand" ""))
17317      (clobber (match_operand 2 "register_operand" ""))])
17318    (set (match_operand:QI 7 "register_operand" "")
17319         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17320    (set (match_operand:QI 8 "register_operand" "")
17321         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17322    (set (reg FLAGS_REG)
17323         (compare (match_dup 7) (match_dup 8)))
17324   ]
17325   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17326   [(parallel[
17327      (set (reg:CC FLAGS_REG)
17328           (compare:CC (mem:BLK (match_dup 4))
17329                       (mem:BLK (match_dup 5))))
17330      (use (match_dup 6))
17331      (use (match_dup 3))
17332      (use (reg:SI DIRFLAG_REG))
17333      (clobber (match_dup 0))
17334      (clobber (match_dup 1))
17335      (clobber (match_dup 2))])]
17336   "")
17337
17338 ;; ...and this one handles cmpstr*_1.
17339 (define_peephole2
17340   [(parallel[
17341      (set (reg:CC FLAGS_REG)
17342           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17343                                (const_int 0))
17344             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17345                         (mem:BLK (match_operand 5 "register_operand" "")))
17346             (const_int 0)))
17347      (use (match_operand:SI 3 "immediate_operand" ""))
17348      (use (reg:CC FLAGS_REG))
17349      (use (reg:SI DIRFLAG_REG))
17350      (clobber (match_operand 0 "register_operand" ""))
17351      (clobber (match_operand 1 "register_operand" ""))
17352      (clobber (match_operand 2 "register_operand" ""))])
17353    (set (match_operand:QI 7 "register_operand" "")
17354         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17355    (set (match_operand:QI 8 "register_operand" "")
17356         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17357    (set (reg FLAGS_REG)
17358         (compare (match_dup 7) (match_dup 8)))
17359   ]
17360   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17361   [(parallel[
17362      (set (reg:CC FLAGS_REG)
17363           (if_then_else:CC (ne (match_dup 6)
17364                                (const_int 0))
17365             (compare:CC (mem:BLK (match_dup 4))
17366                         (mem:BLK (match_dup 5)))
17367             (const_int 0)))
17368      (use (match_dup 3))
17369      (use (reg:CC FLAGS_REG))
17370      (use (reg:SI DIRFLAG_REG))
17371      (clobber (match_dup 0))
17372      (clobber (match_dup 1))
17373      (clobber (match_dup 2))])]
17374   "")
17375
17376
17377 \f
17378 ;; Conditional move instructions.
17379
17380 (define_expand "movdicc"
17381   [(set (match_operand:DI 0 "register_operand" "")
17382         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17383                          (match_operand:DI 2 "general_operand" "")
17384                          (match_operand:DI 3 "general_operand" "")))]
17385   "TARGET_64BIT"
17386   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17387
17388 (define_insn "x86_movdicc_0_m1_rex64"
17389   [(set (match_operand:DI 0 "register_operand" "=r")
17390         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17391           (const_int -1)
17392           (const_int 0)))
17393    (clobber (reg:CC FLAGS_REG))]
17394   "TARGET_64BIT"
17395   "sbb{q}\t%0, %0"
17396   ; Since we don't have the proper number of operands for an alu insn,
17397   ; fill in all the blanks.
17398   [(set_attr "type" "alu")
17399    (set_attr "pent_pair" "pu")
17400    (set_attr "memory" "none")
17401    (set_attr "imm_disp" "false")
17402    (set_attr "mode" "DI")
17403    (set_attr "length_immediate" "0")])
17404
17405 (define_insn "movdicc_c_rex64"
17406   [(set (match_operand:DI 0 "register_operand" "=r,r")
17407         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17408                                 [(reg FLAGS_REG) (const_int 0)])
17409                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17410                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17411   "TARGET_64BIT && TARGET_CMOVE
17412    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17413   "@
17414    cmov%O2%C1\t{%2, %0|%0, %2}
17415    cmov%O2%c1\t{%3, %0|%0, %3}"
17416   [(set_attr "type" "icmov")
17417    (set_attr "mode" "DI")])
17418
17419 (define_expand "movsicc"
17420   [(set (match_operand:SI 0 "register_operand" "")
17421         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17422                          (match_operand:SI 2 "general_operand" "")
17423                          (match_operand:SI 3 "general_operand" "")))]
17424   ""
17425   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17426
17427 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17428 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17429 ;; So just document what we're doing explicitly.
17430
17431 (define_insn "x86_movsicc_0_m1"
17432   [(set (match_operand:SI 0 "register_operand" "=r")
17433         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17434           (const_int -1)
17435           (const_int 0)))
17436    (clobber (reg:CC FLAGS_REG))]
17437   ""
17438   "sbb{l}\t%0, %0"
17439   ; Since we don't have the proper number of operands for an alu insn,
17440   ; fill in all the blanks.
17441   [(set_attr "type" "alu")
17442    (set_attr "pent_pair" "pu")
17443    (set_attr "memory" "none")
17444    (set_attr "imm_disp" "false")
17445    (set_attr "mode" "SI")
17446    (set_attr "length_immediate" "0")])
17447
17448 (define_insn "*movsicc_noc"
17449   [(set (match_operand:SI 0 "register_operand" "=r,r")
17450         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17451                                 [(reg FLAGS_REG) (const_int 0)])
17452                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17453                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17454   "TARGET_CMOVE
17455    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17456   "@
17457    cmov%O2%C1\t{%2, %0|%0, %2}
17458    cmov%O2%c1\t{%3, %0|%0, %3}"
17459   [(set_attr "type" "icmov")
17460    (set_attr "mode" "SI")])
17461
17462 (define_expand "movhicc"
17463   [(set (match_operand:HI 0 "register_operand" "")
17464         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17465                          (match_operand:HI 2 "general_operand" "")
17466                          (match_operand:HI 3 "general_operand" "")))]
17467   "TARGET_HIMODE_MATH"
17468   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17469
17470 (define_insn "*movhicc_noc"
17471   [(set (match_operand:HI 0 "register_operand" "=r,r")
17472         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17473                                 [(reg FLAGS_REG) (const_int 0)])
17474                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17475                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17476   "TARGET_CMOVE
17477    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17478   "@
17479    cmov%O2%C1\t{%2, %0|%0, %2}
17480    cmov%O2%c1\t{%3, %0|%0, %3}"
17481   [(set_attr "type" "icmov")
17482    (set_attr "mode" "HI")])
17483
17484 (define_expand "movqicc"
17485   [(set (match_operand:QI 0 "register_operand" "")
17486         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17487                          (match_operand:QI 2 "general_operand" "")
17488                          (match_operand:QI 3 "general_operand" "")))]
17489   "TARGET_QIMODE_MATH"
17490   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17491
17492 (define_insn_and_split "*movqicc_noc"
17493   [(set (match_operand:QI 0 "register_operand" "=r,r")
17494         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17495                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17496                       (match_operand:QI 2 "register_operand" "r,0")
17497                       (match_operand:QI 3 "register_operand" "0,r")))]
17498   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17499   "#"
17500   "&& reload_completed"
17501   [(set (match_dup 0)
17502         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17503                       (match_dup 2)
17504                       (match_dup 3)))]
17505   "operands[0] = gen_lowpart (SImode, operands[0]);
17506    operands[2] = gen_lowpart (SImode, operands[2]);
17507    operands[3] = gen_lowpart (SImode, operands[3]);"
17508   [(set_attr "type" "icmov")
17509    (set_attr "mode" "SI")])
17510
17511 (define_expand "movsfcc"
17512   [(set (match_operand:SF 0 "register_operand" "")
17513         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17514                          (match_operand:SF 2 "register_operand" "")
17515                          (match_operand:SF 3 "register_operand" "")))]
17516   "TARGET_CMOVE"
17517   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17518
17519 (define_insn "*movsfcc_1"
17520   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17521         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17522                                 [(reg FLAGS_REG) (const_int 0)])
17523                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17524                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17525   "TARGET_CMOVE
17526    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17527   "@
17528    fcmov%F1\t{%2, %0|%0, %2}
17529    fcmov%f1\t{%3, %0|%0, %3}
17530    cmov%O2%C1\t{%2, %0|%0, %2}
17531    cmov%O2%c1\t{%3, %0|%0, %3}"
17532   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17533    (set_attr "mode" "SF,SF,SI,SI")])
17534
17535 (define_expand "movdfcc"
17536   [(set (match_operand:DF 0 "register_operand" "")
17537         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17538                          (match_operand:DF 2 "register_operand" "")
17539                          (match_operand:DF 3 "register_operand" "")))]
17540   "TARGET_CMOVE"
17541   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17542
17543 (define_insn "*movdfcc_1"
17544   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17545         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17546                                 [(reg FLAGS_REG) (const_int 0)])
17547                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17548                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17549   "!TARGET_64BIT && TARGET_CMOVE
17550    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17551   "@
17552    fcmov%F1\t{%2, %0|%0, %2}
17553    fcmov%f1\t{%3, %0|%0, %3}
17554    #
17555    #"
17556   [(set_attr "type" "fcmov,fcmov,multi,multi")
17557    (set_attr "mode" "DF")])
17558
17559 (define_insn "*movdfcc_1_rex64"
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#r,rm#f,0#f")
17564                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,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    cmov%O2%C1\t{%2, %0|%0, %2}
17571    cmov%O2%c1\t{%3, %0|%0, %3}"
17572   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17573    (set_attr "mode" "DF")])
17574
17575 (define_split
17576   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17577         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17578                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17579                       (match_operand:DF 2 "nonimmediate_operand" "")
17580                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17581   "!TARGET_64BIT && reload_completed"
17582   [(set (match_dup 2)
17583         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17584                       (match_dup 5)
17585                       (match_dup 7)))
17586    (set (match_dup 3)
17587         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17588                       (match_dup 6)
17589                       (match_dup 8)))]
17590   "split_di (operands+2, 1, operands+5, operands+6);
17591    split_di (operands+3, 1, operands+7, operands+8);
17592    split_di (operands, 1, operands+2, operands+3);")
17593
17594 (define_expand "movxfcc"
17595   [(set (match_operand:XF 0 "register_operand" "")
17596         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17597                          (match_operand:XF 2 "register_operand" "")
17598                          (match_operand:XF 3 "register_operand" "")))]
17599   "TARGET_CMOVE"
17600   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17601
17602 (define_insn "*movxfcc_1"
17603   [(set (match_operand:XF 0 "register_operand" "=f,f")
17604         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17605                                 [(reg FLAGS_REG) (const_int 0)])
17606                       (match_operand:XF 2 "register_operand" "f,0")
17607                       (match_operand:XF 3 "register_operand" "0,f")))]
17608   "TARGET_CMOVE"
17609   "@
17610    fcmov%F1\t{%2, %0|%0, %2}
17611    fcmov%f1\t{%3, %0|%0, %3}"
17612   [(set_attr "type" "fcmov")
17613    (set_attr "mode" "XF")])
17614
17615 (define_expand "minsf3"
17616   [(parallel [
17617      (set (match_operand:SF 0 "register_operand" "")
17618           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17619                                (match_operand:SF 2 "nonimmediate_operand" ""))
17620                            (match_dup 1)
17621                            (match_dup 2)))
17622      (clobber (reg:CC FLAGS_REG))])]
17623   "TARGET_SSE"
17624   "")
17625
17626 (define_insn "*minsf"
17627   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17628         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17629                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17630                          (match_dup 1)
17631                          (match_dup 2)))
17632    (clobber (reg:CC FLAGS_REG))]
17633   "TARGET_SSE && TARGET_IEEE_FP"
17634   "#")
17635
17636 (define_insn "*minsf_nonieee"
17637   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17638         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17639                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17640                          (match_dup 1)
17641                          (match_dup 2)))
17642    (clobber (reg:CC FLAGS_REG))]
17643   "TARGET_SSE && !TARGET_IEEE_FP
17644    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17645   "#")
17646
17647 (define_split
17648   [(set (match_operand:SF 0 "register_operand" "")
17649         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17650                              (match_operand:SF 2 "nonimmediate_operand" ""))
17651                          (match_operand:SF 3 "register_operand" "")
17652                          (match_operand:SF 4 "nonimmediate_operand" "")))
17653    (clobber (reg:CC FLAGS_REG))]
17654   "SSE_REG_P (operands[0]) && reload_completed
17655    && ((operands_match_p (operands[1], operands[3])
17656         && operands_match_p (operands[2], operands[4]))
17657        || (operands_match_p (operands[1], operands[4])
17658            && operands_match_p (operands[2], operands[3])))"
17659   [(set (match_dup 0)
17660         (if_then_else:SF (lt (match_dup 1)
17661                              (match_dup 2))
17662                          (match_dup 1)
17663                          (match_dup 2)))])
17664
17665 ;; Conditional addition patterns
17666 (define_expand "addqicc"
17667   [(match_operand:QI 0 "register_operand" "")
17668    (match_operand 1 "comparison_operator" "")
17669    (match_operand:QI 2 "register_operand" "")
17670    (match_operand:QI 3 "const_int_operand" "")]
17671   ""
17672   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17673
17674 (define_expand "addhicc"
17675   [(match_operand:HI 0 "register_operand" "")
17676    (match_operand 1 "comparison_operator" "")
17677    (match_operand:HI 2 "register_operand" "")
17678    (match_operand:HI 3 "const_int_operand" "")]
17679   ""
17680   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17681
17682 (define_expand "addsicc"
17683   [(match_operand:SI 0 "register_operand" "")
17684    (match_operand 1 "comparison_operator" "")
17685    (match_operand:SI 2 "register_operand" "")
17686    (match_operand:SI 3 "const_int_operand" "")]
17687   ""
17688   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17689
17690 (define_expand "adddicc"
17691   [(match_operand:DI 0 "register_operand" "")
17692    (match_operand 1 "comparison_operator" "")
17693    (match_operand:DI 2 "register_operand" "")
17694    (match_operand:DI 3 "const_int_operand" "")]
17695   "TARGET_64BIT"
17696   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17697
17698 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17699
17700 (define_split
17701   [(set (match_operand:SF 0 "fp_register_operand" "")
17702         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17703                              (match_operand:SF 2 "register_operand" ""))
17704                          (match_operand:SF 3 "register_operand" "")
17705                          (match_operand:SF 4 "register_operand" "")))
17706    (clobber (reg:CC FLAGS_REG))]
17707   "reload_completed
17708    && ((operands_match_p (operands[1], operands[3])
17709         && operands_match_p (operands[2], operands[4]))
17710        || (operands_match_p (operands[1], operands[4])
17711            && operands_match_p (operands[2], operands[3])))"
17712   [(set (reg:CCFP FLAGS_REG)
17713         (compare:CCFP (match_dup 2)
17714                       (match_dup 1)))
17715    (set (match_dup 0)
17716         (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17717                          (match_dup 1)
17718                          (match_dup 2)))])
17719
17720 (define_insn "*minsf_sse"
17721   [(set (match_operand:SF 0 "register_operand" "=x")
17722         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17723                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17724                          (match_dup 1)
17725                          (match_dup 2)))]
17726   "TARGET_SSE && reload_completed"
17727   "minss\t{%2, %0|%0, %2}"
17728   [(set_attr "type" "sse")
17729    (set_attr "mode" "SF")])
17730
17731 (define_expand "mindf3"
17732   [(parallel [
17733      (set (match_operand:DF 0 "register_operand" "")
17734           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17735                                (match_operand:DF 2 "nonimmediate_operand" ""))
17736                            (match_dup 1)
17737                            (match_dup 2)))
17738      (clobber (reg:CC FLAGS_REG))])]
17739   "TARGET_SSE2 && TARGET_SSE_MATH"
17740   "#")
17741
17742 (define_insn "*mindf"
17743   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17744         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17745                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17746                          (match_dup 1)
17747                          (match_dup 2)))
17748    (clobber (reg:CC FLAGS_REG))]
17749   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17750   "#")
17751
17752 (define_insn "*mindf_nonieee"
17753   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17754         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17755                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17756                          (match_dup 1)
17757                          (match_dup 2)))
17758    (clobber (reg:CC FLAGS_REG))]
17759   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17760    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17761   "#")
17762
17763 (define_split
17764   [(set (match_operand:DF 0 "register_operand" "")
17765         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17766                              (match_operand:DF 2 "nonimmediate_operand" ""))
17767                          (match_operand:DF 3 "register_operand" "")
17768                          (match_operand:DF 4 "nonimmediate_operand" "")))
17769    (clobber (reg:CC FLAGS_REG))]
17770   "SSE_REG_P (operands[0]) && reload_completed
17771    && ((operands_match_p (operands[1], operands[3])
17772         && operands_match_p (operands[2], operands[4]))
17773        || (operands_match_p (operands[1], operands[4])
17774            && operands_match_p (operands[2], operands[3])))"
17775   [(set (match_dup 0)
17776         (if_then_else:DF (lt (match_dup 1)
17777                              (match_dup 2))
17778                          (match_dup 1)
17779                          (match_dup 2)))])
17780
17781 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17782 (define_split
17783   [(set (match_operand:DF 0 "fp_register_operand" "")
17784         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17785                              (match_operand:DF 2 "register_operand" ""))
17786                          (match_operand:DF 3 "register_operand" "")
17787                          (match_operand:DF 4 "register_operand" "")))
17788    (clobber (reg:CC FLAGS_REG))]
17789   "reload_completed
17790    && ((operands_match_p (operands[1], operands[3])
17791         && operands_match_p (operands[2], operands[4]))
17792        || (operands_match_p (operands[1], operands[4])
17793            && operands_match_p (operands[2], operands[3])))"
17794   [(set (reg:CCFP FLAGS_REG)
17795         (compare:CCFP (match_dup 2)
17796                       (match_dup 1)))
17797    (set (match_dup 0)
17798         (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17799                          (match_dup 1)
17800                          (match_dup 2)))])
17801
17802 (define_insn "*mindf_sse"
17803   [(set (match_operand:DF 0 "register_operand" "=Y")
17804         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17805                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17806                          (match_dup 1)
17807                          (match_dup 2)))]
17808   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17809   "minsd\t{%2, %0|%0, %2}"
17810   [(set_attr "type" "sse")
17811    (set_attr "mode" "DF")])
17812
17813 (define_expand "maxsf3"
17814   [(parallel [
17815      (set (match_operand:SF 0 "register_operand" "")
17816           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17817                                (match_operand:SF 2 "nonimmediate_operand" ""))
17818                            (match_dup 1)
17819                            (match_dup 2)))
17820      (clobber (reg:CC FLAGS_REG))])]
17821   "TARGET_SSE"
17822   "#")
17823
17824 (define_insn "*maxsf"
17825   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17826         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17827                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17828                          (match_dup 1)
17829                          (match_dup 2)))
17830    (clobber (reg:CC FLAGS_REG))]
17831   "TARGET_SSE && TARGET_IEEE_FP"
17832   "#")
17833
17834 (define_insn "*maxsf_nonieee"
17835   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17836         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17837                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17838                          (match_dup 1)
17839                          (match_dup 2)))
17840    (clobber (reg:CC FLAGS_REG))]
17841   "TARGET_SSE && !TARGET_IEEE_FP
17842    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17843   "#")
17844
17845 (define_split
17846   [(set (match_operand:SF 0 "register_operand" "")
17847         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17848                              (match_operand:SF 2 "nonimmediate_operand" ""))
17849                          (match_operand:SF 3 "register_operand" "")
17850                          (match_operand:SF 4 "nonimmediate_operand" "")))
17851    (clobber (reg:CC FLAGS_REG))]
17852   "SSE_REG_P (operands[0]) && reload_completed
17853    && ((operands_match_p (operands[1], operands[3])
17854         && operands_match_p (operands[2], operands[4]))
17855        || (operands_match_p (operands[1], operands[4])
17856            && operands_match_p (operands[2], operands[3])))"
17857   [(set (match_dup 0)
17858         (if_then_else:SF (gt (match_dup 1)
17859                              (match_dup 2))
17860                          (match_dup 1)
17861                          (match_dup 2)))])
17862
17863 (define_split
17864   [(set (match_operand:SF 0 "fp_register_operand" "")
17865         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17866                              (match_operand:SF 2 "register_operand" ""))
17867                          (match_operand:SF 3 "register_operand" "")
17868                          (match_operand:SF 4 "register_operand" "")))
17869    (clobber (reg:CC FLAGS_REG))]
17870   "reload_completed
17871    && ((operands_match_p (operands[1], operands[3])
17872         && operands_match_p (operands[2], operands[4]))
17873        || (operands_match_p (operands[1], operands[4])
17874            && operands_match_p (operands[2], operands[3])))"
17875   [(set (reg:CCFP FLAGS_REG)
17876         (compare:CCFP (match_dup 1)
17877                       (match_dup 2)))
17878    (set (match_dup 0)
17879         (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17880                          (match_dup 1)
17881                          (match_dup 2)))])
17882
17883 (define_insn "*maxsf_sse"
17884   [(set (match_operand:SF 0 "register_operand" "=x")
17885         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17886                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17887                          (match_dup 1)
17888                          (match_dup 2)))]
17889   "TARGET_SSE && reload_completed"
17890   "maxss\t{%2, %0|%0, %2}"
17891   [(set_attr "type" "sse")
17892    (set_attr "mode" "SF")])
17893
17894 (define_expand "maxdf3"
17895   [(parallel [
17896      (set (match_operand:DF 0 "register_operand" "")
17897           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17898                                (match_operand:DF 2 "nonimmediate_operand" ""))
17899                            (match_dup 1)
17900                            (match_dup 2)))
17901      (clobber (reg:CC FLAGS_REG))])]
17902   "TARGET_SSE2 && TARGET_SSE_MATH"
17903   "#")
17904
17905 (define_insn "*maxdf"
17906   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17907         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17908                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17909                          (match_dup 1)
17910                          (match_dup 2)))
17911    (clobber (reg:CC FLAGS_REG))]
17912   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17913   "#")
17914
17915 (define_insn "*maxdf_nonieee"
17916   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17917         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17918                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17919                          (match_dup 1)
17920                          (match_dup 2)))
17921    (clobber (reg:CC FLAGS_REG))]
17922   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17923    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17924   "#")
17925
17926 (define_split
17927   [(set (match_operand:DF 0 "register_operand" "")
17928         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17929                              (match_operand:DF 2 "nonimmediate_operand" ""))
17930                          (match_operand:DF 3 "register_operand" "")
17931                          (match_operand:DF 4 "nonimmediate_operand" "")))
17932    (clobber (reg:CC FLAGS_REG))]
17933   "SSE_REG_P (operands[0]) && reload_completed
17934    && ((operands_match_p (operands[1], operands[3])
17935         && operands_match_p (operands[2], operands[4]))
17936        || (operands_match_p (operands[1], operands[4])
17937            && operands_match_p (operands[2], operands[3])))"
17938   [(set (match_dup 0)
17939         (if_then_else:DF (gt (match_dup 1)
17940                              (match_dup 2))
17941                          (match_dup 1)
17942                          (match_dup 2)))])
17943
17944 (define_split
17945   [(set (match_operand:DF 0 "fp_register_operand" "")
17946         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17947                              (match_operand:DF 2 "register_operand" ""))
17948                          (match_operand:DF 3 "register_operand" "")
17949                          (match_operand:DF 4 "register_operand" "")))
17950    (clobber (reg:CC FLAGS_REG))]
17951   "reload_completed
17952    && ((operands_match_p (operands[1], operands[3])
17953         && operands_match_p (operands[2], operands[4]))
17954        || (operands_match_p (operands[1], operands[4])
17955            && operands_match_p (operands[2], operands[3])))"
17956   [(set (reg:CCFP FLAGS_REG)
17957         (compare:CCFP (match_dup 1)
17958                       (match_dup 2)))
17959    (set (match_dup 0)
17960         (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17961                          (match_dup 1)
17962                          (match_dup 2)))])
17963
17964 (define_insn "*maxdf_sse"
17965   [(set (match_operand:DF 0 "register_operand" "=Y")
17966         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17967                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17968                          (match_dup 1)
17969                          (match_dup 2)))]
17970   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17971   "maxsd\t{%2, %0|%0, %2}"
17972   [(set_attr "type" "sse")
17973    (set_attr "mode" "DF")])
17974 \f
17975 ;; Misc patterns (?)
17976
17977 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17978 ;; Otherwise there will be nothing to keep
17979 ;; 
17980 ;; [(set (reg ebp) (reg esp))]
17981 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17982 ;;  (clobber (eflags)]
17983 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17984 ;;
17985 ;; in proper program order.
17986 (define_insn "pro_epilogue_adjust_stack_1"
17987   [(set (match_operand:SI 0 "register_operand" "=r,r")
17988         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17989                  (match_operand:SI 2 "immediate_operand" "i,i")))
17990    (clobber (reg:CC FLAGS_REG))
17991    (clobber (mem:BLK (scratch)))]
17992   "!TARGET_64BIT"
17993 {
17994   switch (get_attr_type (insn))
17995     {
17996     case TYPE_IMOV:
17997       return "mov{l}\t{%1, %0|%0, %1}";
17998
17999     case TYPE_ALU:
18000       if (GET_CODE (operands[2]) == CONST_INT
18001           && (INTVAL (operands[2]) == 128
18002               || (INTVAL (operands[2]) < 0
18003                   && INTVAL (operands[2]) != -128)))
18004         {
18005           operands[2] = GEN_INT (-INTVAL (operands[2]));
18006           return "sub{l}\t{%2, %0|%0, %2}";
18007         }
18008       return "add{l}\t{%2, %0|%0, %2}";
18009
18010     case TYPE_LEA:
18011       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18012       return "lea{l}\t{%a2, %0|%0, %a2}";
18013
18014     default:
18015       abort ();
18016     }
18017 }
18018   [(set (attr "type")
18019         (cond [(eq_attr "alternative" "0")
18020                  (const_string "alu")
18021                (match_operand:SI 2 "const0_operand" "")
18022                  (const_string "imov")
18023               ]
18024               (const_string "lea")))
18025    (set_attr "mode" "SI")])
18026
18027 (define_insn "pro_epilogue_adjust_stack_rex64"
18028   [(set (match_operand:DI 0 "register_operand" "=r,r")
18029         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18030                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18031    (clobber (reg:CC FLAGS_REG))
18032    (clobber (mem:BLK (scratch)))]
18033   "TARGET_64BIT"
18034 {
18035   switch (get_attr_type (insn))
18036     {
18037     case TYPE_IMOV:
18038       return "mov{q}\t{%1, %0|%0, %1}";
18039
18040     case TYPE_ALU:
18041       if (GET_CODE (operands[2]) == CONST_INT
18042           /* Avoid overflows.  */
18043           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18044           && (INTVAL (operands[2]) == 128
18045               || (INTVAL (operands[2]) < 0
18046                   && INTVAL (operands[2]) != -128)))
18047         {
18048           operands[2] = GEN_INT (-INTVAL (operands[2]));
18049           return "sub{q}\t{%2, %0|%0, %2}";
18050         }
18051       return "add{q}\t{%2, %0|%0, %2}";
18052
18053     case TYPE_LEA:
18054       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18055       return "lea{q}\t{%a2, %0|%0, %a2}";
18056
18057     default:
18058       abort ();
18059     }
18060 }
18061   [(set (attr "type")
18062         (cond [(eq_attr "alternative" "0")
18063                  (const_string "alu")
18064                (match_operand:DI 2 "const0_operand" "")
18065                  (const_string "imov")
18066               ]
18067               (const_string "lea")))
18068    (set_attr "mode" "DI")])
18069
18070 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18071   [(set (match_operand:DI 0 "register_operand" "=r,r")
18072         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18073                  (match_operand:DI 3 "immediate_operand" "i,i")))
18074    (use (match_operand:DI 2 "register_operand" "r,r"))
18075    (clobber (reg:CC FLAGS_REG))
18076    (clobber (mem:BLK (scratch)))]
18077   "TARGET_64BIT"
18078 {
18079   switch (get_attr_type (insn))
18080     {
18081     case TYPE_ALU:
18082       return "add{q}\t{%2, %0|%0, %2}";
18083
18084     case TYPE_LEA:
18085       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18086       return "lea{q}\t{%a2, %0|%0, %a2}";
18087
18088     default:
18089       abort ();
18090     }
18091 }
18092   [(set_attr "type" "alu,lea")
18093    (set_attr "mode" "DI")])
18094
18095 ;; Placeholder for the conditional moves.  This one is split either to SSE
18096 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
18097 ;; fact is that compares supported by the cmp??ss instructions are exactly
18098 ;; swapped of those supported by cmove sequence.
18099 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18100 ;; supported by i387 comparisons and we do need to emit two conditional moves
18101 ;; in tandem.
18102
18103 (define_insn "sse_movsfcc"
18104   [(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")
18105         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18106                         [(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")
18107                          (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")])
18108                       (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")
18109                       (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")))
18110    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18111    (clobber (reg:CC FLAGS_REG))]
18112   "TARGET_SSE
18113    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18114    /* Avoid combine from being smart and converting min/max
18115       instruction patterns into conditional moves.  */
18116    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18117         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18118        || !rtx_equal_p (operands[4], operands[2])
18119        || !rtx_equal_p (operands[5], operands[3]))
18120    && (!TARGET_IEEE_FP
18121        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18122   "#")
18123
18124 (define_insn "sse_movsfcc_eq"
18125   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18126         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18127                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18128                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18129                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18130    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18131    (clobber (reg:CC FLAGS_REG))]
18132   "TARGET_SSE
18133    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18134   "#")
18135
18136 (define_insn "sse_movdfcc"
18137   [(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")
18138         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18139                         [(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")
18140                          (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")])
18141                       (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")
18142                       (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")))
18143    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18144    (clobber (reg:CC FLAGS_REG))]
18145   "TARGET_SSE2
18146    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18147    /* Avoid combine from being smart and converting min/max
18148       instruction patterns into conditional moves.  */
18149    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18150         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18151        || !rtx_equal_p (operands[4], operands[2])
18152        || !rtx_equal_p (operands[5], operands[3]))
18153    && (!TARGET_IEEE_FP
18154        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18155   "#")
18156
18157 (define_insn "sse_movdfcc_eq"
18158   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18159         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18160                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18161                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18162                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18163    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18164    (clobber (reg:CC FLAGS_REG))]
18165   "TARGET_SSE
18166    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18167   "#")
18168
18169 ;; For non-sse moves just expand the usual cmove sequence.
18170 (define_split
18171   [(set (match_operand 0 "register_operand" "")
18172         (if_then_else (match_operator 1 "comparison_operator"
18173                         [(match_operand 4 "nonimmediate_operand" "")
18174                          (match_operand 5 "register_operand" "")])
18175                       (match_operand 2 "nonimmediate_operand" "")
18176                       (match_operand 3 "nonimmediate_operand" "")))
18177    (clobber (match_operand 6 "" ""))
18178    (clobber (reg:CC FLAGS_REG))]
18179   "!SSE_REG_P (operands[0]) && reload_completed
18180    && (GET_MODE (operands[0]) == SFmode
18181        || (TARGET_SSE2 && GET_MODE (operands[0]) == DFmode))"
18182   [(const_int 0)]
18183 {
18184    ix86_compare_op0 = operands[5];
18185    ix86_compare_op1 = operands[4];
18186    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18187                                  VOIDmode, operands[5], operands[4]);
18188    ix86_expand_fp_movcc (operands);
18189    DONE;
18190 })
18191
18192 ;; Split SSE based conditional move into sequence:
18193 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
18194 ;; and   op2, op0   -  zero op2 if comparison was false
18195 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
18196 ;; or    op2, op0   -  get the nonzero one into the result.
18197 (define_split
18198   [(set (match_operand:SF 0 "register_operand" "")
18199         (if_then_else:SF (match_operator:SF 1 "sse_comparison_operator"
18200                            [(match_operand:SF 4 "register_operand" "")
18201                             (match_operand:SF 5 "nonimmediate_operand" "")])
18202                          (match_operand:SF 2 "register_operand" "")
18203                          (match_operand:SF 3 "register_operand" "")))
18204    (clobber (match_operand 6 "" ""))
18205    (clobber (reg:CC FLAGS_REG))]
18206   "SSE_REG_P (operands[0]) && reload_completed"
18207   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18208    (set (match_dup 2) (and:V4SF (match_dup 2)
18209                                 (match_dup 8)))
18210    (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18211                                           (match_dup 3)))
18212    (set (match_dup 0) (ior:V4SF (match_dup 6)
18213                                 (match_dup 7)))]
18214 {
18215   /* If op2 == op3, op3 would be clobbered before it is used.  */
18216   if (operands_match_p (operands[2], operands[3]))
18217     {
18218       emit_move_insn (operands[0], operands[2]);
18219       DONE;
18220     }
18221
18222   PUT_MODE (operands[1], GET_MODE (operands[0]));
18223   if (operands_match_p (operands[0], operands[4]))
18224     operands[6] = operands[4], operands[7] = operands[2];
18225   else
18226     operands[6] = operands[2], operands[7] = operands[4];
18227   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18228   operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18229   operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18230   operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18231   operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18232   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18233 })
18234
18235 (define_split
18236   [(set (match_operand:DF 0 "register_operand" "")
18237         (if_then_else:DF (match_operator:DF 1 "sse_comparison_operator"
18238                            [(match_operand:DF 4 "register_operand" "")
18239                             (match_operand:DF 5 "nonimmediate_operand" "")])
18240                          (match_operand:DF 2 "register_operand" "")
18241                          (match_operand:DF 3 "register_operand" "")))
18242    (clobber (match_operand 6 "" ""))
18243    (clobber (reg:CC FLAGS_REG))]
18244   "SSE_REG_P (operands[0]) && reload_completed"
18245   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18246    (set (match_dup 2) (and:V2DF (match_dup 2)
18247                                 (match_dup 8)))
18248    (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18249                                           (match_dup 3)))
18250    (set (match_dup 0) (ior:V2DF (match_dup 6)
18251                                 (match_dup 7)))]
18252 {
18253   if (TARGET_SSE_SPLIT_REGS && !optimize_size)
18254     {
18255       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18256       emit_insn (gen_sse2_unpcklpd (op, op, op));
18257       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18258       emit_insn (gen_sse2_unpcklpd (op, op, op));
18259     }
18260
18261   /* If op2 == op3, op3 would be clobbered before it is used.  */
18262   if (operands_match_p (operands[2], operands[3]))
18263     {
18264       emit_move_insn (operands[0], operands[2]);
18265       DONE;
18266     }
18267
18268   PUT_MODE (operands[1], GET_MODE (operands[0]));
18269   if (operands_match_p (operands[0], operands[4]))
18270     operands[6] = operands[4], operands[7] = operands[2];
18271   else
18272     operands[6] = operands[2], operands[7] = operands[4];
18273   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18274   operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18275   operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18276   operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18277   operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18278   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18279 })
18280
18281 ;; Special case of conditional move we can handle effectively.
18282 ;; Do not brother with the integer/floating point case, since these are
18283 ;; bot considerably slower, unlike in the generic case.
18284 (define_insn "*sse_movsfcc_const0_1"
18285   [(set (match_operand:SF 0 "register_operand" "=&x")
18286         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18287                         [(match_operand:SF 4 "register_operand" "0")
18288                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18289                       (match_operand:SF 2 "register_operand" "x")
18290                       (match_operand:SF 3 "const0_operand" "X")))]
18291   "TARGET_SSE"
18292   "#")
18293
18294 (define_insn "*sse_movsfcc_const0_2"
18295   [(set (match_operand:SF 0 "register_operand" "=&x")
18296         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18297                         [(match_operand:SF 4 "register_operand" "0")
18298                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18299                       (match_operand:SF 2 "const0_operand" "X")
18300                       (match_operand:SF 3 "register_operand" "x")))]
18301   "TARGET_SSE"
18302   "#")
18303
18304 (define_insn "*sse_movsfcc_const0_3"
18305   [(set (match_operand:SF 0 "register_operand" "=&x")
18306         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18307                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18308                          (match_operand:SF 5 "register_operand" "0")])
18309                       (match_operand:SF 2 "register_operand" "x")
18310                       (match_operand:SF 3 "const0_operand" "X")))]
18311   "TARGET_SSE"
18312   "#")
18313
18314 (define_insn "*sse_movsfcc_const0_4"
18315   [(set (match_operand:SF 0 "register_operand" "=&x")
18316         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18317                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18318                          (match_operand:SF 5 "register_operand" "0")])
18319                       (match_operand:SF 2 "const0_operand" "X")
18320                       (match_operand:SF 3 "register_operand" "x")))]
18321   "TARGET_SSE"
18322   "#")
18323
18324 (define_insn "*sse_movdfcc_const0_1"
18325   [(set (match_operand:DF 0 "register_operand" "=&Y")
18326         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18327                         [(match_operand:DF 4 "register_operand" "0")
18328                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18329                       (match_operand:DF 2 "register_operand" "Y")
18330                       (match_operand:DF 3 "const0_operand" "X")))]
18331   "TARGET_SSE2"
18332   "#")
18333
18334 (define_insn "*sse_movdfcc_const0_2"
18335   [(set (match_operand:DF 0 "register_operand" "=&Y")
18336         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18337                         [(match_operand:DF 4 "register_operand" "0")
18338                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18339                       (match_operand:DF 2 "const0_operand" "X")
18340                       (match_operand:DF 3 "register_operand" "Y")))]
18341   "TARGET_SSE2"
18342   "#")
18343
18344 (define_insn "*sse_movdfcc_const0_3"
18345   [(set (match_operand:DF 0 "register_operand" "=&Y")
18346         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18347                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18348                          (match_operand:DF 5 "register_operand" "0")])
18349                       (match_operand:DF 2 "register_operand" "Y")
18350                       (match_operand:DF 3 "const0_operand" "X")))]
18351   "TARGET_SSE2"
18352   "#")
18353
18354 (define_insn "*sse_movdfcc_const0_4"
18355   [(set (match_operand:DF 0 "register_operand" "=&Y")
18356         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18357                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18358                          (match_operand:DF 5 "register_operand" "0")])
18359                       (match_operand:DF 2 "const0_operand" "X")
18360                       (match_operand:DF 3 "register_operand" "Y")))]
18361   "TARGET_SSE2"
18362   "#")
18363
18364 (define_split
18365   [(set (match_operand:SF 0 "register_operand" "")
18366         (if_then_else:SF (match_operator 1 "comparison_operator"
18367                            [(match_operand:SF 4 "nonimmediate_operand" "")
18368                             (match_operand:SF 5 "nonimmediate_operand" "")])
18369                          (match_operand:SF 2 "nonmemory_operand" "")
18370                          (match_operand:SF 3 "nonmemory_operand" "")))]
18371   "SSE_REG_P (operands[0]) && reload_completed
18372    && (const0_operand (operands[2], GET_MODE (operands[0]))
18373        || const0_operand (operands[3], GET_MODE (operands[0])))"
18374   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18375    (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18376 {
18377   PUT_MODE (operands[1], GET_MODE (operands[0]));
18378   if (!sse_comparison_operator (operands[1], VOIDmode)
18379       || !rtx_equal_p (operands[0], operands[4]))
18380     {
18381       rtx tmp = operands[5];
18382       operands[5] = operands[4];
18383       operands[4] = tmp;
18384       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18385     }
18386   if (!rtx_equal_p (operands[0], operands[4]))
18387     abort ();
18388   operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18389   if (const0_operand (operands[2], GET_MODE (operands[2])))
18390     {
18391       operands[7] = operands[3];
18392       operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18393     }
18394   else
18395     {
18396       operands[7] = operands[2];
18397       operands[6] = operands[8];
18398     }
18399   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18400 })
18401
18402 (define_split
18403   [(set (match_operand:DF 0 "register_operand" "")
18404         (if_then_else:DF (match_operator 1 "comparison_operator"
18405                            [(match_operand:DF 4 "nonimmediate_operand" "")
18406                             (match_operand:DF 5 "nonimmediate_operand" "")])
18407                          (match_operand:DF 2 "nonmemory_operand" "")
18408                          (match_operand:DF 3 "nonmemory_operand" "")))]
18409   "SSE_REG_P (operands[0]) && reload_completed
18410    && (const0_operand (operands[2], GET_MODE (operands[0]))
18411        || const0_operand (operands[3], GET_MODE (operands[0])))"
18412   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18413    (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18414 {
18415   if (TARGET_SSE_SPLIT_REGS && !optimize_size)
18416     {
18417       if (REG_P (operands[2]))
18418         {
18419           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18420           emit_insn (gen_sse2_unpcklpd (op, op, op));
18421         }
18422       if (REG_P (operands[3]))
18423         {
18424           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18425           emit_insn (gen_sse2_unpcklpd (op, op, op));
18426         }
18427     }
18428   PUT_MODE (operands[1], GET_MODE (operands[0]));
18429   if (!sse_comparison_operator (operands[1], VOIDmode)
18430       || !rtx_equal_p (operands[0], operands[4]))
18431     {
18432       rtx tmp = operands[5];
18433       operands[5] = operands[4];
18434       operands[4] = tmp;
18435       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18436     }
18437   if (!rtx_equal_p (operands[0], operands[4]))
18438     abort ();
18439   operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18440   if (const0_operand (operands[2], GET_MODE (operands[2])))
18441     {
18442       operands[7] = operands[3];
18443       operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18444     }
18445   else
18446     {
18447       operands[7] = operands[2];
18448       operands[6] = operands[8];
18449     }
18450   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18451 })
18452
18453 (define_expand "allocate_stack_worker"
18454   [(match_operand:SI 0 "register_operand" "")]
18455   "TARGET_STACK_PROBE"
18456 {
18457   if (reload_completed)
18458     {
18459       if (TARGET_64BIT)
18460         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18461       else
18462         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18463     }
18464   else
18465     {
18466       if (TARGET_64BIT)
18467         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18468       else
18469         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18470     }
18471   DONE;
18472 })
18473
18474 (define_insn "allocate_stack_worker_1"
18475   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18476     UNSPECV_STACK_PROBE)
18477    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18478    (clobber (match_scratch:SI 1 "=0"))
18479    (clobber (reg:CC FLAGS_REG))]
18480   "!TARGET_64BIT && TARGET_STACK_PROBE"
18481   "call\t__alloca"
18482   [(set_attr "type" "multi")
18483    (set_attr "length" "5")])
18484
18485 (define_expand "allocate_stack_worker_postreload"
18486   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18487                                     UNSPECV_STACK_PROBE)
18488               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18489               (clobber (match_dup 0))
18490               (clobber (reg:CC FLAGS_REG))])]
18491   ""
18492   "")
18493
18494 (define_insn "allocate_stack_worker_rex64"
18495   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18496     UNSPECV_STACK_PROBE)
18497    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18498    (clobber (match_scratch:DI 1 "=0"))
18499    (clobber (reg:CC FLAGS_REG))]
18500   "TARGET_64BIT && TARGET_STACK_PROBE"
18501   "call\t__alloca"
18502   [(set_attr "type" "multi")
18503    (set_attr "length" "5")])
18504
18505 (define_expand "allocate_stack_worker_rex64_postreload"
18506   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18507                                     UNSPECV_STACK_PROBE)
18508               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18509               (clobber (match_dup 0))
18510               (clobber (reg:CC FLAGS_REG))])]
18511   ""
18512   "")
18513
18514 (define_expand "allocate_stack"
18515   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18516                    (minus:SI (reg:SI SP_REG)
18517                              (match_operand:SI 1 "general_operand" "")))
18518               (clobber (reg:CC FLAGS_REG))])
18519    (parallel [(set (reg:SI SP_REG)
18520                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18521               (clobber (reg:CC FLAGS_REG))])]
18522   "TARGET_STACK_PROBE"
18523 {
18524 #ifdef CHECK_STACK_LIMIT
18525   if (GET_CODE (operands[1]) == CONST_INT
18526       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18527     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18528                            operands[1]));
18529   else 
18530 #endif
18531     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18532                                                             operands[1])));
18533
18534   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18535   DONE;
18536 })
18537
18538 (define_expand "builtin_setjmp_receiver"
18539   [(label_ref (match_operand 0 "" ""))]
18540   "!TARGET_64BIT && flag_pic"
18541 {
18542   emit_insn (gen_set_got (pic_offset_table_rtx));
18543   DONE;
18544 })
18545 \f
18546 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18547
18548 (define_split
18549   [(set (match_operand 0 "register_operand" "")
18550         (match_operator 3 "promotable_binary_operator"
18551            [(match_operand 1 "register_operand" "")
18552             (match_operand 2 "aligned_operand" "")]))
18553    (clobber (reg:CC FLAGS_REG))]
18554   "! TARGET_PARTIAL_REG_STALL && reload_completed
18555    && ((GET_MODE (operands[0]) == HImode 
18556         && ((!optimize_size && !TARGET_FAST_PREFIX)
18557             || GET_CODE (operands[2]) != CONST_INT
18558             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18559        || (GET_MODE (operands[0]) == QImode 
18560            && (TARGET_PROMOTE_QImode || optimize_size)))"
18561   [(parallel [(set (match_dup 0)
18562                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18563               (clobber (reg:CC FLAGS_REG))])]
18564   "operands[0] = gen_lowpart (SImode, operands[0]);
18565    operands[1] = gen_lowpart (SImode, operands[1]);
18566    if (GET_CODE (operands[3]) != ASHIFT)
18567      operands[2] = gen_lowpart (SImode, operands[2]);
18568    PUT_MODE (operands[3], SImode);")
18569
18570 ; Promote the QImode tests, as i386 has encoding of the AND
18571 ; instruction with 32-bit sign-extended immediate and thus the
18572 ; instruction size is unchanged, except in the %eax case for
18573 ; which it is increased by one byte, hence the ! optimize_size.
18574 (define_split
18575   [(set (match_operand 0 "flags_reg_operand" "")
18576         (match_operator 2 "compare_operator"
18577           [(and (match_operand 3 "aligned_operand" "")
18578                 (match_operand 4 "const_int_operand" ""))
18579            (const_int 0)]))
18580    (set (match_operand 1 "register_operand" "")
18581         (and (match_dup 3) (match_dup 4)))]
18582   "! TARGET_PARTIAL_REG_STALL && reload_completed
18583    /* Ensure that the operand will remain sign-extended immediate.  */
18584    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18585    && ! optimize_size
18586    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18587        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18588   [(parallel [(set (match_dup 0)
18589                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18590                                     (const_int 0)]))
18591               (set (match_dup 1)
18592                    (and:SI (match_dup 3) (match_dup 4)))])]
18593 {
18594   operands[4]
18595     = gen_int_mode (INTVAL (operands[4])
18596                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18597   operands[1] = gen_lowpart (SImode, operands[1]);
18598   operands[3] = gen_lowpart (SImode, operands[3]);
18599 })
18600
18601 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18602 ; the TEST instruction with 32-bit sign-extended immediate and thus
18603 ; the instruction size would at least double, which is not what we
18604 ; want even with ! optimize_size.
18605 (define_split
18606   [(set (match_operand 0 "flags_reg_operand" "")
18607         (match_operator 1 "compare_operator"
18608           [(and (match_operand:HI 2 "aligned_operand" "")
18609                 (match_operand:HI 3 "const_int_operand" ""))
18610            (const_int 0)]))]
18611   "! TARGET_PARTIAL_REG_STALL && reload_completed
18612    /* Ensure that the operand will remain sign-extended immediate.  */
18613    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18614    && ! TARGET_FAST_PREFIX
18615    && ! optimize_size"
18616   [(set (match_dup 0)
18617         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18618                          (const_int 0)]))]
18619 {
18620   operands[3]
18621     = gen_int_mode (INTVAL (operands[3])
18622                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18623   operands[2] = gen_lowpart (SImode, operands[2]);
18624 })
18625
18626 (define_split
18627   [(set (match_operand 0 "register_operand" "")
18628         (neg (match_operand 1 "register_operand" "")))
18629    (clobber (reg:CC FLAGS_REG))]
18630   "! TARGET_PARTIAL_REG_STALL && reload_completed
18631    && (GET_MODE (operands[0]) == HImode
18632        || (GET_MODE (operands[0]) == QImode 
18633            && (TARGET_PROMOTE_QImode || optimize_size)))"
18634   [(parallel [(set (match_dup 0)
18635                    (neg:SI (match_dup 1)))
18636               (clobber (reg:CC FLAGS_REG))])]
18637   "operands[0] = gen_lowpart (SImode, operands[0]);
18638    operands[1] = gen_lowpart (SImode, operands[1]);")
18639
18640 (define_split
18641   [(set (match_operand 0 "register_operand" "")
18642         (not (match_operand 1 "register_operand" "")))]
18643   "! TARGET_PARTIAL_REG_STALL && reload_completed
18644    && (GET_MODE (operands[0]) == HImode
18645        || (GET_MODE (operands[0]) == QImode 
18646            && (TARGET_PROMOTE_QImode || optimize_size)))"
18647   [(set (match_dup 0)
18648         (not:SI (match_dup 1)))]
18649   "operands[0] = gen_lowpart (SImode, operands[0]);
18650    operands[1] = gen_lowpart (SImode, operands[1]);")
18651
18652 (define_split 
18653   [(set (match_operand 0 "register_operand" "")
18654         (if_then_else (match_operator 1 "comparison_operator" 
18655                                 [(reg FLAGS_REG) (const_int 0)])
18656                       (match_operand 2 "register_operand" "")
18657                       (match_operand 3 "register_operand" "")))]
18658   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18659    && (GET_MODE (operands[0]) == HImode
18660        || (GET_MODE (operands[0]) == QImode 
18661            && (TARGET_PROMOTE_QImode || optimize_size)))"
18662   [(set (match_dup 0)
18663         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18664   "operands[0] = gen_lowpart (SImode, operands[0]);
18665    operands[2] = gen_lowpart (SImode, operands[2]);
18666    operands[3] = gen_lowpart (SImode, operands[3]);")
18667                         
18668 \f
18669 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18670 ;; transform a complex memory operation into two memory to register operations.
18671
18672 ;; Don't push memory operands
18673 (define_peephole2
18674   [(set (match_operand:SI 0 "push_operand" "")
18675         (match_operand:SI 1 "memory_operand" ""))
18676    (match_scratch:SI 2 "r")]
18677   "! optimize_size && ! TARGET_PUSH_MEMORY"
18678   [(set (match_dup 2) (match_dup 1))
18679    (set (match_dup 0) (match_dup 2))]
18680   "")
18681
18682 (define_peephole2
18683   [(set (match_operand:DI 0 "push_operand" "")
18684         (match_operand:DI 1 "memory_operand" ""))
18685    (match_scratch:DI 2 "r")]
18686   "! optimize_size && ! TARGET_PUSH_MEMORY"
18687   [(set (match_dup 2) (match_dup 1))
18688    (set (match_dup 0) (match_dup 2))]
18689   "")
18690
18691 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18692 ;; SImode pushes.
18693 (define_peephole2
18694   [(set (match_operand:SF 0 "push_operand" "")
18695         (match_operand:SF 1 "memory_operand" ""))
18696    (match_scratch:SF 2 "r")]
18697   "! optimize_size && ! TARGET_PUSH_MEMORY"
18698   [(set (match_dup 2) (match_dup 1))
18699    (set (match_dup 0) (match_dup 2))]
18700   "")
18701
18702 (define_peephole2
18703   [(set (match_operand:HI 0 "push_operand" "")
18704         (match_operand:HI 1 "memory_operand" ""))
18705    (match_scratch:HI 2 "r")]
18706   "! optimize_size && ! TARGET_PUSH_MEMORY"
18707   [(set (match_dup 2) (match_dup 1))
18708    (set (match_dup 0) (match_dup 2))]
18709   "")
18710
18711 (define_peephole2
18712   [(set (match_operand:QI 0 "push_operand" "")
18713         (match_operand:QI 1 "memory_operand" ""))
18714    (match_scratch:QI 2 "q")]
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 ;; Don't move an immediate directly to memory when the instruction
18721 ;; gets too big.
18722 (define_peephole2
18723   [(match_scratch:SI 1 "r")
18724    (set (match_operand:SI 0 "memory_operand" "")
18725         (const_int 0))]
18726   "! optimize_size
18727    && ! TARGET_USE_MOV0
18728    && TARGET_SPLIT_LONG_MOVES
18729    && get_attr_length (insn) >= ix86_cost->large_insn
18730    && peep2_regno_dead_p (0, FLAGS_REG)"
18731   [(parallel [(set (match_dup 1) (const_int 0))
18732               (clobber (reg:CC FLAGS_REG))])
18733    (set (match_dup 0) (match_dup 1))]
18734   "")
18735
18736 (define_peephole2
18737   [(match_scratch:HI 1 "r")
18738    (set (match_operand:HI 0 "memory_operand" "")
18739         (const_int 0))]
18740   "! optimize_size
18741    && ! TARGET_USE_MOV0
18742    && TARGET_SPLIT_LONG_MOVES
18743    && get_attr_length (insn) >= ix86_cost->large_insn
18744    && peep2_regno_dead_p (0, FLAGS_REG)"
18745   [(parallel [(set (match_dup 2) (const_int 0))
18746               (clobber (reg:CC FLAGS_REG))])
18747    (set (match_dup 0) (match_dup 1))]
18748   "operands[2] = gen_lowpart (SImode, operands[1]);")
18749
18750 (define_peephole2
18751   [(match_scratch:QI 1 "q")
18752    (set (match_operand:QI 0 "memory_operand" "")
18753         (const_int 0))]
18754   "! optimize_size
18755    && ! TARGET_USE_MOV0
18756    && TARGET_SPLIT_LONG_MOVES
18757    && get_attr_length (insn) >= ix86_cost->large_insn
18758    && peep2_regno_dead_p (0, FLAGS_REG)"
18759   [(parallel [(set (match_dup 2) (const_int 0))
18760               (clobber (reg:CC FLAGS_REG))])
18761    (set (match_dup 0) (match_dup 1))]
18762   "operands[2] = gen_lowpart (SImode, operands[1]);")
18763
18764 (define_peephole2
18765   [(match_scratch:SI 2 "r")
18766    (set (match_operand:SI 0 "memory_operand" "")
18767         (match_operand:SI 1 "immediate_operand" ""))]
18768   "! optimize_size
18769    && get_attr_length (insn) >= ix86_cost->large_insn
18770    && TARGET_SPLIT_LONG_MOVES"
18771   [(set (match_dup 2) (match_dup 1))
18772    (set (match_dup 0) (match_dup 2))]
18773   "")
18774
18775 (define_peephole2
18776   [(match_scratch:HI 2 "r")
18777    (set (match_operand:HI 0 "memory_operand" "")
18778         (match_operand:HI 1 "immediate_operand" ""))]
18779   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18780   && TARGET_SPLIT_LONG_MOVES"
18781   [(set (match_dup 2) (match_dup 1))
18782    (set (match_dup 0) (match_dup 2))]
18783   "")
18784
18785 (define_peephole2
18786   [(match_scratch:QI 2 "q")
18787    (set (match_operand:QI 0 "memory_operand" "")
18788         (match_operand:QI 1 "immediate_operand" ""))]
18789   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18790   && TARGET_SPLIT_LONG_MOVES"
18791   [(set (match_dup 2) (match_dup 1))
18792    (set (match_dup 0) (match_dup 2))]
18793   "")
18794
18795 ;; Don't compare memory with zero, load and use a test instead.
18796 (define_peephole2
18797   [(set (match_operand 0 "flags_reg_operand" "")
18798         (match_operator 1 "compare_operator"
18799           [(match_operand:SI 2 "memory_operand" "")
18800            (const_int 0)]))
18801    (match_scratch:SI 3 "r")]
18802   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18803   [(set (match_dup 3) (match_dup 2))
18804    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18805   "")
18806
18807 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18808 ;; Don't split NOTs with a displacement operand, because resulting XOR
18809 ;; will not be pairable anyway.
18810 ;;
18811 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18812 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18813 ;; so this split helps here as well.
18814 ;;
18815 ;; Note: Can't do this as a regular split because we can't get proper
18816 ;; lifetime information then.
18817
18818 (define_peephole2
18819   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18820         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18821   "!optimize_size
18822    && peep2_regno_dead_p (0, FLAGS_REG)
18823    && ((TARGET_PENTIUM 
18824         && (GET_CODE (operands[0]) != MEM
18825             || !memory_displacement_operand (operands[0], SImode)))
18826        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18827   [(parallel [(set (match_dup 0)
18828                    (xor:SI (match_dup 1) (const_int -1)))
18829               (clobber (reg:CC FLAGS_REG))])]
18830   "")
18831
18832 (define_peephole2
18833   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18834         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18835   "!optimize_size
18836    && peep2_regno_dead_p (0, FLAGS_REG)
18837    && ((TARGET_PENTIUM 
18838         && (GET_CODE (operands[0]) != MEM
18839             || !memory_displacement_operand (operands[0], HImode)))
18840        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18841   [(parallel [(set (match_dup 0)
18842                    (xor:HI (match_dup 1) (const_int -1)))
18843               (clobber (reg:CC FLAGS_REG))])]
18844   "")
18845
18846 (define_peephole2
18847   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18848         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18849   "!optimize_size
18850    && peep2_regno_dead_p (0, FLAGS_REG)
18851    && ((TARGET_PENTIUM 
18852         && (GET_CODE (operands[0]) != MEM
18853             || !memory_displacement_operand (operands[0], QImode)))
18854        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18855   [(parallel [(set (match_dup 0)
18856                    (xor:QI (match_dup 1) (const_int -1)))
18857               (clobber (reg:CC FLAGS_REG))])]
18858   "")
18859
18860 ;; Non pairable "test imm, reg" instructions can be translated to
18861 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18862 ;; byte opcode instead of two, have a short form for byte operands),
18863 ;; so do it for other CPUs as well.  Given that the value was dead,
18864 ;; this should not create any new dependencies.  Pass on the sub-word
18865 ;; versions if we're concerned about partial register stalls.
18866
18867 (define_peephole2
18868   [(set (match_operand 0 "flags_reg_operand" "")
18869         (match_operator 1 "compare_operator"
18870           [(and:SI (match_operand:SI 2 "register_operand" "")
18871                    (match_operand:SI 3 "immediate_operand" ""))
18872            (const_int 0)]))]
18873   "ix86_match_ccmode (insn, CCNOmode)
18874    && (true_regnum (operands[2]) != 0
18875        || (GET_CODE (operands[3]) == CONST_INT
18876            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18877    && peep2_reg_dead_p (1, operands[2])"
18878   [(parallel
18879      [(set (match_dup 0)
18880            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18881                             (const_int 0)]))
18882       (set (match_dup 2)
18883            (and:SI (match_dup 2) (match_dup 3)))])]
18884   "")
18885
18886 ;; We don't need to handle HImode case, because it will be promoted to SImode
18887 ;; on ! TARGET_PARTIAL_REG_STALL
18888
18889 (define_peephole2
18890   [(set (match_operand 0 "flags_reg_operand" "")
18891         (match_operator 1 "compare_operator"
18892           [(and:QI (match_operand:QI 2 "register_operand" "")
18893                    (match_operand:QI 3 "immediate_operand" ""))
18894            (const_int 0)]))]
18895   "! TARGET_PARTIAL_REG_STALL
18896    && ix86_match_ccmode (insn, CCNOmode)
18897    && true_regnum (operands[2]) != 0
18898    && peep2_reg_dead_p (1, operands[2])"
18899   [(parallel
18900      [(set (match_dup 0)
18901            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18902                             (const_int 0)]))
18903       (set (match_dup 2)
18904            (and:QI (match_dup 2) (match_dup 3)))])]
18905   "")
18906
18907 (define_peephole2
18908   [(set (match_operand 0 "flags_reg_operand" "")
18909         (match_operator 1 "compare_operator"
18910           [(and:SI
18911              (zero_extract:SI
18912                (match_operand 2 "ext_register_operand" "")
18913                (const_int 8)
18914                (const_int 8))
18915              (match_operand 3 "const_int_operand" ""))
18916            (const_int 0)]))]
18917   "! TARGET_PARTIAL_REG_STALL
18918    && ix86_match_ccmode (insn, CCNOmode)
18919    && true_regnum (operands[2]) != 0
18920    && peep2_reg_dead_p (1, operands[2])"
18921   [(parallel [(set (match_dup 0)
18922                    (match_op_dup 1
18923                      [(and:SI
18924                         (zero_extract:SI
18925                           (match_dup 2)
18926                           (const_int 8)
18927                           (const_int 8))
18928                         (match_dup 3))
18929                       (const_int 0)]))
18930               (set (zero_extract:SI (match_dup 2)
18931                                     (const_int 8)
18932                                     (const_int 8))
18933                    (and:SI 
18934                      (zero_extract:SI
18935                        (match_dup 2)
18936                        (const_int 8)
18937                        (const_int 8))
18938                      (match_dup 3)))])]
18939   "")
18940
18941 ;; Don't do logical operations with memory inputs.
18942 (define_peephole2
18943   [(match_scratch:SI 2 "r")
18944    (parallel [(set (match_operand:SI 0 "register_operand" "")
18945                    (match_operator:SI 3 "arith_or_logical_operator"
18946                      [(match_dup 0)
18947                       (match_operand:SI 1 "memory_operand" "")]))
18948               (clobber (reg:CC FLAGS_REG))])]
18949   "! optimize_size && ! TARGET_READ_MODIFY"
18950   [(set (match_dup 2) (match_dup 1))
18951    (parallel [(set (match_dup 0)
18952                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18953               (clobber (reg:CC FLAGS_REG))])]
18954   "")
18955
18956 (define_peephole2
18957   [(match_scratch:SI 2 "r")
18958    (parallel [(set (match_operand:SI 0 "register_operand" "")
18959                    (match_operator:SI 3 "arith_or_logical_operator"
18960                      [(match_operand:SI 1 "memory_operand" "")
18961                       (match_dup 0)]))
18962               (clobber (reg:CC FLAGS_REG))])]
18963   "! optimize_size && ! TARGET_READ_MODIFY"
18964   [(set (match_dup 2) (match_dup 1))
18965    (parallel [(set (match_dup 0)
18966                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18967               (clobber (reg:CC FLAGS_REG))])]
18968   "")
18969
18970 ; Don't do logical operations with memory outputs
18971 ;
18972 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18973 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18974 ; the same decoder scheduling characteristics as the original.
18975
18976 (define_peephole2
18977   [(match_scratch:SI 2 "r")
18978    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18979                    (match_operator:SI 3 "arith_or_logical_operator"
18980                      [(match_dup 0)
18981                       (match_operand:SI 1 "nonmemory_operand" "")]))
18982               (clobber (reg:CC FLAGS_REG))])]
18983   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18984   [(set (match_dup 2) (match_dup 0))
18985    (parallel [(set (match_dup 2)
18986                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18987               (clobber (reg:CC FLAGS_REG))])
18988    (set (match_dup 0) (match_dup 2))]
18989   "")
18990
18991 (define_peephole2
18992   [(match_scratch:SI 2 "r")
18993    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18994                    (match_operator:SI 3 "arith_or_logical_operator"
18995                      [(match_operand:SI 1 "nonmemory_operand" "")
18996                       (match_dup 0)]))
18997               (clobber (reg:CC FLAGS_REG))])]
18998   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18999   [(set (match_dup 2) (match_dup 0))
19000    (parallel [(set (match_dup 2)
19001                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19002               (clobber (reg:CC FLAGS_REG))])
19003    (set (match_dup 0) (match_dup 2))]
19004   "")
19005
19006 ;; Attempt to always use XOR for zeroing registers.
19007 (define_peephole2
19008   [(set (match_operand 0 "register_operand" "")
19009         (const_int 0))]
19010   "(GET_MODE (operands[0]) == QImode
19011     || GET_MODE (operands[0]) == HImode
19012     || GET_MODE (operands[0]) == SImode
19013     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19014    && (! TARGET_USE_MOV0 || optimize_size)
19015    && peep2_regno_dead_p (0, FLAGS_REG)"
19016   [(parallel [(set (match_dup 0) (const_int 0))
19017               (clobber (reg:CC FLAGS_REG))])]
19018   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19019                               operands[0]);")
19020
19021 (define_peephole2
19022   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19023         (const_int 0))]
19024   "(GET_MODE (operands[0]) == QImode
19025     || GET_MODE (operands[0]) == HImode)
19026    && (! TARGET_USE_MOV0 || optimize_size)
19027    && peep2_regno_dead_p (0, FLAGS_REG)"
19028   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19029               (clobber (reg:CC FLAGS_REG))])])
19030
19031 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19032 (define_peephole2
19033   [(set (match_operand 0 "register_operand" "")
19034         (const_int -1))]
19035   "(GET_MODE (operands[0]) == HImode
19036     || GET_MODE (operands[0]) == SImode 
19037     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19038    && (optimize_size || TARGET_PENTIUM)
19039    && peep2_regno_dead_p (0, FLAGS_REG)"
19040   [(parallel [(set (match_dup 0) (const_int -1))
19041               (clobber (reg:CC FLAGS_REG))])]
19042   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19043                               operands[0]);")
19044
19045 ;; Attempt to convert simple leas to adds. These can be created by
19046 ;; move expanders.
19047 (define_peephole2
19048   [(set (match_operand:SI 0 "register_operand" "")
19049         (plus:SI (match_dup 0)
19050                  (match_operand:SI 1 "nonmemory_operand" "")))]
19051   "peep2_regno_dead_p (0, FLAGS_REG)"
19052   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19053               (clobber (reg:CC FLAGS_REG))])]
19054   "")
19055
19056 (define_peephole2
19057   [(set (match_operand:SI 0 "register_operand" "")
19058         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19059                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19060   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19061   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19062               (clobber (reg:CC FLAGS_REG))])]
19063   "operands[2] = gen_lowpart (SImode, operands[2]);")
19064
19065 (define_peephole2
19066   [(set (match_operand:DI 0 "register_operand" "")
19067         (plus:DI (match_dup 0)
19068                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19069   "peep2_regno_dead_p (0, FLAGS_REG)"
19070   [(parallel [(set (match_dup 0) (plus:DI (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         (mult:SI (match_dup 0)
19077                  (match_operand:SI 1 "const_int_operand" "")))]
19078   "exact_log2 (INTVAL (operands[1])) >= 0
19079    && peep2_regno_dead_p (0, FLAGS_REG)"
19080   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19081               (clobber (reg:CC FLAGS_REG))])]
19082   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19083
19084 (define_peephole2
19085   [(set (match_operand:DI 0 "register_operand" "")
19086         (mult:DI (match_dup 0)
19087                  (match_operand:DI 1 "const_int_operand" "")))]
19088   "exact_log2 (INTVAL (operands[1])) >= 0
19089    && peep2_regno_dead_p (0, FLAGS_REG)"
19090   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19091               (clobber (reg:CC FLAGS_REG))])]
19092   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19093
19094 (define_peephole2
19095   [(set (match_operand:SI 0 "register_operand" "")
19096         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19097                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19098   "exact_log2 (INTVAL (operands[2])) >= 0
19099    && REGNO (operands[0]) == REGNO (operands[1])
19100    && peep2_regno_dead_p (0, FLAGS_REG)"
19101   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19102               (clobber (reg:CC FLAGS_REG))])]
19103   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19104
19105 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19106 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19107 ;; many CPUs it is also faster, since special hardware to avoid esp
19108 ;; dependencies is present.
19109
19110 ;; While some of these conversions may be done using splitters, we use peepholes
19111 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19112
19113 ;; Convert prologue esp subtractions to push.
19114 ;; We need register to push.  In order to keep verify_flow_info happy we have
19115 ;; two choices
19116 ;; - use scratch and clobber it in order to avoid dependencies
19117 ;; - use already live register
19118 ;; We can't use the second way right now, since there is no reliable way how to
19119 ;; verify that given register is live.  First choice will also most likely in
19120 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19121 ;; call clobbered registers are dead.  We may want to use base pointer as an
19122 ;; alternative when no register is available later.
19123
19124 (define_peephole2
19125   [(match_scratch:SI 0 "r")
19126    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19127               (clobber (reg:CC FLAGS_REG))
19128               (clobber (mem:BLK (scratch)))])]
19129   "optimize_size || !TARGET_SUB_ESP_4"
19130   [(clobber (match_dup 0))
19131    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19132               (clobber (mem:BLK (scratch)))])])
19133
19134 (define_peephole2
19135   [(match_scratch:SI 0 "r")
19136    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19137               (clobber (reg:CC FLAGS_REG))
19138               (clobber (mem:BLK (scratch)))])]
19139   "optimize_size || !TARGET_SUB_ESP_8"
19140   [(clobber (match_dup 0))
19141    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19142    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19143               (clobber (mem:BLK (scratch)))])])
19144
19145 ;; Convert esp subtractions to push.
19146 (define_peephole2
19147   [(match_scratch:SI 0 "r")
19148    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19149               (clobber (reg:CC FLAGS_REG))])]
19150   "optimize_size || !TARGET_SUB_ESP_4"
19151   [(clobber (match_dup 0))
19152    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19153
19154 (define_peephole2
19155   [(match_scratch:SI 0 "r")
19156    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19157               (clobber (reg:CC FLAGS_REG))])]
19158   "optimize_size || !TARGET_SUB_ESP_8"
19159   [(clobber (match_dup 0))
19160    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19161    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19162
19163 ;; Convert epilogue deallocator to pop.
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               (clobber (mem:BLK (scratch)))])]
19169   "optimize_size || !TARGET_ADD_ESP_4"
19170   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19171               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19172               (clobber (mem:BLK (scratch)))])]
19173   "")
19174
19175 ;; Two pops case is tricky, since pop causes dependency on destination register.
19176 ;; We use two registers if available.
19177 (define_peephole2
19178   [(match_scratch:SI 0 "r")
19179    (match_scratch:SI 1 "r")
19180    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19181               (clobber (reg:CC FLAGS_REG))
19182               (clobber (mem:BLK (scratch)))])]
19183   "optimize_size || !TARGET_ADD_ESP_8"
19184   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19185               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19186               (clobber (mem:BLK (scratch)))])
19187    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19188               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19189   "")
19190
19191 (define_peephole2
19192   [(match_scratch:SI 0 "r")
19193    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19194               (clobber (reg:CC FLAGS_REG))
19195               (clobber (mem:BLK (scratch)))])]
19196   "optimize_size"
19197   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19198               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19199               (clobber (mem:BLK (scratch)))])
19200    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19201               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19202   "")
19203
19204 ;; Convert esp additions to pop.
19205 (define_peephole2
19206   [(match_scratch:SI 0 "r")
19207    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19208               (clobber (reg:CC FLAGS_REG))])]
19209   ""
19210   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19211               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19212   "")
19213
19214 ;; Two pops case is tricky, since pop causes dependency on destination register.
19215 ;; We use two registers if available.
19216 (define_peephole2
19217   [(match_scratch:SI 0 "r")
19218    (match_scratch:SI 1 "r")
19219    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19220               (clobber (reg:CC FLAGS_REG))])]
19221   ""
19222   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19223               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19224    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19225               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19226   "")
19227
19228 (define_peephole2
19229   [(match_scratch:SI 0 "r")
19230    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19231               (clobber (reg:CC FLAGS_REG))])]
19232   "optimize_size"
19233   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19234               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19235    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19236               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19237   "")
19238 \f
19239 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19240 ;; required and register dies.  Similarly for 128 to plus -128.
19241 (define_peephole2
19242   [(set (match_operand 0 "flags_reg_operand" "")
19243         (match_operator 1 "compare_operator"
19244           [(match_operand 2 "register_operand" "")
19245            (match_operand 3 "const_int_operand" "")]))]
19246   "(INTVAL (operands[3]) == -1
19247     || INTVAL (operands[3]) == 1
19248     || INTVAL (operands[3]) == 128)
19249    && ix86_match_ccmode (insn, CCGCmode)
19250    && peep2_reg_dead_p (1, operands[2])"
19251   [(parallel [(set (match_dup 0)
19252                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19253               (clobber (match_dup 2))])]
19254   "")
19255 \f
19256 (define_peephole2
19257   [(match_scratch:DI 0 "r")
19258    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19259               (clobber (reg:CC FLAGS_REG))
19260               (clobber (mem:BLK (scratch)))])]
19261   "optimize_size || !TARGET_SUB_ESP_4"
19262   [(clobber (match_dup 0))
19263    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19264               (clobber (mem:BLK (scratch)))])])
19265
19266 (define_peephole2
19267   [(match_scratch:DI 0 "r")
19268    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19269               (clobber (reg:CC FLAGS_REG))
19270               (clobber (mem:BLK (scratch)))])]
19271   "optimize_size || !TARGET_SUB_ESP_8"
19272   [(clobber (match_dup 0))
19273    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19274    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19275               (clobber (mem:BLK (scratch)))])])
19276
19277 ;; Convert esp subtractions to push.
19278 (define_peephole2
19279   [(match_scratch:DI 0 "r")
19280    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19281               (clobber (reg:CC FLAGS_REG))])]
19282   "optimize_size || !TARGET_SUB_ESP_4"
19283   [(clobber (match_dup 0))
19284    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19285
19286 (define_peephole2
19287   [(match_scratch:DI 0 "r")
19288    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19289               (clobber (reg:CC FLAGS_REG))])]
19290   "optimize_size || !TARGET_SUB_ESP_8"
19291   [(clobber (match_dup 0))
19292    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19293    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19294
19295 ;; Convert epilogue deallocator to pop.
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               (clobber (mem:BLK (scratch)))])]
19301   "optimize_size || !TARGET_ADD_ESP_4"
19302   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19303               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19304               (clobber (mem:BLK (scratch)))])]
19305   "")
19306
19307 ;; Two pops case is tricky, since pop causes dependency on destination register.
19308 ;; We use two registers if available.
19309 (define_peephole2
19310   [(match_scratch:DI 0 "r")
19311    (match_scratch:DI 1 "r")
19312    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19313               (clobber (reg:CC FLAGS_REG))
19314               (clobber (mem:BLK (scratch)))])]
19315   "optimize_size || !TARGET_ADD_ESP_8"
19316   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19317               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19318               (clobber (mem:BLK (scratch)))])
19319    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19320               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19321   "")
19322
19323 (define_peephole2
19324   [(match_scratch:DI 0 "r")
19325    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19326               (clobber (reg:CC FLAGS_REG))
19327               (clobber (mem:BLK (scratch)))])]
19328   "optimize_size"
19329   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19330               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19331               (clobber (mem:BLK (scratch)))])
19332    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19333               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19334   "")
19335
19336 ;; Convert esp additions to pop.
19337 (define_peephole2
19338   [(match_scratch:DI 0 "r")
19339    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19340               (clobber (reg:CC FLAGS_REG))])]
19341   ""
19342   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19343               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19344   "")
19345
19346 ;; Two pops case is tricky, since pop causes dependency on destination register.
19347 ;; We use two registers if available.
19348 (define_peephole2
19349   [(match_scratch:DI 0 "r")
19350    (match_scratch:DI 1 "r")
19351    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19352               (clobber (reg:CC FLAGS_REG))])]
19353   ""
19354   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19355               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19356    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19357               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19358   "")
19359
19360 (define_peephole2
19361   [(match_scratch:DI 0 "r")
19362    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19363               (clobber (reg:CC FLAGS_REG))])]
19364   "optimize_size"
19365   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19366               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19367    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19368               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19369   "")
19370 \f
19371 ;; Convert imul by three, five and nine into lea
19372 (define_peephole2
19373   [(parallel
19374     [(set (match_operand:SI 0 "register_operand" "")
19375           (mult:SI (match_operand:SI 1 "register_operand" "")
19376                    (match_operand:SI 2 "const_int_operand" "")))
19377      (clobber (reg:CC FLAGS_REG))])]
19378   "INTVAL (operands[2]) == 3
19379    || INTVAL (operands[2]) == 5
19380    || INTVAL (operands[2]) == 9"
19381   [(set (match_dup 0)
19382         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19383                  (match_dup 1)))]
19384   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19385
19386 (define_peephole2
19387   [(parallel
19388     [(set (match_operand:SI 0 "register_operand" "")
19389           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19390                    (match_operand:SI 2 "const_int_operand" "")))
19391      (clobber (reg:CC FLAGS_REG))])]
19392   "!optimize_size 
19393    && (INTVAL (operands[2]) == 3
19394        || INTVAL (operands[2]) == 5
19395        || INTVAL (operands[2]) == 9)"
19396   [(set (match_dup 0) (match_dup 1))
19397    (set (match_dup 0)
19398         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19399                  (match_dup 0)))]
19400   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19401
19402 (define_peephole2
19403   [(parallel
19404     [(set (match_operand:DI 0 "register_operand" "")
19405           (mult:DI (match_operand:DI 1 "register_operand" "")
19406                    (match_operand:DI 2 "const_int_operand" "")))
19407      (clobber (reg:CC FLAGS_REG))])]
19408   "TARGET_64BIT
19409    && (INTVAL (operands[2]) == 3
19410        || INTVAL (operands[2]) == 5
19411        || INTVAL (operands[2]) == 9)"
19412   [(set (match_dup 0)
19413         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19414                  (match_dup 1)))]
19415   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19416
19417 (define_peephole2
19418   [(parallel
19419     [(set (match_operand:DI 0 "register_operand" "")
19420           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19421                    (match_operand:DI 2 "const_int_operand" "")))
19422      (clobber (reg:CC FLAGS_REG))])]
19423   "TARGET_64BIT
19424    && !optimize_size 
19425    && (INTVAL (operands[2]) == 3
19426        || INTVAL (operands[2]) == 5
19427        || INTVAL (operands[2]) == 9)"
19428   [(set (match_dup 0) (match_dup 1))
19429    (set (match_dup 0)
19430         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19431                  (match_dup 0)))]
19432   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19433
19434 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19435 ;; imul $32bit_imm, reg, reg is direct decoded.
19436 (define_peephole2
19437   [(match_scratch:DI 3 "r")
19438    (parallel [(set (match_operand:DI 0 "register_operand" "")
19439                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19440                             (match_operand:DI 2 "immediate_operand" "")))
19441               (clobber (reg:CC FLAGS_REG))])]
19442   "TARGET_K8 && !optimize_size
19443    && (GET_CODE (operands[2]) != CONST_INT
19444        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19445   [(set (match_dup 3) (match_dup 1))
19446    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19447               (clobber (reg:CC FLAGS_REG))])]
19448 "")
19449
19450 (define_peephole2
19451   [(match_scratch:SI 3 "r")
19452    (parallel [(set (match_operand:SI 0 "register_operand" "")
19453                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19454                             (match_operand:SI 2 "immediate_operand" "")))
19455               (clobber (reg:CC FLAGS_REG))])]
19456   "TARGET_K8 && !optimize_size
19457    && (GET_CODE (operands[2]) != CONST_INT
19458        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19459   [(set (match_dup 3) (match_dup 1))
19460    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19461               (clobber (reg:CC FLAGS_REG))])]
19462 "")
19463
19464 (define_peephole2
19465   [(match_scratch:SI 3 "r")
19466    (parallel [(set (match_operand:DI 0 "register_operand" "")
19467                    (zero_extend:DI
19468                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19469                               (match_operand:SI 2 "immediate_operand" ""))))
19470               (clobber (reg:CC FLAGS_REG))])]
19471   "TARGET_K8 && !optimize_size
19472    && (GET_CODE (operands[2]) != CONST_INT
19473        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19474   [(set (match_dup 3) (match_dup 1))
19475    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19476               (clobber (reg:CC FLAGS_REG))])]
19477 "")
19478
19479 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19480 ;; Convert it into imul reg, reg
19481 ;; It would be better to force assembler to encode instruction using long
19482 ;; immediate, but there is apparently no way to do so.
19483 (define_peephole2
19484   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19485                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19486                             (match_operand:DI 2 "const_int_operand" "")))
19487               (clobber (reg:CC FLAGS_REG))])
19488    (match_scratch:DI 3 "r")]
19489   "TARGET_K8 && !optimize_size
19490    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19491   [(set (match_dup 3) (match_dup 2))
19492    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19493               (clobber (reg:CC FLAGS_REG))])]
19494 {
19495   if (!rtx_equal_p (operands[0], operands[1]))
19496     emit_move_insn (operands[0], operands[1]);
19497 })
19498
19499 (define_peephole2
19500   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19501                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19502                             (match_operand:SI 2 "const_int_operand" "")))
19503               (clobber (reg:CC FLAGS_REG))])
19504    (match_scratch:SI 3 "r")]
19505   "TARGET_K8 && !optimize_size
19506    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19507   [(set (match_dup 3) (match_dup 2))
19508    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19509               (clobber (reg:CC FLAGS_REG))])]
19510 {
19511   if (!rtx_equal_p (operands[0], operands[1]))
19512     emit_move_insn (operands[0], operands[1]);
19513 })
19514
19515 (define_peephole2
19516   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19517                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19518                             (match_operand:HI 2 "immediate_operand" "")))
19519               (clobber (reg:CC FLAGS_REG))])
19520    (match_scratch:HI 3 "r")]
19521   "TARGET_K8 && !optimize_size"
19522   [(set (match_dup 3) (match_dup 2))
19523    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19524               (clobber (reg:CC FLAGS_REG))])]
19525 {
19526   if (!rtx_equal_p (operands[0], operands[1]))
19527     emit_move_insn (operands[0], operands[1]);
19528 })
19529 \f
19530 ;; Call-value patterns last so that the wildcard operand does not
19531 ;; disrupt insn-recog's switch tables.
19532
19533 (define_insn "*call_value_pop_0"
19534   [(set (match_operand 0 "" "")
19535         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19536               (match_operand:SI 2 "" "")))
19537    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19538                             (match_operand:SI 3 "immediate_operand" "")))]
19539   "!TARGET_64BIT"
19540 {
19541   if (SIBLING_CALL_P (insn))
19542     return "jmp\t%P1";
19543   else
19544     return "call\t%P1";
19545 }
19546   [(set_attr "type" "callv")])
19547
19548 (define_insn "*call_value_pop_1"
19549   [(set (match_operand 0 "" "")
19550         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19551               (match_operand:SI 2 "" "")))
19552    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19553                             (match_operand:SI 3 "immediate_operand" "i")))]
19554   "!TARGET_64BIT"
19555 {
19556   if (constant_call_address_operand (operands[1], Pmode))
19557     {
19558       if (SIBLING_CALL_P (insn))
19559         return "jmp\t%P1";
19560       else
19561         return "call\t%P1";
19562     }
19563   if (SIBLING_CALL_P (insn))
19564     return "jmp\t%A1";
19565   else
19566     return "call\t%A1";
19567 }
19568   [(set_attr "type" "callv")])
19569
19570 (define_insn "*call_value_0"
19571   [(set (match_operand 0 "" "")
19572         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19573               (match_operand:SI 2 "" "")))]
19574   "!TARGET_64BIT"
19575 {
19576   if (SIBLING_CALL_P (insn))
19577     return "jmp\t%P1";
19578   else
19579     return "call\t%P1";
19580 }
19581   [(set_attr "type" "callv")])
19582
19583 (define_insn "*call_value_0_rex64"
19584   [(set (match_operand 0 "" "")
19585         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19586               (match_operand:DI 2 "const_int_operand" "")))]
19587   "TARGET_64BIT"
19588 {
19589   if (SIBLING_CALL_P (insn))
19590     return "jmp\t%P1";
19591   else
19592     return "call\t%P1";
19593 }
19594   [(set_attr "type" "callv")])
19595
19596 (define_insn "*call_value_1"
19597   [(set (match_operand 0 "" "")
19598         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19599               (match_operand:SI 2 "" "")))]
19600   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19601 {
19602   if (constant_call_address_operand (operands[1], Pmode))
19603     return "call\t%P1";
19604   return "call\t%A1";
19605 }
19606   [(set_attr "type" "callv")])
19607
19608 (define_insn "*sibcall_value_1"
19609   [(set (match_operand 0 "" "")
19610         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19611               (match_operand:SI 2 "" "")))]
19612   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19613 {
19614   if (constant_call_address_operand (operands[1], Pmode))
19615     return "jmp\t%P1";
19616   return "jmp\t%A1";
19617 }
19618   [(set_attr "type" "callv")])
19619
19620 (define_insn "*call_value_1_rex64"
19621   [(set (match_operand 0 "" "")
19622         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19623               (match_operand:DI 2 "" "")))]
19624   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19625 {
19626   if (constant_call_address_operand (operands[1], Pmode))
19627     return "call\t%P1";
19628   return "call\t%A1";
19629 }
19630   [(set_attr "type" "callv")])
19631
19632 (define_insn "*sibcall_value_1_rex64"
19633   [(set (match_operand 0 "" "")
19634         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19635               (match_operand:DI 2 "" "")))]
19636   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19637   "jmp\t%P1"
19638   [(set_attr "type" "callv")])
19639
19640 (define_insn "*sibcall_value_1_rex64_v"
19641   [(set (match_operand 0 "" "")
19642         (call (mem:QI (reg:DI 40))
19643               (match_operand:DI 1 "" "")))]
19644   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19645   "jmp\t*%%r11"
19646   [(set_attr "type" "callv")])
19647 \f
19648 (define_insn "trap"
19649   [(trap_if (const_int 1) (const_int 5))]
19650   ""
19651   "int\t$5")
19652
19653 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19654 ;;; for the sake of bounds checking.  By emitting bounds checks as
19655 ;;; conditional traps rather than as conditional jumps around
19656 ;;; unconditional traps we avoid introducing spurious basic-block
19657 ;;; boundaries and facilitate elimination of redundant checks.  In
19658 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19659 ;;; interrupt 5.
19660 ;;; 
19661 ;;; FIXME: Static branch prediction rules for ix86 are such that
19662 ;;; forward conditional branches predict as untaken.  As implemented
19663 ;;; below, pseudo conditional traps violate that rule.  We should use
19664 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19665 ;;; section loaded at the end of the text segment and branch forward
19666 ;;; there on bounds-failure, and then jump back immediately (in case
19667 ;;; the system chooses to ignore bounds violations, or to report
19668 ;;; violations and continue execution).
19669
19670 (define_expand "conditional_trap"
19671   [(trap_if (match_operator 0 "comparison_operator"
19672              [(match_dup 2) (const_int 0)])
19673             (match_operand 1 "const_int_operand" ""))]
19674   ""
19675 {
19676   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19677                               ix86_expand_compare (GET_CODE (operands[0]),
19678                                                    NULL, NULL),
19679                               operands[1]));
19680   DONE;
19681 })
19682
19683 (define_insn "*conditional_trap_1"
19684   [(trap_if (match_operator 0 "comparison_operator"
19685              [(reg FLAGS_REG) (const_int 0)])
19686             (match_operand 1 "const_int_operand" ""))]
19687   ""
19688 {
19689   operands[2] = gen_label_rtx ();
19690   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19691   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19692                              CODE_LABEL_NUMBER (operands[2]));
19693   RET;
19694 })
19695
19696         ;; Pentium III SIMD instructions.
19697
19698 ;; Moves for SSE/MMX regs.
19699
19700 (define_expand "movv4sf"
19701   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19702         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19703   "TARGET_SSE"
19704 {
19705   ix86_expand_vector_move (V4SFmode, operands);
19706   DONE;
19707 })
19708
19709 (define_insn "*movv4sf_internal"
19710   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19711         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19712   "TARGET_SSE"
19713   "@
19714     xorps\t%0, %0
19715     movaps\t{%1, %0|%0, %1}
19716     movaps\t{%1, %0|%0, %1}"
19717   [(set_attr "type" "ssemov")
19718    (set_attr "mode" "V4SF")])
19719
19720 (define_split
19721   [(set (match_operand:V4SF 0 "register_operand" "")
19722         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19723   "TARGET_SSE && reload_completed"
19724   [(set (match_dup 0)
19725         (vec_merge:V4SF
19726          (vec_duplicate:V4SF (match_dup 1))
19727          (match_dup 2)
19728          (const_int 1)))]
19729 {
19730   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19731   operands[2] = CONST0_RTX (V4SFmode);
19732 })
19733
19734 (define_expand "movv2df"
19735   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19736         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19737   "TARGET_SSE"
19738 {
19739   ix86_expand_vector_move (V2DFmode, operands);
19740   DONE;
19741 })
19742
19743 (define_insn "*movv2df_internal"
19744   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19745         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19746   "TARGET_SSE
19747    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19748 {
19749   switch (which_alternative)
19750     {
19751     case 0:
19752       if (get_attr_mode (insn) == MODE_V4SF)
19753         return "xorps\t%0, %0";
19754       else
19755         return "xorpd\t%0, %0";
19756     case 1:
19757     case 2:
19758       if (get_attr_mode (insn) == MODE_V4SF)
19759         return "movaps\t{%1, %0|%0, %1}";
19760       else
19761         return "movapd\t{%1, %0|%0, %1}";
19762     default:
19763       abort ();
19764     }
19765 }
19766   [(set_attr "type" "ssemov")
19767    (set (attr "mode")
19768         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
19769                  (const_string "V4SF")
19770                (eq_attr "alternative" "0,1")
19771                  (if_then_else
19772                    (ne (symbol_ref "optimize_size")
19773                        (const_int 0))
19774                    (const_string "V4SF")
19775                    (const_string "V2DF"))
19776                (eq_attr "alternative" "2")
19777                  (if_then_else
19778                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19779                             (const_int 0))
19780                         (ne (symbol_ref "optimize_size")
19781                             (const_int 0)))
19782                    (const_string "V4SF")
19783                    (const_string "V2DF"))]
19784                (const_string "V2DF")))])
19785
19786 (define_split
19787   [(set (match_operand:V2DF 0 "register_operand" "")
19788         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19789   "TARGET_SSE2 && reload_completed"
19790   [(set (match_dup 0)
19791         (vec_merge:V2DF
19792          (vec_duplicate:V2DF (match_dup 1))
19793          (match_dup 2)
19794          (const_int 1)))]
19795 {
19796   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19797   operands[2] = CONST0_RTX (V2DFmode);
19798 })
19799
19800 ;; 16 byte integral modes handled by SSE, minus TImode, which gets
19801 ;; special-cased for TARGET_64BIT.
19802 (define_mode_macro SSEINT16 [V16QI V8HI V4SI V2DI])
19803
19804 (define_expand "mov<mode>"
19805   [(set (match_operand:SSEINT16 0 "nonimmediate_operand" "")
19806         (match_operand:SSEINT16 1 "nonimmediate_operand" ""))]
19807   "TARGET_SSE"
19808 {
19809   ix86_expand_vector_move (<MODE>mode, operands);
19810   DONE;
19811 })
19812
19813 (define_insn "*mov<mode>_internal"
19814   [(set (match_operand:SSEINT16 0 "nonimmediate_operand" "=x,x ,m")
19815         (match_operand:SSEINT16 1 "vector_move_operand"  "C ,xm,x"))]
19816   "TARGET_SSE
19817    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19818 {
19819   switch (which_alternative)
19820     {
19821     case 0:
19822       if (get_attr_mode (insn) == MODE_V4SF)
19823         return "xorps\t%0, %0";
19824       else
19825         return "pxor\t%0, %0";
19826     case 1:
19827     case 2:
19828       if (get_attr_mode (insn) == MODE_V4SF)
19829         return "movaps\t{%1, %0|%0, %1}";
19830       else
19831         return "movdqa\t{%1, %0|%0, %1}";
19832     default:
19833       abort ();
19834     }
19835 }
19836   [(set_attr "type" "ssemov")
19837    (set (attr "mode")
19838         (cond [(eq_attr "alternative" "0,1")
19839                  (if_then_else
19840                    (ne (symbol_ref "optimize_size")
19841                        (const_int 0))
19842                    (const_string "V4SF")
19843                    (const_string "TI"))
19844                (eq_attr "alternative" "2")
19845                  (if_then_else
19846                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19847                             (const_int 0))
19848                         (ne (symbol_ref "optimize_size")
19849                             (const_int 0)))
19850                    (const_string "V4SF")
19851                    (const_string "TI"))]
19852                (const_string "TI")))])
19853
19854 ;; 8 byte integral modes handled by MMX (and by extension, SSE)
19855 (define_mode_macro MMXINT8 [V8QI V4HI V2SI])
19856
19857 (define_expand "mov<mode>"
19858   [(set (match_operand:MMXINT8 0 "nonimmediate_operand" "")
19859         (match_operand:MMXINT8 1 "nonimmediate_operand" ""))]
19860   "TARGET_MMX"
19861 {
19862   ix86_expand_vector_move (<MODE>mode, operands);
19863   DONE;
19864 })
19865
19866 (define_insn "*mov<mode>_internal"
19867   [(set (match_operand:MMXINT8 0 "nonimmediate_operand"
19868                                         "=y,y ,m,!y,!*Y,*x,?*x,?m")
19869         (match_operand:MMXINT8 1 "vector_move_operand"
19870                                         "C ,ym,y,*Y,y  ,C ,*xm,*x"))]
19871   "TARGET_MMX
19872    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19873   "@
19874     pxor\t%0, %0
19875     movq\t{%1, %0|%0, %1}
19876     movq\t{%1, %0|%0, %1}
19877     movdq2q\t{%1, %0|%0, %1}
19878     movq2dq\t{%1, %0|%0, %1}
19879     pxor\t%0, %0
19880     movq\t{%1, %0|%0, %1}
19881     movq\t{%1, %0|%0, %1}"
19882   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
19883    (set_attr "mode" "DI")])
19884
19885 (define_expand "movv2sf"
19886   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19887         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19888   "TARGET_MMX"
19889 {
19890   ix86_expand_vector_move (V2SFmode, operands);
19891   DONE;
19892 })
19893
19894 (define_insn "*movv2sf_internal"
19895   [(set (match_operand:V2SF 0 "nonimmediate_operand"
19896                                         "=y,y ,m,!y,!*Y,*x,?*x,?m")
19897         (match_operand:V2SF 1 "vector_move_operand"
19898                                         "C ,ym,y,*Y,y  ,C ,*xm,*x"))]
19899   "TARGET_MMX
19900    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19901   "@
19902     pxor\t%0, %0
19903     movq\t{%1, %0|%0, %1}
19904     movq\t{%1, %0|%0, %1}
19905     movdq2q\t{%1, %0|%0, %1}
19906     movq2dq\t{%1, %0|%0, %1}
19907     xorps\t%0, %0
19908     movlps\t{%1, %0|%0, %1}
19909     movlps\t{%1, %0|%0, %1}"
19910   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
19911    (set_attr "mode" "DI,DI,DI,DI,DI,V4SF,V2SF,V2SF")])
19912
19913 (define_expand "movti"
19914   [(set (match_operand:TI 0 "nonimmediate_operand" "")
19915         (match_operand:TI 1 "nonimmediate_operand" ""))]
19916   "TARGET_SSE || TARGET_64BIT"
19917 {
19918   if (TARGET_64BIT)
19919     ix86_expand_move (TImode, operands);
19920   else
19921     ix86_expand_vector_move (TImode, operands);
19922   DONE;
19923 })
19924
19925 (define_insn "*movti_internal"
19926   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19927         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19928   "TARGET_SSE && !TARGET_64BIT
19929    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19930 {
19931   switch (which_alternative)
19932     {
19933     case 0:
19934       if (get_attr_mode (insn) == MODE_V4SF)
19935         return "xorps\t%0, %0";
19936       else
19937         return "pxor\t%0, %0";
19938     case 1:
19939     case 2:
19940       if (get_attr_mode (insn) == MODE_V4SF)
19941         return "movaps\t{%1, %0|%0, %1}";
19942       else
19943         return "movdqa\t{%1, %0|%0, %1}";
19944     default:
19945       abort ();
19946     }
19947 }
19948   [(set_attr "type" "ssemov,ssemov,ssemov")
19949    (set (attr "mode")
19950         (cond [(eq_attr "alternative" "0,1")
19951                  (if_then_else
19952                    (ne (symbol_ref "optimize_size")
19953                        (const_int 0))
19954                    (const_string "V4SF")
19955                    (const_string "TI"))
19956                (eq_attr "alternative" "2")
19957                  (if_then_else
19958                    (ne (symbol_ref "optimize_size")
19959                        (const_int 0))
19960                    (const_string "V4SF")
19961                    (const_string "TI"))]
19962                (const_string "TI")))])
19963
19964 (define_insn "*movti_rex64"
19965   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19966         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19967   "TARGET_64BIT
19968    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19969 {
19970   switch (which_alternative)
19971     {
19972     case 0:
19973     case 1:
19974       return "#";
19975     case 2:
19976       if (get_attr_mode (insn) == MODE_V4SF)
19977         return "xorps\t%0, %0";
19978       else
19979         return "pxor\t%0, %0";
19980     case 3:
19981     case 4:
19982       if (get_attr_mode (insn) == MODE_V4SF)
19983         return "movaps\t{%1, %0|%0, %1}";
19984       else
19985         return "movdqa\t{%1, %0|%0, %1}";
19986     default:
19987       abort ();
19988     }
19989 }
19990   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19991    (set (attr "mode")
19992         (cond [(eq_attr "alternative" "2,3")
19993                  (if_then_else
19994                    (ne (symbol_ref "optimize_size")
19995                        (const_int 0))
19996                    (const_string "V4SF")
19997                    (const_string "TI"))
19998                (eq_attr "alternative" "4")
19999                  (if_then_else
20000                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20001                             (const_int 0))
20002                         (ne (symbol_ref "optimize_size")
20003                             (const_int 0)))
20004                    (const_string "V4SF")
20005                    (const_string "TI"))]
20006                (const_string "DI")))])
20007
20008 (define_expand "movtf"
20009   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20010         (match_operand:TF 1 "nonimmediate_operand" ""))]
20011   "TARGET_64BIT"
20012 {
20013   ix86_expand_move (TFmode, operands);
20014   DONE;
20015 })
20016
20017 (define_insn "*movtf_internal"
20018   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20019         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20020   "TARGET_64BIT
20021    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20022 {
20023   switch (which_alternative)
20024     {
20025     case 0:
20026     case 1:
20027       return "#";
20028     case 2:
20029       if (get_attr_mode (insn) == MODE_V4SF)
20030         return "xorps\t%0, %0";
20031       else
20032         return "pxor\t%0, %0";
20033     case 3:
20034     case 4:
20035       if (get_attr_mode (insn) == MODE_V4SF)
20036         return "movaps\t{%1, %0|%0, %1}";
20037       else
20038         return "movdqa\t{%1, %0|%0, %1}";
20039     default:
20040       abort ();
20041     }
20042 }
20043   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20044    (set (attr "mode")
20045         (cond [(eq_attr "alternative" "2,3")
20046                  (if_then_else
20047                    (ne (symbol_ref "optimize_size")
20048                        (const_int 0))
20049                    (const_string "V4SF")
20050                    (const_string "TI"))
20051                (eq_attr "alternative" "4")
20052                  (if_then_else
20053                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20054                             (const_int 0))
20055                         (ne (symbol_ref "optimize_size")
20056                             (const_int 0)))
20057                    (const_string "V4SF")
20058                    (const_string "TI"))]
20059                (const_string "DI")))])
20060
20061 (define_mode_macro SSEPUSH [V16QI V8HI V4SI V2DI TI V4SF V2DF])
20062
20063 (define_insn "*push<mode>"
20064   [(set (match_operand:SSEPUSH 0 "push_operand" "=<")
20065         (match_operand:SSEPUSH 1 "register_operand" "x"))]
20066   "TARGET_SSE"
20067   "#")
20068
20069 (define_mode_macro MMXPUSH [V8QI V4HI V2SI V2SF])
20070
20071 (define_insn "*push<mode>"
20072   [(set (match_operand:MMXPUSH 0 "push_operand" "=<")
20073         (match_operand:MMXPUSH 1 "register_operand" "xy"))]
20074   "TARGET_MMX"
20075   "#")
20076
20077 (define_split
20078   [(set (match_operand 0 "push_operand" "")
20079         (match_operand 1 "register_operand" ""))]
20080   "!TARGET_64BIT && reload_completed
20081    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20082   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20083    (set (match_dup 2) (match_dup 1))]
20084   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20085                                  stack_pointer_rtx);
20086    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20087
20088 (define_split
20089   [(set (match_operand 0 "push_operand" "")
20090         (match_operand 1 "register_operand" ""))]
20091   "TARGET_64BIT && reload_completed
20092    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20093   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20094    (set (match_dup 2) (match_dup 1))]
20095   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20096                                  stack_pointer_rtx);
20097    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20098
20099
20100 (define_split
20101   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20102         (match_operand:TI 1 "general_operand" ""))]
20103   "reload_completed && !SSE_REG_P (operands[0])
20104    && !SSE_REG_P (operands[1])"
20105   [(const_int 0)]
20106   "ix86_split_long_move (operands); DONE;")
20107
20108 (define_split
20109   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20110         (match_operand:TF 1 "general_operand" ""))]
20111   "reload_completed && !SSE_REG_P (operands[0])
20112    && !SSE_REG_P (operands[1])"
20113   [(const_int 0)]
20114   "ix86_split_long_move (operands); DONE;")
20115
20116 ;; These two patterns are useful for specifying exactly whether to use
20117 ;; movaps or movups
20118 (define_expand "sse_movaps"
20119   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20120         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20121                      UNSPEC_MOVA))]
20122   "TARGET_SSE"
20123 {
20124   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20125     {
20126       rtx tmp = gen_reg_rtx (V4SFmode);
20127       emit_insn (gen_sse_movaps (tmp, operands[1]));
20128       emit_move_insn (operands[0], tmp);
20129       DONE;
20130     }
20131 })
20132
20133 (define_insn "*sse_movaps_1"
20134   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20135         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20136                      UNSPEC_MOVA))]
20137   "TARGET_SSE
20138    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20139   "movaps\t{%1, %0|%0, %1}"
20140   [(set_attr "type" "ssemov,ssemov")
20141    (set_attr "mode" "V4SF")])
20142
20143 (define_expand "sse_movups"
20144   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20145         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20146                      UNSPEC_MOVU))]
20147   "TARGET_SSE"
20148 {
20149   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20150     {
20151       rtx tmp = gen_reg_rtx (V4SFmode);
20152       emit_insn (gen_sse_movups (tmp, operands[1]));
20153       emit_move_insn (operands[0], tmp);
20154       DONE;
20155     }
20156 })
20157
20158 (define_insn "*sse_movups_1"
20159   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20160         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20161                      UNSPEC_MOVU))]
20162   "TARGET_SSE
20163    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20164   "movups\t{%1, %0|%0, %1}"
20165   [(set_attr "type" "ssecvt,ssecvt")
20166    (set_attr "mode" "V4SF")])
20167
20168 ;; SSE Strange Moves.
20169
20170 (define_insn "sse_movmskps"
20171   [(set (match_operand:SI 0 "register_operand" "=r")
20172         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20173                    UNSPEC_MOVMSK))]
20174   "TARGET_SSE"
20175   "movmskps\t{%1, %0|%0, %1}"
20176   [(set_attr "type" "ssecvt")
20177    (set_attr "mode" "V4SF")])
20178
20179 (define_insn "mmx_pmovmskb"
20180   [(set (match_operand:SI 0 "register_operand" "=r")
20181         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20182                    UNSPEC_MOVMSK))]
20183   "TARGET_SSE || TARGET_3DNOW_A"
20184   "pmovmskb\t{%1, %0|%0, %1}"
20185   [(set_attr "type" "ssecvt")
20186    (set_attr "mode" "V4SF")])
20187
20188
20189 (define_insn "mmx_maskmovq"
20190   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20191         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20192                       (match_operand:V8QI 2 "register_operand" "y")]
20193                      UNSPEC_MASKMOV))]
20194   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20195   ;; @@@ check ordering of operands in intel/nonintel syntax
20196   "maskmovq\t{%2, %1|%1, %2}"
20197   [(set_attr "type" "mmxcvt")
20198    (set_attr "mode" "DI")])
20199
20200 (define_insn "mmx_maskmovq_rex"
20201   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20202         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20203                       (match_operand:V8QI 2 "register_operand" "y")]
20204                      UNSPEC_MASKMOV))]
20205   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20206   ;; @@@ check ordering of operands in intel/nonintel syntax
20207   "maskmovq\t{%2, %1|%1, %2}"
20208   [(set_attr "type" "mmxcvt")
20209    (set_attr "mode" "DI")])
20210
20211 (define_insn "sse_movntv4sf"
20212   [(set (match_operand:V4SF 0 "memory_operand" "=m")
20213         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20214                      UNSPEC_MOVNT))]
20215   "TARGET_SSE"
20216   "movntps\t{%1, %0|%0, %1}"
20217   [(set_attr "type" "ssemov")
20218    (set_attr "mode" "V4SF")])
20219
20220 (define_insn "sse_movntdi"
20221   [(set (match_operand:DI 0 "memory_operand" "=m")
20222         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20223                    UNSPEC_MOVNT))]
20224   "TARGET_SSE || TARGET_3DNOW_A"
20225   "movntq\t{%1, %0|%0, %1}"
20226   [(set_attr "type" "mmxmov")
20227    (set_attr "mode" "DI")])
20228
20229 (define_insn "sse_movhlps"
20230   [(set (match_operand:V4SF 0 "register_operand" "=x")
20231         (vec_merge:V4SF
20232          (match_operand:V4SF 1 "register_operand" "0")
20233          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20234                           (parallel [(const_int 2)
20235                                      (const_int 3)
20236                                      (const_int 0)
20237                                      (const_int 1)]))
20238          (const_int 3)))]
20239   "TARGET_SSE"
20240   "movhlps\t{%2, %0|%0, %2}"
20241   [(set_attr "type" "ssecvt")
20242    (set_attr "mode" "V4SF")])
20243
20244 (define_insn "sse_movlhps"
20245   [(set (match_operand:V4SF 0 "register_operand" "=x")
20246         (vec_merge:V4SF
20247          (match_operand:V4SF 1 "register_operand" "0")
20248          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20249                           (parallel [(const_int 2)
20250                                      (const_int 3)
20251                                      (const_int 0)
20252                                      (const_int 1)]))
20253          (const_int 12)))]
20254   "TARGET_SSE"
20255   "movlhps\t{%2, %0|%0, %2}"
20256   [(set_attr "type" "ssecvt")
20257    (set_attr "mode" "V4SF")])
20258
20259 (define_insn "sse_movhps"
20260   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20261         (vec_merge:V4SF
20262          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20263          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20264          (const_int 12)))]
20265   "TARGET_SSE
20266    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20267   "movhps\t{%2, %0|%0, %2}"
20268   [(set_attr "type" "ssecvt")
20269    (set_attr "mode" "V4SF")])
20270
20271 (define_insn "sse_movlps"
20272   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20273         (vec_merge:V4SF
20274          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20275          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20276          (const_int 3)))]
20277   "TARGET_SSE
20278    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20279   "movlps\t{%2, %0|%0, %2}"
20280   [(set_attr "type" "ssecvt")
20281    (set_attr "mode" "V4SF")])
20282
20283 (define_expand "sse_loadss"
20284   [(match_operand:V4SF 0 "register_operand" "")
20285    (match_operand:SF 1 "memory_operand" "")]
20286   "TARGET_SSE"
20287 {
20288   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20289                                CONST0_RTX (V4SFmode)));
20290   DONE;
20291 })
20292
20293 (define_insn "sse_loadss_1"
20294   [(set (match_operand:V4SF 0 "register_operand" "=x")
20295         (vec_merge:V4SF
20296          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20297          (match_operand:V4SF 2 "const0_operand" "X")
20298          (const_int 1)))]
20299   "TARGET_SSE"
20300   "movss\t{%1, %0|%0, %1}"
20301   [(set_attr "type" "ssemov")
20302    (set_attr "mode" "SF")])
20303
20304 (define_insn "sse_movss"
20305   [(set (match_operand:V4SF 0 "register_operand" "=x")
20306         (vec_merge:V4SF
20307          (match_operand:V4SF 1 "register_operand" "0")
20308          (match_operand:V4SF 2 "register_operand" "x")
20309          (const_int 14)))]
20310   "TARGET_SSE"
20311   "movss\t{%2, %0|%0, %2}"
20312   [(set_attr "type" "ssemov")
20313    (set_attr "mode" "SF")])
20314
20315 (define_insn "sse_storess"
20316   [(set (match_operand:SF 0 "memory_operand" "=m")
20317         (vec_select:SF
20318          (match_operand:V4SF 1 "register_operand" "x")
20319          (parallel [(const_int 0)])))]
20320   "TARGET_SSE"
20321   "movss\t{%1, %0|%0, %1}"
20322   [(set_attr "type" "ssemov")
20323    (set_attr "mode" "SF")])
20324
20325 (define_insn "sse_shufps"
20326   [(set (match_operand:V4SF 0 "register_operand" "=x")
20327         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20328                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20329                       (match_operand:SI 3 "immediate_operand" "i")]
20330                      UNSPEC_SHUFFLE))]
20331   "TARGET_SSE"
20332   ;; @@@ check operand order for intel/nonintel syntax
20333   "shufps\t{%3, %2, %0|%0, %2, %3}"
20334   [(set_attr "type" "ssecvt")
20335    (set_attr "mode" "V4SF")])
20336
20337
20338 ;; SSE arithmetic
20339
20340 (define_insn "addv4sf3"
20341   [(set (match_operand:V4SF 0 "register_operand" "=x")
20342         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20343                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20344   "TARGET_SSE"
20345   "addps\t{%2, %0|%0, %2}"
20346   [(set_attr "type" "sseadd")
20347    (set_attr "mode" "V4SF")])
20348
20349 (define_insn "vmaddv4sf3"
20350   [(set (match_operand:V4SF 0 "register_operand" "=x")
20351         (vec_merge:V4SF
20352          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20353                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20354          (match_dup 1)
20355          (const_int 1)))]
20356   "TARGET_SSE"
20357   "addss\t{%2, %0|%0, %2}"
20358   [(set_attr "type" "sseadd")
20359    (set_attr "mode" "SF")])
20360
20361 (define_insn "subv4sf3"
20362   [(set (match_operand:V4SF 0 "register_operand" "=x")
20363         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20364                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20365   "TARGET_SSE"
20366   "subps\t{%2, %0|%0, %2}"
20367   [(set_attr "type" "sseadd")
20368    (set_attr "mode" "V4SF")])
20369
20370 (define_insn "vmsubv4sf3"
20371   [(set (match_operand:V4SF 0 "register_operand" "=x")
20372         (vec_merge:V4SF
20373          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20374                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20375          (match_dup 1)
20376          (const_int 1)))]
20377   "TARGET_SSE"
20378   "subss\t{%2, %0|%0, %2}"
20379   [(set_attr "type" "sseadd")
20380    (set_attr "mode" "SF")])
20381
20382 ;; ??? Should probably be done by generic code instead.
20383 (define_expand "negv4sf2"
20384   [(set (match_operand:V4SF 0 "register_operand" "")
20385         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20386                   (match_dup 2)))]
20387   "TARGET_SSE"
20388 {
20389   rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20390   rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20391   operands[2] = force_reg (V4SFmode, vm0);
20392 })
20393
20394 (define_insn "mulv4sf3"
20395   [(set (match_operand:V4SF 0 "register_operand" "=x")
20396         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20397                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20398   "TARGET_SSE"
20399   "mulps\t{%2, %0|%0, %2}"
20400   [(set_attr "type" "ssemul")
20401    (set_attr "mode" "V4SF")])
20402
20403 (define_insn "vmmulv4sf3"
20404   [(set (match_operand:V4SF 0 "register_operand" "=x")
20405         (vec_merge:V4SF
20406          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20407                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20408          (match_dup 1)
20409          (const_int 1)))]
20410   "TARGET_SSE"
20411   "mulss\t{%2, %0|%0, %2}"
20412   [(set_attr "type" "ssemul")
20413    (set_attr "mode" "SF")])
20414
20415 (define_insn "divv4sf3"
20416   [(set (match_operand:V4SF 0 "register_operand" "=x")
20417         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20418                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20419   "TARGET_SSE"
20420   "divps\t{%2, %0|%0, %2}"
20421   [(set_attr "type" "ssediv")
20422    (set_attr "mode" "V4SF")])
20423
20424 (define_insn "vmdivv4sf3"
20425   [(set (match_operand:V4SF 0 "register_operand" "=x")
20426         (vec_merge:V4SF
20427          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20428                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20429          (match_dup 1)
20430          (const_int 1)))]
20431   "TARGET_SSE"
20432   "divss\t{%2, %0|%0, %2}"
20433   [(set_attr "type" "ssediv")
20434    (set_attr "mode" "SF")])
20435
20436
20437 ;; SSE square root/reciprocal
20438
20439 (define_insn "rcpv4sf2"
20440   [(set (match_operand:V4SF 0 "register_operand" "=x")
20441         (unspec:V4SF
20442          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20443   "TARGET_SSE"
20444   "rcpps\t{%1, %0|%0, %1}"
20445   [(set_attr "type" "sse")
20446    (set_attr "mode" "V4SF")])
20447
20448 (define_insn "vmrcpv4sf2"
20449   [(set (match_operand:V4SF 0 "register_operand" "=x")
20450         (vec_merge:V4SF
20451          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20452                       UNSPEC_RCP)
20453          (match_operand:V4SF 2 "register_operand" "0")
20454          (const_int 1)))]
20455   "TARGET_SSE"
20456   "rcpss\t{%1, %0|%0, %1}"
20457   [(set_attr "type" "sse")
20458    (set_attr "mode" "SF")])
20459
20460 (define_insn "rsqrtv4sf2"
20461   [(set (match_operand:V4SF 0 "register_operand" "=x")
20462         (unspec:V4SF
20463          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20464   "TARGET_SSE"
20465   "rsqrtps\t{%1, %0|%0, %1}"
20466   [(set_attr "type" "sse")
20467    (set_attr "mode" "V4SF")])
20468
20469 (define_insn "vmrsqrtv4sf2"
20470   [(set (match_operand:V4SF 0 "register_operand" "=x")
20471         (vec_merge:V4SF
20472          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20473                       UNSPEC_RSQRT)
20474          (match_operand:V4SF 2 "register_operand" "0")
20475          (const_int 1)))]
20476   "TARGET_SSE"
20477   "rsqrtss\t{%1, %0|%0, %1}"
20478   [(set_attr "type" "sse")
20479    (set_attr "mode" "SF")])
20480
20481 (define_insn "sqrtv4sf2"
20482   [(set (match_operand:V4SF 0 "register_operand" "=x")
20483         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20484   "TARGET_SSE"
20485   "sqrtps\t{%1, %0|%0, %1}"
20486   [(set_attr "type" "sse")
20487    (set_attr "mode" "V4SF")])
20488
20489 (define_insn "vmsqrtv4sf2"
20490   [(set (match_operand:V4SF 0 "register_operand" "=x")
20491         (vec_merge:V4SF
20492          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20493          (match_operand:V4SF 2 "register_operand" "0")
20494          (const_int 1)))]
20495   "TARGET_SSE"
20496   "sqrtss\t{%1, %0|%0, %1}"
20497   [(set_attr "type" "sse")
20498    (set_attr "mode" "SF")])
20499
20500 ;; SSE logical operations.
20501
20502 ;; SSE defines logical operations on floating point values.  This brings
20503 ;; interesting challenge to RTL representation where logicals are only valid
20504 ;; on integral types.  We deal with this by representing the floating point
20505 ;; logical as logical on arguments casted to TImode as this is what hardware
20506 ;; really does.  Unfortunately hardware requires the type information to be
20507 ;; present and thus we must avoid subregs from being simplified and eliminated
20508 ;; in later compilation phases.
20509 ;;
20510 ;; We have following variants from each instruction:
20511 ;; sse_andsf3 - the operation taking V4SF vector operands
20512 ;;              and doing TImode cast on them
20513 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20514 ;;                      TImode, since backend insist on eliminating casts
20515 ;;                      on memory operands
20516 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20517 ;;                   We cannot accept memory operand here as instruction reads
20518 ;;                   whole scalar.  This is generated only post reload by GCC
20519 ;;                   scalar float operations that expands to logicals (fabs)
20520 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20521 ;;                   memory operand.  Eventually combine can be able
20522 ;;                   to synthesize these using splitter.
20523 ;; sse2_anddf3, *sse2_anddf3_memory
20524 ;;              
20525 ;; 
20526 ;; These are not called andti3 etc. because we really really don't want
20527 ;; the compiler to widen DImode ands to TImode ands and then try to move
20528 ;; into DImode subregs of SSE registers, and them together, and move out
20529 ;; of DImode subregs again!
20530 ;; SSE1 single precision floating point logical operation
20531 (define_expand "sse_andv4sf3"
20532   [(set (match_operand:V4SF 0 "register_operand" "")
20533         (and:V4SF (match_operand:V4SF 1 "register_operand" "")
20534                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20535   "TARGET_SSE"
20536   "")
20537
20538 (define_insn "*sse_andv4sf3"
20539   [(set (match_operand:V4SF 0 "register_operand" "=x")
20540         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20541                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20542   "TARGET_SSE
20543    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20544   "andps\t{%2, %0|%0, %2}"
20545   [(set_attr "type" "sselog")
20546    (set_attr "mode" "V4SF")])
20547
20548 (define_expand "sse_nandv4sf3"
20549   [(set (match_operand:V4SF 0 "register_operand" "")
20550         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
20551                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20552   "TARGET_SSE"
20553   "")
20554
20555 (define_insn "*sse_nandv4sf3"
20556   [(set (match_operand:V4SF 0 "register_operand" "=x")
20557         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
20558                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20559   "TARGET_SSE"
20560   "andnps\t{%2, %0|%0, %2}"
20561   [(set_attr "type" "sselog")
20562    (set_attr "mode" "V4SF")])
20563
20564 (define_expand "sse_iorv4sf3"
20565   [(set (match_operand:V4SF 0 "register_operand" "")
20566         (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
20567                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20568   "TARGET_SSE"
20569   "")
20570
20571 (define_insn "*sse_iorv4sf3"
20572   [(set (match_operand:V4SF 0 "register_operand" "=x")
20573         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20574                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20575   "TARGET_SSE
20576    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20577   "orps\t{%2, %0|%0, %2}"
20578   [(set_attr "type" "sselog")
20579    (set_attr "mode" "V4SF")])
20580
20581 (define_expand "sse_xorv4sf3"
20582   [(set (match_operand:V4SF 0 "register_operand" "")
20583         (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
20584                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20585   "TARGET_SSE"
20586   "")
20587
20588 (define_insn "*sse_xorv4sf3"
20589   [(set (match_operand:V4SF 0 "register_operand" "=x")
20590         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20591                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20592   "TARGET_SSE
20593    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20594   "xorps\t{%2, %0|%0, %2}"
20595   [(set_attr "type" "sselog")
20596    (set_attr "mode" "V4SF")])
20597
20598 ;; SSE2 double precision floating point logical operation
20599
20600 (define_expand "sse2_andv2df3"
20601   [(set (match_operand:V2DF 0 "register_operand" "")
20602         (and:V2DF (match_operand:V2DF 1 "register_operand" "")
20603                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20604   "TARGET_SSE2"
20605   "")
20606
20607 (define_insn "*sse2_andv2df3"
20608   [(set (match_operand:V2DF 0 "register_operand" "=x")
20609         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20610                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20611   "TARGET_SSE2
20612    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20613   "andpd\t{%2, %0|%0, %2}"
20614   [(set_attr "type" "sselog")
20615    (set_attr "mode" "V2DF")])
20616
20617 (define_expand "sse2_nandv2df3"
20618   [(set (match_operand:V2DF 0 "register_operand" "")
20619         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
20620                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20621   "TARGET_SSE2"
20622   "")
20623
20624 (define_insn "*sse2_nandv2df3"
20625   [(set (match_operand:V2DF 0 "register_operand" "=x")
20626         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
20627                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20628   "TARGET_SSE2"
20629   "andnpd\t{%2, %0|%0, %2}"
20630   [(set_attr "type" "sselog")
20631    (set_attr "mode" "V2DF")])
20632
20633 (define_expand "sse2_iorv2df3"
20634   [(set (match_operand:V2DF 0 "register_operand" "")
20635         (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
20636                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20637   "TARGET_SSE2"
20638   "")
20639
20640 (define_insn "*sse2_iorv2df3"
20641   [(set (match_operand:V2DF 0 "register_operand" "=x")
20642         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20643                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20644   "TARGET_SSE2
20645    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20646   "orpd\t{%2, %0|%0, %2}"
20647   [(set_attr "type" "sselog")
20648    (set_attr "mode" "V2DF")])
20649
20650 (define_expand "sse2_xorv2df3"
20651   [(set (match_operand:V2DF 0 "register_operand" "")
20652         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
20653                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20654   "TARGET_SSE2"
20655   "")
20656
20657 (define_insn "*sse2_xorv2df3"
20658   [(set (match_operand:V2DF 0 "register_operand" "=x")
20659         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20660                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20661   "TARGET_SSE2
20662    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20663   "xorpd\t{%2, %0|%0, %2}"
20664   [(set_attr "type" "sselog")
20665    (set_attr "mode" "V2DF")])
20666
20667 ;; SSE2 integral logicals.  These patterns must always come after floating
20668 ;; point ones since we don't want compiler to use integer opcodes on floating
20669 ;; point SSE values to avoid matching of subregs in the match_operand.
20670 (define_insn "*sse2_andti3"
20671   [(set (match_operand:TI 0 "register_operand" "=x")
20672         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20673                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20674   "TARGET_SSE2
20675    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20676   "pand\t{%2, %0|%0, %2}"
20677   [(set_attr "type" "sselog")
20678    (set_attr "mode" "TI")])
20679
20680 (define_insn "sse2_andv2di3"
20681   [(set (match_operand:V2DI 0 "register_operand" "=x")
20682         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20683                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20684   "TARGET_SSE2
20685    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20686   "pand\t{%2, %0|%0, %2}"
20687   [(set_attr "type" "sselog")
20688    (set_attr "mode" "TI")])
20689
20690 (define_insn "*sse2_nandti3"
20691   [(set (match_operand:TI 0 "register_operand" "=x")
20692         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20693                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20694   "TARGET_SSE2"
20695   "pandn\t{%2, %0|%0, %2}"
20696   [(set_attr "type" "sselog")
20697    (set_attr "mode" "TI")])
20698
20699 (define_insn "sse2_nandv2di3"
20700   [(set (match_operand:V2DI 0 "register_operand" "=x")
20701         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20702                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20703   "TARGET_SSE2
20704    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20705   "pandn\t{%2, %0|%0, %2}"
20706   [(set_attr "type" "sselog")
20707    (set_attr "mode" "TI")])
20708
20709 (define_insn "*sse2_iorti3"
20710   [(set (match_operand:TI 0 "register_operand" "=x")
20711         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20712                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20713   "TARGET_SSE2
20714    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20715   "por\t{%2, %0|%0, %2}"
20716   [(set_attr "type" "sselog")
20717    (set_attr "mode" "TI")])
20718
20719 (define_insn "sse2_iorv2di3"
20720   [(set (match_operand:V2DI 0 "register_operand" "=x")
20721         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20722                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20723   "TARGET_SSE2
20724    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20725   "por\t{%2, %0|%0, %2}"
20726   [(set_attr "type" "sselog")
20727    (set_attr "mode" "TI")])
20728
20729 (define_insn "*sse2_xorti3"
20730   [(set (match_operand:TI 0 "register_operand" "=x")
20731         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20732                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20733   "TARGET_SSE2
20734    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20735   "pxor\t{%2, %0|%0, %2}"
20736   [(set_attr "type" "sselog")
20737    (set_attr "mode" "TI")])
20738
20739 (define_insn "sse2_xorv2di3"
20740   [(set (match_operand:V2DI 0 "register_operand" "=x")
20741         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20742                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20743   "TARGET_SSE2
20744    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20745   "pxor\t{%2, %0|%0, %2}"
20746   [(set_attr "type" "sselog")
20747    (set_attr "mode" "TI")])
20748
20749 ;; Use xor, but don't show input operands so they aren't live before
20750 ;; this insn.
20751 (define_insn "sse_clrv4sf"
20752   [(set (match_operand:V4SF 0 "register_operand" "=x")
20753         (match_operand:V4SF 1 "const0_operand" "X"))]
20754   "TARGET_SSE"
20755 {
20756   if (get_attr_mode (insn) == MODE_TI)
20757     return "pxor\t{%0, %0|%0, %0}";
20758   else
20759     return "xorps\t{%0, %0|%0, %0}";
20760 }
20761   [(set_attr "type" "sselog")
20762    (set_attr "memory" "none")
20763    (set (attr "mode")
20764         (if_then_else
20765            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
20766                          (const_int 0))
20767                      (ne (symbol_ref "TARGET_SSE2")
20768                          (const_int 0)))
20769                 (eq (symbol_ref "optimize_size")
20770                     (const_int 0)))
20771          (const_string "TI")
20772          (const_string "V4SF")))])
20773
20774 ;; Use xor, but don't show input operands so they aren't live before
20775 ;; this insn.
20776 (define_insn "sse_clrv2df"
20777   [(set (match_operand:V2DF 0 "register_operand" "=x")
20778         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
20779   "TARGET_SSE2"
20780   "xorpd\t{%0, %0|%0, %0}"
20781   [(set_attr "type" "sselog")
20782    (set_attr "memory" "none")
20783    (set_attr "mode" "V4SF")])
20784
20785 ;; SSE mask-generating compares
20786
20787 (define_insn "maskcmpv4sf3"
20788   [(set (match_operand:V4SI 0 "register_operand" "=x")
20789         (match_operator:V4SI 3 "sse_comparison_operator"
20790                 [(match_operand:V4SF 1 "register_operand" "0")
20791                  (match_operand:V4SF 2 "register_operand" "x")]))]
20792   "TARGET_SSE"
20793   "cmp%D3ps\t{%2, %0|%0, %2}"
20794   [(set_attr "type" "ssecmp")
20795    (set_attr "mode" "V4SF")])
20796
20797 (define_insn "maskncmpv4sf3"
20798   [(set (match_operand:V4SI 0 "register_operand" "=x")
20799         (not:V4SI
20800          (match_operator:V4SI 3 "sse_comparison_operator"
20801                 [(match_operand:V4SF 1 "register_operand" "0")
20802                  (match_operand:V4SF 2 "register_operand" "x")])))]
20803   "TARGET_SSE"
20804 {
20805   if (GET_CODE (operands[3]) == UNORDERED)
20806     return "cmpordps\t{%2, %0|%0, %2}";
20807   else
20808     return "cmpn%D3ps\t{%2, %0|%0, %2}";
20809 }
20810   [(set_attr "type" "ssecmp")
20811    (set_attr "mode" "V4SF")])
20812
20813 (define_insn "vmmaskcmpv4sf3"
20814   [(set (match_operand:V4SI 0 "register_operand" "=x")
20815         (vec_merge:V4SI
20816          (match_operator:V4SI 3 "sse_comparison_operator"
20817                 [(match_operand:V4SF 1 "register_operand" "0")
20818                  (match_operand:V4SF 2 "register_operand" "x")])
20819          (subreg:V4SI (match_dup 1) 0)
20820          (const_int 1)))]
20821   "TARGET_SSE"
20822   "cmp%D3ss\t{%2, %0|%0, %2}"
20823   [(set_attr "type" "ssecmp")
20824    (set_attr "mode" "SF")])
20825
20826 (define_insn "vmmaskncmpv4sf3"
20827   [(set (match_operand:V4SI 0 "register_operand" "=x")
20828         (vec_merge:V4SI
20829          (not:V4SI
20830           (match_operator:V4SI 3 "sse_comparison_operator"
20831                 [(match_operand:V4SF 1 "register_operand" "0")
20832                  (match_operand:V4SF 2 "register_operand" "x")]))
20833          (subreg:V4SI (match_dup 1) 0)
20834          (const_int 1)))]
20835   "TARGET_SSE"
20836 {
20837   if (GET_CODE (operands[3]) == UNORDERED)
20838     return "cmpordss\t{%2, %0|%0, %2}";
20839   else
20840     return "cmpn%D3ss\t{%2, %0|%0, %2}";
20841 }
20842   [(set_attr "type" "ssecmp")
20843    (set_attr "mode" "SF")])
20844
20845 (define_insn "sse_comi"
20846   [(set (reg:CCFP FLAGS_REG)
20847         (compare:CCFP (vec_select:SF
20848                        (match_operand:V4SF 0 "register_operand" "x")
20849                        (parallel [(const_int 0)]))
20850                       (vec_select:SF
20851                        (match_operand:V4SF 1 "register_operand" "x")
20852                        (parallel [(const_int 0)]))))]
20853   "TARGET_SSE"
20854   "comiss\t{%1, %0|%0, %1}"
20855   [(set_attr "type" "ssecomi")
20856    (set_attr "mode" "SF")])
20857
20858 (define_insn "sse_ucomi"
20859   [(set (reg:CCFPU FLAGS_REG)
20860         (compare:CCFPU (vec_select:SF
20861                         (match_operand:V4SF 0 "register_operand" "x")
20862                         (parallel [(const_int 0)]))
20863                        (vec_select:SF
20864                         (match_operand:V4SF 1 "register_operand" "x")
20865                         (parallel [(const_int 0)]))))]
20866   "TARGET_SSE"
20867   "ucomiss\t{%1, %0|%0, %1}"
20868   [(set_attr "type" "ssecomi")
20869    (set_attr "mode" "SF")])
20870
20871
20872 ;; SSE unpack
20873
20874 (define_insn "sse_unpckhps"
20875   [(set (match_operand:V4SF 0 "register_operand" "=x")
20876         (vec_merge:V4SF
20877          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20878                           (parallel [(const_int 2)
20879                                      (const_int 0)
20880                                      (const_int 3)
20881                                      (const_int 1)]))
20882          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20883                           (parallel [(const_int 0)
20884                                      (const_int 2)
20885                                      (const_int 1)
20886                                      (const_int 3)]))
20887          (const_int 5)))]
20888   "TARGET_SSE"
20889   "unpckhps\t{%2, %0|%0, %2}"
20890   [(set_attr "type" "ssecvt")
20891    (set_attr "mode" "V4SF")])
20892
20893 (define_insn "sse_unpcklps"
20894   [(set (match_operand:V4SF 0 "register_operand" "=x")
20895         (vec_merge:V4SF
20896          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20897                           (parallel [(const_int 0)
20898                                      (const_int 2)
20899                                      (const_int 1)
20900                                      (const_int 3)]))
20901          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20902                           (parallel [(const_int 2)
20903                                      (const_int 0)
20904                                      (const_int 3)
20905                                      (const_int 1)]))
20906          (const_int 5)))]
20907   "TARGET_SSE"
20908   "unpcklps\t{%2, %0|%0, %2}"
20909   [(set_attr "type" "ssecvt")
20910    (set_attr "mode" "V4SF")])
20911
20912
20913 ;; SSE min/max
20914
20915 (define_insn "smaxv4sf3"
20916   [(set (match_operand:V4SF 0 "register_operand" "=x")
20917         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20918                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20919   "TARGET_SSE"
20920   "maxps\t{%2, %0|%0, %2}"
20921   [(set_attr "type" "sse")
20922    (set_attr "mode" "V4SF")])
20923
20924 (define_insn "vmsmaxv4sf3"
20925   [(set (match_operand:V4SF 0 "register_operand" "=x")
20926         (vec_merge:V4SF
20927          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20928                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20929          (match_dup 1)
20930          (const_int 1)))]
20931   "TARGET_SSE"
20932   "maxss\t{%2, %0|%0, %2}"
20933   [(set_attr "type" "sse")
20934    (set_attr "mode" "SF")])
20935
20936 (define_insn "sminv4sf3"
20937   [(set (match_operand:V4SF 0 "register_operand" "=x")
20938         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20939                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20940   "TARGET_SSE"
20941   "minps\t{%2, %0|%0, %2}"
20942   [(set_attr "type" "sse")
20943    (set_attr "mode" "V4SF")])
20944
20945 (define_insn "vmsminv4sf3"
20946   [(set (match_operand:V4SF 0 "register_operand" "=x")
20947         (vec_merge:V4SF
20948          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20949                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20950          (match_dup 1)
20951          (const_int 1)))]
20952   "TARGET_SSE"
20953   "minss\t{%2, %0|%0, %2}"
20954   [(set_attr "type" "sse")
20955    (set_attr "mode" "SF")])
20956
20957 ;; SSE <-> integer/MMX conversions
20958
20959 (define_insn "cvtpi2ps"
20960   [(set (match_operand:V4SF 0 "register_operand" "=x")
20961         (vec_merge:V4SF
20962          (match_operand:V4SF 1 "register_operand" "0")
20963          (vec_duplicate:V4SF
20964           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20965          (const_int 12)))]
20966   "TARGET_SSE"
20967   "cvtpi2ps\t{%2, %0|%0, %2}"
20968   [(set_attr "type" "ssecvt")
20969    (set_attr "mode" "V4SF")])
20970
20971 (define_insn "cvtps2pi"
20972   [(set (match_operand:V2SI 0 "register_operand" "=y")
20973         (vec_select:V2SI
20974          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20975          (parallel [(const_int 0) (const_int 1)])))]
20976   "TARGET_SSE"
20977   "cvtps2pi\t{%1, %0|%0, %1}"
20978   [(set_attr "type" "ssecvt")
20979    (set_attr "mode" "V4SF")])
20980
20981 (define_insn "cvttps2pi"
20982   [(set (match_operand:V2SI 0 "register_operand" "=y")
20983         (vec_select:V2SI
20984          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20985                       UNSPEC_FIX)
20986          (parallel [(const_int 0) (const_int 1)])))]
20987   "TARGET_SSE"
20988   "cvttps2pi\t{%1, %0|%0, %1}"
20989   [(set_attr "type" "ssecvt")
20990    (set_attr "mode" "SF")])
20991
20992 (define_insn "cvtsi2ss"
20993   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20994         (vec_merge:V4SF
20995          (match_operand:V4SF 1 "register_operand" "0,0")
20996          (vec_duplicate:V4SF
20997           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20998          (const_int 14)))]
20999   "TARGET_SSE"
21000   "cvtsi2ss\t{%2, %0|%0, %2}"
21001   [(set_attr "type" "sseicvt")
21002    (set_attr "athlon_decode" "vector,double")
21003    (set_attr "mode" "SF")])
21004
21005 (define_insn "cvtsi2ssq"
21006   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21007         (vec_merge:V4SF
21008          (match_operand:V4SF 1 "register_operand" "0,0")
21009          (vec_duplicate:V4SF
21010           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21011          (const_int 14)))]
21012   "TARGET_SSE && TARGET_64BIT"
21013   "cvtsi2ssq\t{%2, %0|%0, %2}"
21014   [(set_attr "type" "sseicvt")
21015    (set_attr "athlon_decode" "vector,double")
21016    (set_attr "mode" "SF")])
21017
21018 (define_insn "cvtss2si"
21019   [(set (match_operand:SI 0 "register_operand" "=r,r")
21020         (vec_select:SI
21021          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21022          (parallel [(const_int 0)])))]
21023   "TARGET_SSE"
21024   "cvtss2si\t{%1, %0|%0, %1}"
21025   [(set_attr "type" "sseicvt")
21026    (set_attr "athlon_decode" "double,vector")
21027    (set_attr "mode" "SI")])
21028
21029 (define_insn "cvtss2siq"
21030   [(set (match_operand:DI 0 "register_operand" "=r,r")
21031         (vec_select:DI
21032          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21033          (parallel [(const_int 0)])))]
21034   "TARGET_SSE"
21035   "cvtss2siq\t{%1, %0|%0, %1}"
21036   [(set_attr "type" "sseicvt")
21037    (set_attr "athlon_decode" "double,vector")
21038    (set_attr "mode" "DI")])
21039
21040 (define_insn "cvttss2si"
21041   [(set (match_operand:SI 0 "register_operand" "=r,r")
21042         (vec_select:SI
21043          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21044                       UNSPEC_FIX)
21045          (parallel [(const_int 0)])))]
21046   "TARGET_SSE"
21047   "cvttss2si\t{%1, %0|%0, %1}"
21048   [(set_attr "type" "sseicvt")
21049    (set_attr "mode" "SF")
21050    (set_attr "athlon_decode" "double,vector")])
21051
21052 (define_insn "cvttss2siq"
21053   [(set (match_operand:DI 0 "register_operand" "=r,r")
21054         (vec_select:DI
21055          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21056                       UNSPEC_FIX)
21057          (parallel [(const_int 0)])))]
21058   "TARGET_SSE && TARGET_64BIT"
21059   "cvttss2siq\t{%1, %0|%0, %1}"
21060   [(set_attr "type" "sseicvt")
21061    (set_attr "mode" "SF")
21062    (set_attr "athlon_decode" "double,vector")])
21063
21064
21065 ;; MMX insns
21066
21067 ;; MMX arithmetic
21068
21069 (define_insn "addv8qi3"
21070   [(set (match_operand:V8QI 0 "register_operand" "=y")
21071         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21072                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21073   "TARGET_MMX"
21074   "paddb\t{%2, %0|%0, %2}"
21075   [(set_attr "type" "mmxadd")
21076    (set_attr "mode" "DI")])
21077
21078 (define_insn "addv4hi3"
21079   [(set (match_operand:V4HI 0 "register_operand" "=y")
21080         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21081                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21082   "TARGET_MMX"
21083   "paddw\t{%2, %0|%0, %2}"
21084   [(set_attr "type" "mmxadd")
21085    (set_attr "mode" "DI")])
21086
21087 (define_insn "addv2si3"
21088   [(set (match_operand:V2SI 0 "register_operand" "=y")
21089         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21090                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21091   "TARGET_MMX"
21092   "paddd\t{%2, %0|%0, %2}"
21093   [(set_attr "type" "mmxadd")
21094    (set_attr "mode" "DI")])
21095
21096 (define_insn "mmx_adddi3"
21097   [(set (match_operand:DI 0 "register_operand" "=y")
21098         (unspec:DI
21099          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21100                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21101          UNSPEC_NOP))]
21102   "TARGET_MMX"
21103   "paddq\t{%2, %0|%0, %2}"
21104   [(set_attr "type" "mmxadd")
21105    (set_attr "mode" "DI")])
21106
21107 (define_insn "ssaddv8qi3"
21108   [(set (match_operand:V8QI 0 "register_operand" "=y")
21109         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21110                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21111   "TARGET_MMX"
21112   "paddsb\t{%2, %0|%0, %2}"
21113   [(set_attr "type" "mmxadd")
21114    (set_attr "mode" "DI")])
21115
21116 (define_insn "ssaddv4hi3"
21117   [(set (match_operand:V4HI 0 "register_operand" "=y")
21118         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21119                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21120   "TARGET_MMX"
21121   "paddsw\t{%2, %0|%0, %2}"
21122   [(set_attr "type" "mmxadd")
21123    (set_attr "mode" "DI")])
21124
21125 (define_insn "usaddv8qi3"
21126   [(set (match_operand:V8QI 0 "register_operand" "=y")
21127         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21128                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21129   "TARGET_MMX"
21130   "paddusb\t{%2, %0|%0, %2}"
21131   [(set_attr "type" "mmxadd")
21132    (set_attr "mode" "DI")])
21133
21134 (define_insn "usaddv4hi3"
21135   [(set (match_operand:V4HI 0 "register_operand" "=y")
21136         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21137                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21138   "TARGET_MMX"
21139   "paddusw\t{%2, %0|%0, %2}"
21140   [(set_attr "type" "mmxadd")
21141    (set_attr "mode" "DI")])
21142
21143 (define_insn "subv8qi3"
21144   [(set (match_operand:V8QI 0 "register_operand" "=y")
21145         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21146                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21147   "TARGET_MMX"
21148   "psubb\t{%2, %0|%0, %2}"
21149   [(set_attr "type" "mmxadd")
21150    (set_attr "mode" "DI")])
21151
21152 (define_insn "subv4hi3"
21153   [(set (match_operand:V4HI 0 "register_operand" "=y")
21154         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21155                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21156   "TARGET_MMX"
21157   "psubw\t{%2, %0|%0, %2}"
21158   [(set_attr "type" "mmxadd")
21159    (set_attr "mode" "DI")])
21160
21161 (define_insn "subv2si3"
21162   [(set (match_operand:V2SI 0 "register_operand" "=y")
21163         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21164                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21165   "TARGET_MMX"
21166   "psubd\t{%2, %0|%0, %2}"
21167   [(set_attr "type" "mmxadd")
21168    (set_attr "mode" "DI")])
21169
21170 (define_insn "mmx_subdi3"
21171   [(set (match_operand:DI 0 "register_operand" "=y")
21172         (unspec:DI
21173          [(minus:DI (match_operand:DI 1 "register_operand" "0")
21174                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21175          UNSPEC_NOP))]
21176   "TARGET_MMX"
21177   "psubq\t{%2, %0|%0, %2}"
21178   [(set_attr "type" "mmxadd")
21179    (set_attr "mode" "DI")])
21180
21181 (define_insn "sssubv8qi3"
21182   [(set (match_operand:V8QI 0 "register_operand" "=y")
21183         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21184                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21185   "TARGET_MMX"
21186   "psubsb\t{%2, %0|%0, %2}"
21187   [(set_attr "type" "mmxadd")
21188    (set_attr "mode" "DI")])
21189
21190 (define_insn "sssubv4hi3"
21191   [(set (match_operand:V4HI 0 "register_operand" "=y")
21192         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21193                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21194   "TARGET_MMX"
21195   "psubsw\t{%2, %0|%0, %2}"
21196   [(set_attr "type" "mmxadd")
21197    (set_attr "mode" "DI")])
21198
21199 (define_insn "ussubv8qi3"
21200   [(set (match_operand:V8QI 0 "register_operand" "=y")
21201         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21202                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21203   "TARGET_MMX"
21204   "psubusb\t{%2, %0|%0, %2}"
21205   [(set_attr "type" "mmxadd")
21206    (set_attr "mode" "DI")])
21207
21208 (define_insn "ussubv4hi3"
21209   [(set (match_operand:V4HI 0 "register_operand" "=y")
21210         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21211                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21212   "TARGET_MMX"
21213   "psubusw\t{%2, %0|%0, %2}"
21214   [(set_attr "type" "mmxadd")
21215    (set_attr "mode" "DI")])
21216
21217 (define_insn "mulv4hi3"
21218   [(set (match_operand:V4HI 0 "register_operand" "=y")
21219         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21220                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21221   "TARGET_MMX"
21222   "pmullw\t{%2, %0|%0, %2}"
21223   [(set_attr "type" "mmxmul")
21224    (set_attr "mode" "DI")])
21225
21226 (define_insn "smulv4hi3_highpart"
21227   [(set (match_operand:V4HI 0 "register_operand" "=y")
21228         (truncate:V4HI
21229          (lshiftrt:V4SI
21230           (mult:V4SI (sign_extend:V4SI
21231                       (match_operand:V4HI 1 "register_operand" "0"))
21232                      (sign_extend:V4SI
21233                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21234           (const_int 16))))]
21235   "TARGET_MMX"
21236   "pmulhw\t{%2, %0|%0, %2}"
21237   [(set_attr "type" "mmxmul")
21238    (set_attr "mode" "DI")])
21239
21240 (define_insn "umulv4hi3_highpart"
21241   [(set (match_operand:V4HI 0 "register_operand" "=y")
21242         (truncate:V4HI
21243          (lshiftrt:V4SI
21244           (mult:V4SI (zero_extend:V4SI
21245                       (match_operand:V4HI 1 "register_operand" "0"))
21246                      (zero_extend:V4SI
21247                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21248           (const_int 16))))]
21249   "TARGET_SSE || TARGET_3DNOW_A"
21250   "pmulhuw\t{%2, %0|%0, %2}"
21251   [(set_attr "type" "mmxmul")
21252    (set_attr "mode" "DI")])
21253
21254 (define_insn "mmx_pmaddwd"
21255   [(set (match_operand:V2SI 0 "register_operand" "=y")
21256         (plus:V2SI
21257          (mult:V2SI
21258           (sign_extend:V2SI
21259            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21260                             (parallel [(const_int 0) (const_int 2)])))
21261           (sign_extend:V2SI
21262            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21263                             (parallel [(const_int 0) (const_int 2)]))))
21264          (mult:V2SI
21265           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21266                                              (parallel [(const_int 1)
21267                                                         (const_int 3)])))
21268           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21269                                              (parallel [(const_int 1)
21270                                                         (const_int 3)]))))))]
21271   "TARGET_MMX"
21272   "pmaddwd\t{%2, %0|%0, %2}"
21273   [(set_attr "type" "mmxmul")
21274    (set_attr "mode" "DI")])
21275
21276
21277 ;; MMX logical operations
21278 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21279 ;; normal code that also wants to use the FPU from getting broken.
21280 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21281 (define_insn "mmx_iordi3"
21282   [(set (match_operand:DI 0 "register_operand" "=y")
21283         (unspec:DI
21284          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21285                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21286          UNSPEC_NOP))]
21287   "TARGET_MMX"
21288   "por\t{%2, %0|%0, %2}"
21289   [(set_attr "type" "mmxadd")
21290    (set_attr "mode" "DI")])
21291
21292 (define_insn "mmx_xordi3"
21293   [(set (match_operand:DI 0 "register_operand" "=y")
21294         (unspec:DI
21295          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21296                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21297          UNSPEC_NOP))]
21298   "TARGET_MMX"
21299   "pxor\t{%2, %0|%0, %2}"
21300   [(set_attr "type" "mmxadd")
21301    (set_attr "mode" "DI")
21302    (set_attr "memory" "none")])
21303
21304 ;; Same as pxor, but don't show input operands so that we don't think
21305 ;; they are live.
21306 (define_insn "mmx_clrdi"
21307   [(set (match_operand:DI 0 "register_operand" "=y")
21308         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21309   "TARGET_MMX"
21310   "pxor\t{%0, %0|%0, %0}"
21311   [(set_attr "type" "mmxadd")
21312    (set_attr "mode" "DI")
21313    (set_attr "memory" "none")])
21314
21315 (define_insn "mmx_anddi3"
21316   [(set (match_operand:DI 0 "register_operand" "=y")
21317         (unspec:DI
21318          [(and:DI (match_operand:DI 1 "register_operand" "%0")
21319                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21320          UNSPEC_NOP))]
21321   "TARGET_MMX"
21322   "pand\t{%2, %0|%0, %2}"
21323   [(set_attr "type" "mmxadd")
21324    (set_attr "mode" "DI")])
21325
21326 (define_insn "mmx_nanddi3"
21327   [(set (match_operand:DI 0 "register_operand" "=y")
21328         (unspec:DI
21329          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21330                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21331          UNSPEC_NOP))]
21332   "TARGET_MMX"
21333   "pandn\t{%2, %0|%0, %2}"
21334   [(set_attr "type" "mmxadd")
21335    (set_attr "mode" "DI")])
21336
21337
21338 ;; MMX unsigned averages/sum of absolute differences
21339
21340 (define_insn "mmx_uavgv8qi3"
21341   [(set (match_operand:V8QI 0 "register_operand" "=y")
21342         (ashiftrt:V8QI
21343          (plus:V8QI (plus:V8QI
21344                      (match_operand:V8QI 1 "register_operand" "0")
21345                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21346                     (const_vector:V8QI [(const_int 1)
21347                                         (const_int 1)
21348                                         (const_int 1)
21349                                         (const_int 1)
21350                                         (const_int 1)
21351                                         (const_int 1)
21352                                         (const_int 1)
21353                                         (const_int 1)]))
21354          (const_int 1)))]
21355   "TARGET_SSE || TARGET_3DNOW_A"
21356   "pavgb\t{%2, %0|%0, %2}"
21357   [(set_attr "type" "mmxshft")
21358    (set_attr "mode" "DI")])
21359
21360 (define_insn "mmx_uavgv4hi3"
21361   [(set (match_operand:V4HI 0 "register_operand" "=y")
21362         (ashiftrt:V4HI
21363          (plus:V4HI (plus:V4HI
21364                      (match_operand:V4HI 1 "register_operand" "0")
21365                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21366                     (const_vector:V4HI [(const_int 1)
21367                                         (const_int 1)
21368                                         (const_int 1)
21369                                         (const_int 1)]))
21370          (const_int 1)))]
21371   "TARGET_SSE || TARGET_3DNOW_A"
21372   "pavgw\t{%2, %0|%0, %2}"
21373   [(set_attr "type" "mmxshft")
21374    (set_attr "mode" "DI")])
21375
21376 (define_insn "mmx_psadbw"
21377   [(set (match_operand:DI 0 "register_operand" "=y")
21378         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21379                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21380                    UNSPEC_PSADBW))]
21381   "TARGET_SSE || TARGET_3DNOW_A"
21382   "psadbw\t{%2, %0|%0, %2}"
21383   [(set_attr "type" "mmxshft")
21384    (set_attr "mode" "DI")])
21385
21386
21387 ;; MMX insert/extract/shuffle
21388
21389 (define_insn "mmx_pinsrw"
21390   [(set (match_operand:V4HI 0 "register_operand" "=y")
21391         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21392                         (vec_duplicate:V4HI
21393                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21394                         (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21395   "TARGET_SSE || TARGET_3DNOW_A"
21396   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21397   [(set_attr "type" "mmxcvt")
21398    (set_attr "mode" "DI")])
21399
21400 (define_insn "mmx_pextrw"
21401   [(set (match_operand:SI 0 "register_operand" "=r")
21402         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21403                                        (parallel
21404                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21405   "TARGET_SSE || TARGET_3DNOW_A"
21406   "pextrw\t{%2, %1, %0|%0, %1, %2}"
21407   [(set_attr "type" "mmxcvt")
21408    (set_attr "mode" "DI")])
21409
21410 (define_insn "mmx_pshufw"
21411   [(set (match_operand:V4HI 0 "register_operand" "=y")
21412         (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21413                       (match_operand:SI 2 "immediate_operand" "i")]
21414                      UNSPEC_SHUFFLE))]
21415   "TARGET_SSE || TARGET_3DNOW_A"
21416   "pshufw\t{%2, %1, %0|%0, %1, %2}"
21417   [(set_attr "type" "mmxcvt")
21418    (set_attr "mode" "DI")])
21419
21420
21421 ;; MMX mask-generating comparisons
21422
21423 (define_insn "eqv8qi3"
21424   [(set (match_operand:V8QI 0 "register_operand" "=y")
21425         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21426                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21427   "TARGET_MMX"
21428   "pcmpeqb\t{%2, %0|%0, %2}"
21429   [(set_attr "type" "mmxcmp")
21430    (set_attr "mode" "DI")])
21431
21432 (define_insn "eqv4hi3"
21433   [(set (match_operand:V4HI 0 "register_operand" "=y")
21434         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21435                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21436   "TARGET_MMX"
21437   "pcmpeqw\t{%2, %0|%0, %2}"
21438   [(set_attr "type" "mmxcmp")
21439    (set_attr "mode" "DI")])
21440
21441 (define_insn "eqv2si3"
21442   [(set (match_operand:V2SI 0 "register_operand" "=y")
21443         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21444                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21445   "TARGET_MMX"
21446   "pcmpeqd\t{%2, %0|%0, %2}"
21447   [(set_attr "type" "mmxcmp")
21448    (set_attr "mode" "DI")])
21449
21450 (define_insn "gtv8qi3"
21451   [(set (match_operand:V8QI 0 "register_operand" "=y")
21452         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21453                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21454   "TARGET_MMX"
21455   "pcmpgtb\t{%2, %0|%0, %2}"
21456   [(set_attr "type" "mmxcmp")
21457    (set_attr "mode" "DI")])
21458
21459 (define_insn "gtv4hi3"
21460   [(set (match_operand:V4HI 0 "register_operand" "=y")
21461         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21462                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21463   "TARGET_MMX"
21464   "pcmpgtw\t{%2, %0|%0, %2}"
21465   [(set_attr "type" "mmxcmp")
21466    (set_attr "mode" "DI")])
21467
21468 (define_insn "gtv2si3"
21469   [(set (match_operand:V2SI 0 "register_operand" "=y")
21470         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21471                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21472   "TARGET_MMX"
21473   "pcmpgtd\t{%2, %0|%0, %2}"
21474   [(set_attr "type" "mmxcmp")
21475    (set_attr "mode" "DI")])
21476
21477
21478 ;; MMX max/min insns
21479
21480 (define_insn "umaxv8qi3"
21481   [(set (match_operand:V8QI 0 "register_operand" "=y")
21482         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21483                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21484   "TARGET_SSE || TARGET_3DNOW_A"
21485   "pmaxub\t{%2, %0|%0, %2}"
21486   [(set_attr "type" "mmxadd")
21487    (set_attr "mode" "DI")])
21488
21489 (define_insn "smaxv4hi3"
21490   [(set (match_operand:V4HI 0 "register_operand" "=y")
21491         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21492                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21493   "TARGET_SSE || TARGET_3DNOW_A"
21494   "pmaxsw\t{%2, %0|%0, %2}"
21495   [(set_attr "type" "mmxadd")
21496    (set_attr "mode" "DI")])
21497
21498 (define_insn "uminv8qi3"
21499   [(set (match_operand:V8QI 0 "register_operand" "=y")
21500         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21501                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21502   "TARGET_SSE || TARGET_3DNOW_A"
21503   "pminub\t{%2, %0|%0, %2}"
21504   [(set_attr "type" "mmxadd")
21505    (set_attr "mode" "DI")])
21506
21507 (define_insn "sminv4hi3"
21508   [(set (match_operand:V4HI 0 "register_operand" "=y")
21509         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21510                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21511   "TARGET_SSE || TARGET_3DNOW_A"
21512   "pminsw\t{%2, %0|%0, %2}"
21513   [(set_attr "type" "mmxadd")
21514    (set_attr "mode" "DI")])
21515
21516
21517 ;; MMX shifts
21518
21519 (define_insn "ashrv4hi3"
21520   [(set (match_operand:V4HI 0 "register_operand" "=y")
21521         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21522                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21523   "TARGET_MMX"
21524   "psraw\t{%2, %0|%0, %2}"
21525   [(set_attr "type" "mmxshft")
21526    (set_attr "mode" "DI")])
21527
21528 (define_insn "ashrv2si3"
21529   [(set (match_operand:V2SI 0 "register_operand" "=y")
21530         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21531                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21532   "TARGET_MMX"
21533   "psrad\t{%2, %0|%0, %2}"
21534   [(set_attr "type" "mmxshft")
21535    (set_attr "mode" "DI")])
21536
21537 (define_insn "lshrv4hi3"
21538   [(set (match_operand:V4HI 0 "register_operand" "=y")
21539         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21540                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21541   "TARGET_MMX"
21542   "psrlw\t{%2, %0|%0, %2}"
21543   [(set_attr "type" "mmxshft")
21544    (set_attr "mode" "DI")])
21545
21546 (define_insn "lshrv2si3"
21547   [(set (match_operand:V2SI 0 "register_operand" "=y")
21548         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21549                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21550   "TARGET_MMX"
21551   "psrld\t{%2, %0|%0, %2}"
21552   [(set_attr "type" "mmxshft")
21553    (set_attr "mode" "DI")])
21554
21555 ;; See logical MMX insns.
21556 (define_insn "mmx_lshrdi3"
21557   [(set (match_operand:DI 0 "register_operand" "=y")
21558         (unspec:DI
21559           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21560                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
21561           UNSPEC_NOP))]
21562   "TARGET_MMX"
21563   "psrlq\t{%2, %0|%0, %2}"
21564   [(set_attr "type" "mmxshft")
21565    (set_attr "mode" "DI")])
21566
21567 (define_insn "ashlv4hi3"
21568   [(set (match_operand:V4HI 0 "register_operand" "=y")
21569         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21570                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21571   "TARGET_MMX"
21572   "psllw\t{%2, %0|%0, %2}"
21573   [(set_attr "type" "mmxshft")
21574    (set_attr "mode" "DI")])
21575
21576 (define_insn "ashlv2si3"
21577   [(set (match_operand:V2SI 0 "register_operand" "=y")
21578         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21579                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21580   "TARGET_MMX"
21581   "pslld\t{%2, %0|%0, %2}"
21582   [(set_attr "type" "mmxshft")
21583    (set_attr "mode" "DI")])
21584
21585 ;; See logical MMX insns.
21586 (define_insn "mmx_ashldi3"
21587   [(set (match_operand:DI 0 "register_operand" "=y")
21588         (unspec:DI
21589          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21590                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
21591          UNSPEC_NOP))]
21592   "TARGET_MMX"
21593   "psllq\t{%2, %0|%0, %2}"
21594   [(set_attr "type" "mmxshft")
21595    (set_attr "mode" "DI")])
21596
21597
21598 ;; MMX pack/unpack insns.
21599
21600 (define_insn "mmx_packsswb"
21601   [(set (match_operand:V8QI 0 "register_operand" "=y")
21602         (vec_concat:V8QI
21603          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21604          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21605   "TARGET_MMX"
21606   "packsswb\t{%2, %0|%0, %2}"
21607   [(set_attr "type" "mmxshft")
21608    (set_attr "mode" "DI")])
21609
21610 (define_insn "mmx_packssdw"
21611   [(set (match_operand:V4HI 0 "register_operand" "=y")
21612         (vec_concat:V4HI
21613          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21614          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21615   "TARGET_MMX"
21616   "packssdw\t{%2, %0|%0, %2}"
21617   [(set_attr "type" "mmxshft")
21618    (set_attr "mode" "DI")])
21619
21620 (define_insn "mmx_packuswb"
21621   [(set (match_operand:V8QI 0 "register_operand" "=y")
21622         (vec_concat:V8QI
21623          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21624          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21625   "TARGET_MMX"
21626   "packuswb\t{%2, %0|%0, %2}"
21627   [(set_attr "type" "mmxshft")
21628    (set_attr "mode" "DI")])
21629
21630 (define_insn "mmx_punpckhbw"
21631   [(set (match_operand:V8QI 0 "register_operand" "=y")
21632         (vec_merge:V8QI
21633          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21634                           (parallel [(const_int 4)
21635                                      (const_int 0)
21636                                      (const_int 5)
21637                                      (const_int 1)
21638                                      (const_int 6)
21639                                      (const_int 2)
21640                                      (const_int 7)
21641                                      (const_int 3)]))
21642          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21643                           (parallel [(const_int 0)
21644                                      (const_int 4)
21645                                      (const_int 1)
21646                                      (const_int 5)
21647                                      (const_int 2)
21648                                      (const_int 6)
21649                                      (const_int 3)
21650                                      (const_int 7)]))
21651          (const_int 85)))]
21652   "TARGET_MMX"
21653   "punpckhbw\t{%2, %0|%0, %2}"
21654   [(set_attr "type" "mmxcvt")
21655    (set_attr "mode" "DI")])
21656
21657 (define_insn "mmx_punpckhwd"
21658   [(set (match_operand:V4HI 0 "register_operand" "=y")
21659         (vec_merge:V4HI
21660          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21661                           (parallel [(const_int 0)
21662                                      (const_int 2)
21663                                      (const_int 1)
21664                                      (const_int 3)]))
21665          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21666                           (parallel [(const_int 2)
21667                                      (const_int 0)
21668                                      (const_int 3)
21669                                      (const_int 1)]))
21670          (const_int 5)))]
21671   "TARGET_MMX"
21672   "punpckhwd\t{%2, %0|%0, %2}"
21673   [(set_attr "type" "mmxcvt")
21674    (set_attr "mode" "DI")])
21675
21676 (define_insn "mmx_punpckhdq"
21677   [(set (match_operand:V2SI 0 "register_operand" "=y")
21678         (vec_merge:V2SI
21679          (match_operand:V2SI 1 "register_operand" "0")
21680          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21681                           (parallel [(const_int 1)
21682                                      (const_int 0)]))
21683          (const_int 1)))]
21684   "TARGET_MMX"
21685   "punpckhdq\t{%2, %0|%0, %2}"
21686   [(set_attr "type" "mmxcvt")
21687    (set_attr "mode" "DI")])
21688
21689 (define_insn "mmx_punpcklbw"
21690   [(set (match_operand:V8QI 0 "register_operand" "=y")
21691         (vec_merge:V8QI
21692          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21693                           (parallel [(const_int 0)
21694                                      (const_int 4)
21695                                      (const_int 1)
21696                                      (const_int 5)
21697                                      (const_int 2)
21698                                      (const_int 6)
21699                                      (const_int 3)
21700                                      (const_int 7)]))
21701          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21702                           (parallel [(const_int 4)
21703                                      (const_int 0)
21704                                      (const_int 5)
21705                                      (const_int 1)
21706                                      (const_int 6)
21707                                      (const_int 2)
21708                                      (const_int 7)
21709                                      (const_int 3)]))
21710          (const_int 85)))]
21711   "TARGET_MMX"
21712   "punpcklbw\t{%2, %0|%0, %2}"
21713   [(set_attr "type" "mmxcvt")
21714    (set_attr "mode" "DI")])
21715
21716 (define_insn "mmx_punpcklwd"
21717   [(set (match_operand:V4HI 0 "register_operand" "=y")
21718         (vec_merge:V4HI
21719          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21720                           (parallel [(const_int 2)
21721                                      (const_int 0)
21722                                      (const_int 3)
21723                                      (const_int 1)]))
21724          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21725                           (parallel [(const_int 0)
21726                                      (const_int 2)
21727                                      (const_int 1)
21728                                      (const_int 3)]))
21729          (const_int 5)))]
21730   "TARGET_MMX"
21731   "punpcklwd\t{%2, %0|%0, %2}"
21732   [(set_attr "type" "mmxcvt")
21733    (set_attr "mode" "DI")])
21734
21735 (define_insn "mmx_punpckldq"
21736   [(set (match_operand:V2SI 0 "register_operand" "=y")
21737         (vec_merge:V2SI
21738          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
21739                            (parallel [(const_int 1)
21740                                       (const_int 0)]))
21741          (match_operand:V2SI 2 "register_operand" "y")
21742          (const_int 1)))]
21743   "TARGET_MMX"
21744   "punpckldq\t{%2, %0|%0, %2}"
21745   [(set_attr "type" "mmxcvt")
21746    (set_attr "mode" "DI")])
21747
21748
21749 ;; Miscellaneous stuff
21750
21751 (define_insn "emms"
21752   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
21753    (clobber (reg:XF 8))
21754    (clobber (reg:XF 9))
21755    (clobber (reg:XF 10))
21756    (clobber (reg:XF 11))
21757    (clobber (reg:XF 12))
21758    (clobber (reg:XF 13))
21759    (clobber (reg:XF 14))
21760    (clobber (reg:XF 15))
21761    (clobber (reg:DI 29))
21762    (clobber (reg:DI 30))
21763    (clobber (reg:DI 31))
21764    (clobber (reg:DI 32))
21765    (clobber (reg:DI 33))
21766    (clobber (reg:DI 34))
21767    (clobber (reg:DI 35))
21768    (clobber (reg:DI 36))]
21769   "TARGET_MMX"
21770   "emms"
21771   [(set_attr "type" "mmx")
21772    (set_attr "memory" "unknown")])
21773
21774 (define_insn "ldmxcsr"
21775   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
21776                     UNSPECV_LDMXCSR)]
21777   "TARGET_SSE"
21778   "ldmxcsr\t%0"
21779   [(set_attr "type" "sse")
21780    (set_attr "memory" "load")])
21781
21782 (define_insn "stmxcsr"
21783   [(set (match_operand:SI 0 "memory_operand" "=m")
21784         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21785   "TARGET_SSE"
21786   "stmxcsr\t%0"
21787   [(set_attr "type" "sse")
21788    (set_attr "memory" "store")])
21789
21790 (define_expand "sfence"
21791   [(set (match_dup 0)
21792         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21793   "TARGET_SSE || TARGET_3DNOW_A"
21794 {
21795   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21796   MEM_VOLATILE_P (operands[0]) = 1;
21797 })
21798
21799 (define_insn "*sfence_insn"
21800   [(set (match_operand:BLK 0 "" "")
21801         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21802   "TARGET_SSE || TARGET_3DNOW_A"
21803   "sfence"
21804   [(set_attr "type" "sse")
21805    (set_attr "memory" "unknown")])
21806
21807 (define_expand "sse_prologue_save"
21808   [(parallel [(set (match_operand:BLK 0 "" "")
21809                    (unspec:BLK [(reg:DI 21)
21810                                 (reg:DI 22)
21811                                 (reg:DI 23)
21812                                 (reg:DI 24)
21813                                 (reg:DI 25)
21814                                 (reg:DI 26)
21815                                 (reg:DI 27)
21816                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21817               (use (match_operand:DI 1 "register_operand" ""))
21818               (use (match_operand:DI 2 "immediate_operand" ""))
21819               (use (label_ref:DI (match_operand 3 "" "")))])]
21820   "TARGET_64BIT"
21821   "")
21822
21823 (define_insn "*sse_prologue_save_insn"
21824   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21825                           (match_operand:DI 4 "const_int_operand" "n")))
21826         (unspec:BLK [(reg:DI 21)
21827                      (reg:DI 22)
21828                      (reg:DI 23)
21829                      (reg:DI 24)
21830                      (reg:DI 25)
21831                      (reg:DI 26)
21832                      (reg:DI 27)
21833                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21834    (use (match_operand:DI 1 "register_operand" "r"))
21835    (use (match_operand:DI 2 "const_int_operand" "i"))
21836    (use (label_ref:DI (match_operand 3 "" "X")))]
21837   "TARGET_64BIT
21838    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21839    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21840   "*
21841 {
21842   int i;
21843   operands[0] = gen_rtx_MEM (Pmode,
21844                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21845   output_asm_insn (\"jmp\\t%A1\", operands);
21846   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21847     {
21848       operands[4] = adjust_address (operands[0], DImode, i*16);
21849       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21850       PUT_MODE (operands[4], TImode);
21851       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21852         output_asm_insn (\"rex\", operands);
21853       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21854     }
21855   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21856                              CODE_LABEL_NUMBER (operands[3]));
21857   RET;
21858 }
21859   "
21860   [(set_attr "type" "other")
21861    (set_attr "length_immediate" "0")
21862    (set_attr "length_address" "0")
21863    (set_attr "length" "135")
21864    (set_attr "memory" "store")
21865    (set_attr "modrm" "0")
21866    (set_attr "mode" "DI")])
21867
21868 ;; 3Dnow! instructions
21869
21870 (define_insn "addv2sf3"
21871   [(set (match_operand:V2SF 0 "register_operand" "=y")
21872         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21873                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21874   "TARGET_3DNOW"
21875   "pfadd\\t{%2, %0|%0, %2}"
21876   [(set_attr "type" "mmxadd")
21877    (set_attr "mode" "V2SF")])
21878
21879 (define_insn "subv2sf3"
21880   [(set (match_operand:V2SF 0 "register_operand" "=y")
21881         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21882                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21883   "TARGET_3DNOW"
21884   "pfsub\\t{%2, %0|%0, %2}"
21885   [(set_attr "type" "mmxadd")
21886    (set_attr "mode" "V2SF")])
21887
21888 (define_insn "subrv2sf3"
21889   [(set (match_operand:V2SF 0 "register_operand" "=y")
21890         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
21891                     (match_operand:V2SF 1 "register_operand" "0")))]
21892   "TARGET_3DNOW"
21893   "pfsubr\\t{%2, %0|%0, %2}"
21894   [(set_attr "type" "mmxadd")
21895    (set_attr "mode" "V2SF")])
21896
21897 (define_insn "gtv2sf3"
21898   [(set (match_operand:V2SI 0 "register_operand" "=y")
21899         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
21900                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21901   "TARGET_3DNOW"
21902   "pfcmpgt\\t{%2, %0|%0, %2}"
21903   [(set_attr "type" "mmxcmp")
21904    (set_attr "mode" "V2SF")])
21905
21906 (define_insn "gev2sf3"
21907   [(set (match_operand:V2SI 0 "register_operand" "=y")
21908         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
21909                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21910   "TARGET_3DNOW"
21911   "pfcmpge\\t{%2, %0|%0, %2}"
21912   [(set_attr "type" "mmxcmp")
21913    (set_attr "mode" "V2SF")])
21914
21915 (define_insn "eqv2sf3"
21916   [(set (match_operand:V2SI 0 "register_operand" "=y")
21917         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
21918                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21919   "TARGET_3DNOW"
21920   "pfcmpeq\\t{%2, %0|%0, %2}"
21921   [(set_attr "type" "mmxcmp")
21922    (set_attr "mode" "V2SF")])
21923
21924 (define_insn "pfmaxv2sf3"
21925   [(set (match_operand:V2SF 0 "register_operand" "=y")
21926         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
21927                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21928   "TARGET_3DNOW"
21929   "pfmax\\t{%2, %0|%0, %2}"
21930   [(set_attr "type" "mmxadd")
21931    (set_attr "mode" "V2SF")])
21932
21933 (define_insn "pfminv2sf3"
21934   [(set (match_operand:V2SF 0 "register_operand" "=y")
21935         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
21936                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21937   "TARGET_3DNOW"
21938   "pfmin\\t{%2, %0|%0, %2}"
21939   [(set_attr "type" "mmxadd")
21940    (set_attr "mode" "V2SF")])
21941
21942 (define_insn "mulv2sf3"
21943   [(set (match_operand:V2SF 0 "register_operand" "=y")
21944         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
21945                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21946   "TARGET_3DNOW"
21947   "pfmul\\t{%2, %0|%0, %2}"
21948   [(set_attr "type" "mmxmul")
21949    (set_attr "mode" "V2SF")])
21950
21951 (define_insn "femms"
21952   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21953    (clobber (reg:XF 8))
21954    (clobber (reg:XF 9))
21955    (clobber (reg:XF 10))
21956    (clobber (reg:XF 11))
21957    (clobber (reg:XF 12))
21958    (clobber (reg:XF 13))
21959    (clobber (reg:XF 14))
21960    (clobber (reg:XF 15))
21961    (clobber (reg:DI 29))
21962    (clobber (reg:DI 30))
21963    (clobber (reg:DI 31))
21964    (clobber (reg:DI 32))
21965    (clobber (reg:DI 33))
21966    (clobber (reg:DI 34))
21967    (clobber (reg:DI 35))
21968    (clobber (reg:DI 36))]
21969   "TARGET_3DNOW"
21970   "femms"
21971   [(set_attr "type" "mmx")
21972    (set_attr "memory" "none")]) 
21973
21974 (define_insn "pf2id"
21975   [(set (match_operand:V2SI 0 "register_operand" "=y")
21976         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21977   "TARGET_3DNOW"
21978   "pf2id\\t{%1, %0|%0, %1}"
21979   [(set_attr "type" "mmxcvt")
21980    (set_attr "mode" "V2SF")])
21981
21982 (define_insn "pf2iw"
21983   [(set (match_operand:V2SI 0 "register_operand" "=y")
21984         (sign_extend:V2SI
21985            (ss_truncate:V2HI
21986               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
21987   "TARGET_3DNOW_A"
21988   "pf2iw\\t{%1, %0|%0, %1}"
21989   [(set_attr "type" "mmxcvt")
21990    (set_attr "mode" "V2SF")])
21991
21992 (define_insn "pfacc"
21993   [(set (match_operand:V2SF 0 "register_operand" "=y")
21994         (vec_concat:V2SF
21995            (plus:SF
21996               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21997                              (parallel [(const_int  0)]))
21998               (vec_select:SF (match_dup 1)
21999                              (parallel [(const_int 1)])))
22000            (plus:SF
22001               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22002                              (parallel [(const_int  0)]))
22003               (vec_select:SF (match_dup 2)
22004                              (parallel [(const_int 1)])))))]
22005   "TARGET_3DNOW"
22006   "pfacc\\t{%2, %0|%0, %2}"
22007   [(set_attr "type" "mmxadd")
22008    (set_attr "mode" "V2SF")])
22009
22010 (define_insn "pfnacc"
22011   [(set (match_operand:V2SF 0 "register_operand" "=y")
22012         (vec_concat:V2SF
22013            (minus: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            (minus: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_A"
22024   "pfnacc\\t{%2, %0|%0, %2}"
22025   [(set_attr "type" "mmxadd")
22026    (set_attr "mode" "V2SF")])
22027
22028 (define_insn "pfpnacc"
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            (plus: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   "pfpnacc\\t{%2, %0|%0, %2}"
22043   [(set_attr "type" "mmxadd")
22044    (set_attr "mode" "V2SF")])
22045
22046 (define_insn "pi2fw"
22047   [(set (match_operand:V2SF 0 "register_operand" "=y")
22048         (float:V2SF
22049            (vec_concat:V2SI
22050               (sign_extend:SI
22051                  (truncate:HI
22052                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22053                                    (parallel [(const_int 0)]))))
22054               (sign_extend:SI
22055                  (truncate:HI
22056                     (vec_select:SI (match_dup 1)
22057                                    (parallel [(const_int  1)])))))))]
22058   "TARGET_3DNOW_A"
22059   "pi2fw\\t{%1, %0|%0, %1}"
22060   [(set_attr "type" "mmxcvt")
22061    (set_attr "mode" "V2SF")])
22062
22063 (define_insn "floatv2si2"
22064   [(set (match_operand:V2SF 0 "register_operand" "=y")
22065         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22066   "TARGET_3DNOW"
22067   "pi2fd\\t{%1, %0|%0, %1}"
22068   [(set_attr "type" "mmxcvt")
22069    (set_attr "mode" "V2SF")])
22070
22071 ;; This insn is identical to pavgb in operation, but the opcode is
22072 ;; different.  To avoid accidentally matching pavgb, use an unspec.
22073
22074 (define_insn "pavgusb"
22075  [(set (match_operand:V8QI 0 "register_operand" "=y")
22076        (unspec:V8QI
22077           [(match_operand:V8QI 1 "register_operand" "0")
22078            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22079           UNSPEC_PAVGUSB))]
22080   "TARGET_3DNOW"
22081   "pavgusb\\t{%2, %0|%0, %2}"
22082   [(set_attr "type" "mmxshft")
22083    (set_attr "mode" "TI")])
22084
22085 ;; 3DNow reciprocal and sqrt
22086  
22087 (define_insn "pfrcpv2sf2"
22088   [(set (match_operand:V2SF 0 "register_operand" "=y")
22089         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22090         UNSPEC_PFRCP))]
22091   "TARGET_3DNOW"
22092   "pfrcp\\t{%1, %0|%0, %1}"
22093   [(set_attr "type" "mmx")
22094    (set_attr "mode" "TI")])
22095
22096 (define_insn "pfrcpit1v2sf3"
22097   [(set (match_operand:V2SF 0 "register_operand" "=y")
22098         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22099                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22100                      UNSPEC_PFRCPIT1))]
22101   "TARGET_3DNOW"
22102   "pfrcpit1\\t{%2, %0|%0, %2}"
22103   [(set_attr "type" "mmx")
22104    (set_attr "mode" "TI")])
22105
22106 (define_insn "pfrcpit2v2sf3"
22107   [(set (match_operand:V2SF 0 "register_operand" "=y")
22108         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22109                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22110                      UNSPEC_PFRCPIT2))]
22111   "TARGET_3DNOW"
22112   "pfrcpit2\\t{%2, %0|%0, %2}"
22113   [(set_attr "type" "mmx")
22114    (set_attr "mode" "TI")])
22115
22116 (define_insn "pfrsqrtv2sf2"
22117   [(set (match_operand:V2SF 0 "register_operand" "=y")
22118         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22119                      UNSPEC_PFRSQRT))]
22120   "TARGET_3DNOW"
22121   "pfrsqrt\\t{%1, %0|%0, %1}"
22122   [(set_attr "type" "mmx")
22123    (set_attr "mode" "TI")])
22124                 
22125 (define_insn "pfrsqit1v2sf3"
22126   [(set (match_operand:V2SF 0 "register_operand" "=y")
22127         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22128                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22129                      UNSPEC_PFRSQIT1))]
22130   "TARGET_3DNOW"
22131   "pfrsqit1\\t{%2, %0|%0, %2}"
22132   [(set_attr "type" "mmx")
22133    (set_attr "mode" "TI")])
22134
22135 (define_insn "pmulhrwv4hi3"
22136   [(set (match_operand:V4HI 0 "register_operand" "=y")
22137         (truncate:V4HI
22138            (lshiftrt:V4SI
22139               (plus:V4SI
22140                  (mult:V4SI
22141                     (sign_extend:V4SI
22142                        (match_operand:V4HI 1 "register_operand" "0"))
22143                     (sign_extend:V4SI
22144                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22145                  (const_vector:V4SI [(const_int 32768)
22146                                      (const_int 32768)
22147                                      (const_int 32768)
22148                                      (const_int 32768)]))
22149               (const_int 16))))]
22150   "TARGET_3DNOW"
22151   "pmulhrw\\t{%2, %0|%0, %2}"
22152   [(set_attr "type" "mmxmul")
22153    (set_attr "mode" "TI")])
22154
22155 (define_insn "pswapdv2si2"
22156   [(set (match_operand:V2SI 0 "register_operand" "=y")
22157         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22158                          (parallel [(const_int 1) (const_int 0)])))]
22159   "TARGET_3DNOW_A"
22160   "pswapd\\t{%1, %0|%0, %1}"
22161   [(set_attr "type" "mmxcvt")
22162    (set_attr "mode" "TI")])
22163
22164 (define_insn "pswapdv2sf2"
22165   [(set (match_operand:V2SF 0 "register_operand" "=y")
22166         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22167                          (parallel [(const_int 1) (const_int 0)])))]
22168   "TARGET_3DNOW_A"
22169   "pswapd\\t{%1, %0|%0, %1}"
22170   [(set_attr "type" "mmxcvt")
22171    (set_attr "mode" "TI")])
22172
22173 (define_expand "prefetch"
22174   [(prefetch (match_operand 0 "address_operand" "")
22175              (match_operand:SI 1 "const_int_operand" "")
22176              (match_operand:SI 2 "const_int_operand" ""))]
22177   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22178 {
22179   int rw = INTVAL (operands[1]);
22180   int locality = INTVAL (operands[2]);
22181
22182   if (rw != 0 && rw != 1)
22183     abort ();
22184   if (locality < 0 || locality > 3)
22185     abort ();
22186   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22187     abort ();
22188
22189   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22190      suported by SSE counterpart or the SSE prefetch is not available
22191      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22192      of locality.  */
22193   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22194     operands[2] = GEN_INT (3);
22195   else
22196     operands[1] = const0_rtx;
22197 })
22198
22199 (define_insn "*prefetch_sse"
22200   [(prefetch (match_operand:SI 0 "address_operand" "p")
22201              (const_int 0)
22202              (match_operand:SI 1 "const_int_operand" ""))]
22203   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22204 {
22205   static const char * const patterns[4] = {
22206    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22207   };
22208
22209   int locality = INTVAL (operands[1]);
22210   if (locality < 0 || locality > 3)
22211     abort ();
22212
22213   return patterns[locality];  
22214 }
22215   [(set_attr "type" "sse")
22216    (set_attr "memory" "none")])
22217
22218 (define_insn "*prefetch_sse_rex"
22219   [(prefetch (match_operand:DI 0 "address_operand" "p")
22220              (const_int 0)
22221              (match_operand:SI 1 "const_int_operand" ""))]
22222   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22223 {
22224   static const char * const patterns[4] = {
22225    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22226   };
22227
22228   int locality = INTVAL (operands[1]);
22229   if (locality < 0 || locality > 3)
22230     abort ();
22231
22232   return patterns[locality];  
22233 }
22234   [(set_attr "type" "sse")
22235    (set_attr "memory" "none")])
22236
22237 (define_insn "*prefetch_3dnow"
22238   [(prefetch (match_operand:SI 0 "address_operand" "p")
22239              (match_operand:SI 1 "const_int_operand" "n")
22240              (const_int 3))]
22241   "TARGET_3DNOW && !TARGET_64BIT"
22242 {
22243   if (INTVAL (operands[1]) == 0)
22244     return "prefetch\t%a0";
22245   else
22246     return "prefetchw\t%a0";
22247 }
22248   [(set_attr "type" "mmx")
22249    (set_attr "memory" "none")])
22250
22251 (define_insn "*prefetch_3dnow_rex"
22252   [(prefetch (match_operand:DI 0 "address_operand" "p")
22253              (match_operand:SI 1 "const_int_operand" "n")
22254              (const_int 3))]
22255   "TARGET_3DNOW && TARGET_64BIT"
22256 {
22257   if (INTVAL (operands[1]) == 0)
22258     return "prefetch\t%a0";
22259   else
22260     return "prefetchw\t%a0";
22261 }
22262   [(set_attr "type" "mmx")
22263    (set_attr "memory" "none")])
22264
22265 ;; SSE2 support
22266
22267 (define_insn "addv2df3"
22268   [(set (match_operand:V2DF 0 "register_operand" "=x")
22269         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22270                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22271   "TARGET_SSE2"
22272   "addpd\t{%2, %0|%0, %2}"
22273   [(set_attr "type" "sseadd")
22274    (set_attr "mode" "V2DF")])
22275
22276 (define_insn "vmaddv2df3"
22277   [(set (match_operand:V2DF 0 "register_operand" "=x")
22278         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22279                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22280                         (match_dup 1)
22281                         (const_int 1)))]
22282   "TARGET_SSE2"
22283   "addsd\t{%2, %0|%0, %2}"
22284   [(set_attr "type" "sseadd")
22285    (set_attr "mode" "DF")])
22286
22287 (define_insn "subv2df3"
22288   [(set (match_operand:V2DF 0 "register_operand" "=x")
22289         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22290                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22291   "TARGET_SSE2"
22292   "subpd\t{%2, %0|%0, %2}"
22293   [(set_attr "type" "sseadd")
22294    (set_attr "mode" "V2DF")])
22295
22296 (define_insn "vmsubv2df3"
22297   [(set (match_operand:V2DF 0 "register_operand" "=x")
22298         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22299                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22300                         (match_dup 1)
22301                         (const_int 1)))]
22302   "TARGET_SSE2"
22303   "subsd\t{%2, %0|%0, %2}"
22304   [(set_attr "type" "sseadd")
22305    (set_attr "mode" "DF")])
22306
22307 (define_insn "mulv2df3"
22308   [(set (match_operand:V2DF 0 "register_operand" "=x")
22309         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22310                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22311   "TARGET_SSE2"
22312   "mulpd\t{%2, %0|%0, %2}"
22313   [(set_attr "type" "ssemul")
22314    (set_attr "mode" "V2DF")])
22315
22316 (define_insn "vmmulv2df3"
22317   [(set (match_operand:V2DF 0 "register_operand" "=x")
22318         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22319                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22320                         (match_dup 1)
22321                         (const_int 1)))]
22322   "TARGET_SSE2"
22323   "mulsd\t{%2, %0|%0, %2}"
22324   [(set_attr "type" "ssemul")
22325    (set_attr "mode" "DF")])
22326
22327 (define_insn "divv2df3"
22328   [(set (match_operand:V2DF 0 "register_operand" "=x")
22329         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22330                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22331   "TARGET_SSE2"
22332   "divpd\t{%2, %0|%0, %2}"
22333   [(set_attr "type" "ssediv")
22334    (set_attr "mode" "V2DF")])
22335
22336 (define_insn "vmdivv2df3"
22337   [(set (match_operand:V2DF 0 "register_operand" "=x")
22338         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22339                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22340                         (match_dup 1)
22341                         (const_int 1)))]
22342   "TARGET_SSE2"
22343   "divsd\t{%2, %0|%0, %2}"
22344   [(set_attr "type" "ssediv")
22345    (set_attr "mode" "DF")])
22346
22347 ;; SSE min/max
22348
22349 (define_insn "smaxv2df3"
22350   [(set (match_operand:V2DF 0 "register_operand" "=x")
22351         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22352                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22353   "TARGET_SSE2"
22354   "maxpd\t{%2, %0|%0, %2}"
22355   [(set_attr "type" "sseadd")
22356    (set_attr "mode" "V2DF")])
22357
22358 (define_insn "vmsmaxv2df3"
22359   [(set (match_operand:V2DF 0 "register_operand" "=x")
22360         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22361                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22362                         (match_dup 1)
22363                         (const_int 1)))]
22364   "TARGET_SSE2"
22365   "maxsd\t{%2, %0|%0, %2}"
22366   [(set_attr "type" "sseadd")
22367    (set_attr "mode" "DF")])
22368
22369 (define_insn "sminv2df3"
22370   [(set (match_operand:V2DF 0 "register_operand" "=x")
22371         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22372                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22373   "TARGET_SSE2"
22374   "minpd\t{%2, %0|%0, %2}"
22375   [(set_attr "type" "sseadd")
22376    (set_attr "mode" "V2DF")])
22377
22378 (define_insn "vmsminv2df3"
22379   [(set (match_operand:V2DF 0 "register_operand" "=x")
22380         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22381                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22382                         (match_dup 1)
22383                         (const_int 1)))]
22384   "TARGET_SSE2"
22385   "minsd\t{%2, %0|%0, %2}"
22386   [(set_attr "type" "sseadd")
22387    (set_attr "mode" "DF")])
22388 ;; SSE2 square root.  There doesn't appear to be an extension for the
22389 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22390
22391 (define_insn "sqrtv2df2"
22392   [(set (match_operand:V2DF 0 "register_operand" "=x")
22393         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22394   "TARGET_SSE2"
22395   "sqrtpd\t{%1, %0|%0, %1}"
22396   [(set_attr "type" "sse")
22397    (set_attr "mode" "V2DF")])
22398
22399 (define_insn "vmsqrtv2df2"
22400   [(set (match_operand:V2DF 0 "register_operand" "=x")
22401         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22402                         (match_operand:V2DF 2 "register_operand" "0")
22403                         (const_int 1)))]
22404   "TARGET_SSE2"
22405   "sqrtsd\t{%1, %0|%0, %1}"
22406   [(set_attr "type" "sse")
22407    (set_attr "mode" "SF")])
22408
22409 ;; SSE mask-generating compares
22410
22411 (define_insn "maskcmpv2df3"
22412   [(set (match_operand:V2DI 0 "register_operand" "=x")
22413         (match_operator:V2DI 3 "sse_comparison_operator"
22414                              [(match_operand:V2DF 1 "register_operand" "0")
22415                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22416   "TARGET_SSE2"
22417   "cmp%D3pd\t{%2, %0|%0, %2}"
22418   [(set_attr "type" "ssecmp")
22419    (set_attr "mode" "V2DF")])
22420
22421 (define_insn "maskncmpv2df3"
22422   [(set (match_operand:V2DI 0 "register_operand" "=x")
22423         (not:V2DI
22424          (match_operator:V2DI 3 "sse_comparison_operator"
22425                               [(match_operand:V2DF 1 "register_operand" "0")
22426                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22427   "TARGET_SSE2"
22428 {
22429   if (GET_CODE (operands[3]) == UNORDERED)
22430     return "cmpordps\t{%2, %0|%0, %2}";
22431   else
22432     return "cmpn%D3pd\t{%2, %0|%0, %2}";
22433 }
22434   [(set_attr "type" "ssecmp")
22435    (set_attr "mode" "V2DF")])
22436
22437 (define_insn "vmmaskcmpv2df3"
22438   [(set (match_operand:V2DI 0 "register_operand" "=x")
22439         (vec_merge:V2DI
22440          (match_operator:V2DI 3 "sse_comparison_operator"
22441                               [(match_operand:V2DF 1 "register_operand" "0")
22442                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22443          (subreg:V2DI (match_dup 1) 0)
22444          (const_int 1)))]
22445   "TARGET_SSE2"
22446   "cmp%D3sd\t{%2, %0|%0, %2}"
22447   [(set_attr "type" "ssecmp")
22448    (set_attr "mode" "DF")])
22449
22450 (define_insn "vmmaskncmpv2df3"
22451   [(set (match_operand:V2DI 0 "register_operand" "=x")
22452         (vec_merge:V2DI
22453          (not:V2DI
22454           (match_operator:V2DI 3 "sse_comparison_operator"
22455                                [(match_operand:V2DF 1 "register_operand" "0")
22456                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22457          (subreg:V2DI (match_dup 1) 0)
22458          (const_int 1)))]
22459   "TARGET_SSE2"
22460 {
22461   if (GET_CODE (operands[3]) == UNORDERED)
22462     return "cmpordsd\t{%2, %0|%0, %2}";
22463   else
22464     return "cmpn%D3sd\t{%2, %0|%0, %2}";
22465 }
22466   [(set_attr "type" "ssecmp")
22467    (set_attr "mode" "DF")])
22468
22469 (define_insn "sse2_comi"
22470   [(set (reg:CCFP FLAGS_REG)
22471         (compare:CCFP (vec_select:DF
22472                        (match_operand:V2DF 0 "register_operand" "x")
22473                        (parallel [(const_int 0)]))
22474                       (vec_select:DF
22475                        (match_operand:V2DF 1 "register_operand" "x")
22476                        (parallel [(const_int 0)]))))]
22477   "TARGET_SSE2"
22478   "comisd\t{%1, %0|%0, %1}"
22479   [(set_attr "type" "ssecomi")
22480    (set_attr "mode" "DF")])
22481
22482 (define_insn "sse2_ucomi"
22483   [(set (reg:CCFPU FLAGS_REG)
22484         (compare:CCFPU (vec_select:DF
22485                          (match_operand:V2DF 0 "register_operand" "x")
22486                          (parallel [(const_int 0)]))
22487                         (vec_select:DF
22488                          (match_operand:V2DF 1 "register_operand" "x")
22489                          (parallel [(const_int 0)]))))]
22490   "TARGET_SSE2"
22491   "ucomisd\t{%1, %0|%0, %1}"
22492   [(set_attr "type" "ssecomi")
22493    (set_attr "mode" "DF")])
22494
22495 ;; SSE Strange Moves.
22496
22497 (define_insn "sse2_movmskpd"
22498   [(set (match_operand:SI 0 "register_operand" "=r")
22499         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22500                    UNSPEC_MOVMSK))]
22501   "TARGET_SSE2"
22502   "movmskpd\t{%1, %0|%0, %1}"
22503   [(set_attr "type" "ssecvt")
22504    (set_attr "mode" "V2DF")])
22505
22506 (define_insn "sse2_pmovmskb"
22507   [(set (match_operand:SI 0 "register_operand" "=r")
22508         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22509                    UNSPEC_MOVMSK))]
22510   "TARGET_SSE2"
22511   "pmovmskb\t{%1, %0|%0, %1}"
22512   [(set_attr "type" "ssecvt")
22513    (set_attr "mode" "V2DF")])
22514
22515 (define_insn "sse2_maskmovdqu"
22516   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22517         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22518                        (match_operand:V16QI 2 "register_operand" "x")]
22519                       UNSPEC_MASKMOV))]
22520   "TARGET_SSE2"
22521   ;; @@@ check ordering of operands in intel/nonintel syntax
22522   "maskmovdqu\t{%2, %1|%1, %2}"
22523   [(set_attr "type" "ssecvt")
22524    (set_attr "mode" "TI")])
22525
22526 (define_insn "sse2_maskmovdqu_rex64"
22527   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22528         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22529                        (match_operand:V16QI 2 "register_operand" "x")]
22530                       UNSPEC_MASKMOV))]
22531   "TARGET_SSE2"
22532   ;; @@@ check ordering of operands in intel/nonintel syntax
22533   "maskmovdqu\t{%2, %1|%1, %2}"
22534   [(set_attr "type" "ssecvt")
22535    (set_attr "mode" "TI")])
22536
22537 (define_insn "sse2_movntv2df"
22538   [(set (match_operand:V2DF 0 "memory_operand" "=m")
22539         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22540                      UNSPEC_MOVNT))]
22541   "TARGET_SSE2"
22542   "movntpd\t{%1, %0|%0, %1}"
22543   [(set_attr "type" "ssecvt")
22544    (set_attr "mode" "V2DF")])
22545
22546 (define_insn "sse2_movntv2di"
22547   [(set (match_operand:V2DI 0 "memory_operand" "=m")
22548         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22549                      UNSPEC_MOVNT))]
22550   "TARGET_SSE2"
22551   "movntdq\t{%1, %0|%0, %1}"
22552   [(set_attr "type" "ssecvt")
22553    (set_attr "mode" "TI")])
22554
22555 (define_insn "sse2_movntsi"
22556   [(set (match_operand:SI 0 "memory_operand" "=m")
22557         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22558                    UNSPEC_MOVNT))]
22559   "TARGET_SSE2"
22560   "movnti\t{%1, %0|%0, %1}"
22561   [(set_attr "type" "ssecvt")
22562    (set_attr "mode" "V2DF")])
22563
22564 ;; SSE <-> integer/MMX conversions
22565
22566 ;; Conversions between SI and SF
22567
22568 (define_insn "cvtdq2ps"
22569   [(set (match_operand:V4SF 0 "register_operand" "=x")
22570         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22571   "TARGET_SSE2"
22572   "cvtdq2ps\t{%1, %0|%0, %1}"
22573   [(set_attr "type" "ssecvt")
22574    (set_attr "mode" "V2DF")])
22575
22576 (define_insn "cvtps2dq"
22577   [(set (match_operand:V4SI 0 "register_operand" "=x")
22578         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22579   "TARGET_SSE2"
22580   "cvtps2dq\t{%1, %0|%0, %1}"
22581   [(set_attr "type" "ssecvt")
22582    (set_attr "mode" "TI")])
22583
22584 (define_insn "cvttps2dq"
22585   [(set (match_operand:V4SI 0 "register_operand" "=x")
22586         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22587                      UNSPEC_FIX))]
22588   "TARGET_SSE2"
22589   "cvttps2dq\t{%1, %0|%0, %1}"
22590   [(set_attr "type" "ssecvt")
22591    (set_attr "mode" "TI")])
22592
22593 ;; Conversions between SI and DF
22594
22595 (define_insn "cvtdq2pd"
22596   [(set (match_operand:V2DF 0 "register_operand" "=x")
22597         (float:V2DF (vec_select:V2SI
22598                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22599                      (parallel
22600                       [(const_int 0)
22601                        (const_int 1)]))))]
22602   "TARGET_SSE2"
22603   "cvtdq2pd\t{%1, %0|%0, %1}"
22604   [(set_attr "type" "ssecvt")
22605    (set_attr "mode" "V2DF")])
22606
22607 (define_insn "cvtpd2dq"
22608   [(set (match_operand:V4SI 0 "register_operand" "=x")
22609         (vec_concat:V4SI
22610          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22611          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22612   "TARGET_SSE2"
22613   "cvtpd2dq\t{%1, %0|%0, %1}"
22614   [(set_attr "type" "ssecvt")
22615    (set_attr "mode" "TI")])
22616
22617 (define_insn "cvttpd2dq"
22618   [(set (match_operand:V4SI 0 "register_operand" "=x")
22619         (vec_concat:V4SI
22620          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22621                       UNSPEC_FIX)
22622          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22623   "TARGET_SSE2"
22624   "cvttpd2dq\t{%1, %0|%0, %1}"
22625   [(set_attr "type" "ssecvt")
22626    (set_attr "mode" "TI")])
22627
22628 (define_insn "cvtpd2pi"
22629   [(set (match_operand:V2SI 0 "register_operand" "=y")
22630         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22631   "TARGET_SSE2"
22632   "cvtpd2pi\t{%1, %0|%0, %1}"
22633   [(set_attr "type" "ssecvt")
22634    (set_attr "mode" "TI")])
22635
22636 (define_insn "cvttpd2pi"
22637   [(set (match_operand:V2SI 0 "register_operand" "=y")
22638         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22639                      UNSPEC_FIX))]
22640   "TARGET_SSE2"
22641   "cvttpd2pi\t{%1, %0|%0, %1}"
22642   [(set_attr "type" "ssecvt")
22643    (set_attr "mode" "TI")])
22644
22645 (define_insn "cvtpi2pd"
22646   [(set (match_operand:V2DF 0 "register_operand" "=x")
22647         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22648   "TARGET_SSE2"
22649   "cvtpi2pd\t{%1, %0|%0, %1}"
22650   [(set_attr "type" "ssecvt")
22651    (set_attr "mode" "TI")])
22652
22653 ;; Conversions between SI and DF
22654
22655 (define_insn "cvtsd2si"
22656   [(set (match_operand:SI 0 "register_operand" "=r,r")
22657         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22658                                (parallel [(const_int 0)]))))]
22659   "TARGET_SSE2"
22660   "cvtsd2si\t{%1, %0|%0, %1}"
22661   [(set_attr "type" "sseicvt")
22662    (set_attr "athlon_decode" "double,vector")
22663    (set_attr "mode" "SI")])
22664
22665 (define_insn "cvtsd2siq"
22666   [(set (match_operand:DI 0 "register_operand" "=r,r")
22667         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22668                                (parallel [(const_int 0)]))))]
22669   "TARGET_SSE2 && TARGET_64BIT"
22670   "cvtsd2siq\t{%1, %0|%0, %1}"
22671   [(set_attr "type" "sseicvt")
22672    (set_attr "athlon_decode" "double,vector")
22673    (set_attr "mode" "DI")])
22674
22675 (define_insn "cvttsd2si"
22676   [(set (match_operand:SI 0 "register_operand" "=r,r")
22677         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22678                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22679   "TARGET_SSE2"
22680   "cvttsd2si\t{%1, %0|%0, %1}"
22681   [(set_attr "type" "sseicvt")
22682    (set_attr "mode" "SI")
22683    (set_attr "athlon_decode" "double,vector")])
22684
22685 (define_insn "cvttsd2siq"
22686   [(set (match_operand:DI 0 "register_operand" "=r,r")
22687         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22688                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22689   "TARGET_SSE2 && TARGET_64BIT"
22690   "cvttsd2siq\t{%1, %0|%0, %1}"
22691   [(set_attr "type" "sseicvt")
22692    (set_attr "mode" "DI")
22693    (set_attr "athlon_decode" "double,vector")])
22694
22695 (define_insn "cvtsi2sd"
22696   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22697         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22698                         (vec_duplicate:V2DF
22699                           (float:DF
22700                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22701                         (const_int 2)))]
22702   "TARGET_SSE2"
22703   "cvtsi2sd\t{%2, %0|%0, %2}"
22704   [(set_attr "type" "sseicvt")
22705    (set_attr "mode" "DF")
22706    (set_attr "athlon_decode" "double,direct")])
22707
22708 (define_insn "cvtsi2sdq"
22709   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22710         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22711                         (vec_duplicate:V2DF
22712                           (float:DF
22713                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22714                         (const_int 2)))]
22715   "TARGET_SSE2 && TARGET_64BIT"
22716   "cvtsi2sdq\t{%2, %0|%0, %2}"
22717   [(set_attr "type" "sseicvt")
22718    (set_attr "mode" "DF")
22719    (set_attr "athlon_decode" "double,direct")])
22720
22721 ;; Conversions between SF and DF
22722
22723 (define_insn "cvtsd2ss"
22724   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22725         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22726                         (vec_duplicate:V4SF
22727                           (float_truncate:V2SF
22728                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22729                         (const_int 14)))]
22730   "TARGET_SSE2"
22731   "cvtsd2ss\t{%2, %0|%0, %2}"
22732   [(set_attr "type" "ssecvt")
22733    (set_attr "athlon_decode" "vector,double")
22734    (set_attr "mode" "SF")])
22735
22736 (define_insn "cvtss2sd"
22737   [(set (match_operand:V2DF 0 "register_operand" "=x")
22738         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
22739                         (float_extend:V2DF
22740                           (vec_select:V2SF
22741                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
22742                             (parallel [(const_int 0)
22743                                        (const_int 1)])))
22744                         (const_int 2)))]
22745   "TARGET_SSE2"
22746   "cvtss2sd\t{%2, %0|%0, %2}"
22747   [(set_attr "type" "ssecvt")
22748    (set_attr "mode" "DF")])
22749
22750 (define_insn "cvtpd2ps"
22751   [(set (match_operand:V4SF 0 "register_operand" "=x")
22752         (subreg:V4SF
22753           (vec_concat:V4SI
22754             (subreg:V2SI (float_truncate:V2SF
22755                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
22756             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
22757   "TARGET_SSE2"
22758   "cvtpd2ps\t{%1, %0|%0, %1}"
22759   [(set_attr "type" "ssecvt")
22760    (set_attr "mode" "V4SF")])
22761
22762 (define_insn "cvtps2pd"
22763   [(set (match_operand:V2DF 0 "register_operand" "=x")
22764         (float_extend:V2DF
22765           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
22766                            (parallel [(const_int 0)
22767                                       (const_int 1)]))))]
22768   "TARGET_SSE2"
22769   "cvtps2pd\t{%1, %0|%0, %1}"
22770   [(set_attr "type" "ssecvt")
22771    (set_attr "mode" "V2DF")])
22772
22773 ;; SSE2 variants of MMX insns
22774
22775 ;; MMX arithmetic
22776
22777 (define_insn "addv16qi3"
22778   [(set (match_operand:V16QI 0 "register_operand" "=x")
22779         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22780                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22781   "TARGET_SSE2"
22782   "paddb\t{%2, %0|%0, %2}"
22783   [(set_attr "type" "sseiadd")
22784    (set_attr "mode" "TI")])
22785
22786 (define_insn "addv8hi3"
22787   [(set (match_operand:V8HI 0 "register_operand" "=x")
22788         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22789                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22790   "TARGET_SSE2"
22791   "paddw\t{%2, %0|%0, %2}"
22792   [(set_attr "type" "sseiadd")
22793    (set_attr "mode" "TI")])
22794
22795 (define_insn "addv4si3"
22796   [(set (match_operand:V4SI 0 "register_operand" "=x")
22797         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22798                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22799   "TARGET_SSE2"
22800   "paddd\t{%2, %0|%0, %2}"
22801   [(set_attr "type" "sseiadd")
22802    (set_attr "mode" "TI")])
22803
22804 (define_insn "addv2di3"
22805   [(set (match_operand:V2DI 0 "register_operand" "=x")
22806         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
22807                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22808   "TARGET_SSE2"
22809   "paddq\t{%2, %0|%0, %2}"
22810   [(set_attr "type" "sseiadd")
22811    (set_attr "mode" "TI")])
22812
22813 (define_insn "ssaddv16qi3"
22814   [(set (match_operand:V16QI 0 "register_operand" "=x")
22815         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22816                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22817   "TARGET_SSE2"
22818   "paddsb\t{%2, %0|%0, %2}"
22819   [(set_attr "type" "sseiadd")
22820    (set_attr "mode" "TI")])
22821
22822 (define_insn "ssaddv8hi3"
22823   [(set (match_operand:V8HI 0 "register_operand" "=x")
22824         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22825                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22826   "TARGET_SSE2"
22827   "paddsw\t{%2, %0|%0, %2}"
22828   [(set_attr "type" "sseiadd")
22829    (set_attr "mode" "TI")])
22830
22831 (define_insn "usaddv16qi3"
22832   [(set (match_operand:V16QI 0 "register_operand" "=x")
22833         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22834                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22835   "TARGET_SSE2"
22836   "paddusb\t{%2, %0|%0, %2}"
22837   [(set_attr "type" "sseiadd")
22838    (set_attr "mode" "TI")])
22839
22840 (define_insn "usaddv8hi3"
22841   [(set (match_operand:V8HI 0 "register_operand" "=x")
22842         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22843                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22844   "TARGET_SSE2"
22845   "paddusw\t{%2, %0|%0, %2}"
22846   [(set_attr "type" "sseiadd")
22847    (set_attr "mode" "TI")])
22848
22849 (define_insn "subv16qi3"
22850   [(set (match_operand:V16QI 0 "register_operand" "=x")
22851         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22852                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22853   "TARGET_SSE2"
22854   "psubb\t{%2, %0|%0, %2}"
22855   [(set_attr "type" "sseiadd")
22856    (set_attr "mode" "TI")])
22857
22858 (define_insn "subv8hi3"
22859   [(set (match_operand:V8HI 0 "register_operand" "=x")
22860         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22861                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22862   "TARGET_SSE2"
22863   "psubw\t{%2, %0|%0, %2}"
22864   [(set_attr "type" "sseiadd")
22865    (set_attr "mode" "TI")])
22866
22867 (define_insn "subv4si3"
22868   [(set (match_operand:V4SI 0 "register_operand" "=x")
22869         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
22870                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22871   "TARGET_SSE2"
22872   "psubd\t{%2, %0|%0, %2}"
22873   [(set_attr "type" "sseiadd")
22874    (set_attr "mode" "TI")])
22875
22876 (define_insn "subv2di3"
22877   [(set (match_operand:V2DI 0 "register_operand" "=x")
22878         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
22879                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22880   "TARGET_SSE2"
22881   "psubq\t{%2, %0|%0, %2}"
22882   [(set_attr "type" "sseiadd")
22883    (set_attr "mode" "TI")])
22884
22885 (define_insn "sssubv16qi3"
22886   [(set (match_operand:V16QI 0 "register_operand" "=x")
22887         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22888                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22889   "TARGET_SSE2"
22890   "psubsb\t{%2, %0|%0, %2}"
22891   [(set_attr "type" "sseiadd")
22892    (set_attr "mode" "TI")])
22893
22894 (define_insn "sssubv8hi3"
22895   [(set (match_operand:V8HI 0 "register_operand" "=x")
22896         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22897                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22898   "TARGET_SSE2"
22899   "psubsw\t{%2, %0|%0, %2}"
22900   [(set_attr "type" "sseiadd")
22901    (set_attr "mode" "TI")])
22902
22903 (define_insn "ussubv16qi3"
22904   [(set (match_operand:V16QI 0 "register_operand" "=x")
22905         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22906                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22907   "TARGET_SSE2"
22908   "psubusb\t{%2, %0|%0, %2}"
22909   [(set_attr "type" "sseiadd")
22910    (set_attr "mode" "TI")])
22911
22912 (define_insn "ussubv8hi3"
22913   [(set (match_operand:V8HI 0 "register_operand" "=x")
22914         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22915                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22916   "TARGET_SSE2"
22917   "psubusw\t{%2, %0|%0, %2}"
22918   [(set_attr "type" "sseiadd")
22919    (set_attr "mode" "TI")])
22920
22921 (define_insn "mulv8hi3"
22922   [(set (match_operand:V8HI 0 "register_operand" "=x")
22923         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
22924                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22925   "TARGET_SSE2"
22926   "pmullw\t{%2, %0|%0, %2}"
22927   [(set_attr "type" "sseimul")
22928    (set_attr "mode" "TI")])
22929
22930 (define_insn "smulv8hi3_highpart"
22931   [(set (match_operand:V8HI 0 "register_operand" "=x")
22932         (truncate:V8HI
22933          (lshiftrt:V8SI
22934           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22935                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22936           (const_int 16))))]
22937   "TARGET_SSE2"
22938   "pmulhw\t{%2, %0|%0, %2}"
22939   [(set_attr "type" "sseimul")
22940    (set_attr "mode" "TI")])
22941
22942 (define_insn "umulv8hi3_highpart"
22943   [(set (match_operand:V8HI 0 "register_operand" "=x")
22944         (truncate:V8HI
22945          (lshiftrt:V8SI
22946           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22947                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22948           (const_int 16))))]
22949   "TARGET_SSE2"
22950   "pmulhuw\t{%2, %0|%0, %2}"
22951   [(set_attr "type" "sseimul")
22952    (set_attr "mode" "TI")])
22953
22954 (define_insn "sse2_umulsidi3"
22955   [(set (match_operand:DI 0 "register_operand" "=y")
22956         (mult:DI (zero_extend:DI (vec_select:SI
22957                                   (match_operand:V2SI 1 "register_operand" "0")
22958                                   (parallel [(const_int 0)])))
22959                  (zero_extend:DI (vec_select:SI
22960                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22961                                   (parallel [(const_int 0)])))))]
22962   "TARGET_SSE2"
22963   "pmuludq\t{%2, %0|%0, %2}"
22964   [(set_attr "type" "mmxmul")
22965    (set_attr "mode" "DI")])
22966
22967 (define_insn "sse2_umulv2siv2di3"
22968   [(set (match_operand:V2DI 0 "register_operand" "=x")
22969         (mult:V2DI (zero_extend:V2DI
22970                      (vec_select:V2SI
22971                        (match_operand:V4SI 1 "register_operand" "0")
22972                        (parallel [(const_int 0) (const_int 2)])))
22973                    (zero_extend:V2DI
22974                      (vec_select:V2SI
22975                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22976                        (parallel [(const_int 0) (const_int 2)])))))]
22977   "TARGET_SSE2"
22978   "pmuludq\t{%2, %0|%0, %2}"
22979   [(set_attr "type" "sseimul")
22980    (set_attr "mode" "TI")])
22981
22982 (define_insn "sse2_pmaddwd"
22983   [(set (match_operand:V4SI 0 "register_operand" "=x")
22984         (plus:V4SI
22985          (mult:V4SI
22986           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22987                                              (parallel [(const_int 0)
22988                                                         (const_int 2)
22989                                                         (const_int 4)
22990                                                         (const_int 6)])))
22991           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22992                                              (parallel [(const_int 0)
22993                                                         (const_int 2)
22994                                                         (const_int 4)
22995                                                         (const_int 6)]))))
22996          (mult:V4SI
22997           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22998                                              (parallel [(const_int 1)
22999                                                         (const_int 3)
23000                                                         (const_int 5)
23001                                                         (const_int 7)])))
23002           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23003                                              (parallel [(const_int 1)
23004                                                         (const_int 3)
23005                                                         (const_int 5)
23006                                                         (const_int 7)]))))))]
23007   "TARGET_SSE2"
23008   "pmaddwd\t{%2, %0|%0, %2}"
23009   [(set_attr "type" "sseiadd")
23010    (set_attr "mode" "TI")])
23011
23012 ;; Same as pxor, but don't show input operands so that we don't think
23013 ;; they are live.
23014 (define_insn "sse2_clrti"
23015   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23016   "TARGET_SSE2"
23017 {
23018   if (get_attr_mode (insn) == MODE_TI)
23019     return "pxor\t%0, %0";
23020   else
23021     return "xorps\t%0, %0";
23022 }
23023   [(set_attr "type" "ssemov")
23024    (set_attr "memory" "none")
23025    (set (attr "mode")
23026               (if_then_else
23027                 (ne (symbol_ref "optimize_size")
23028                     (const_int 0))
23029                 (const_string "V4SF")
23030                 (const_string "TI")))])
23031
23032 ;; MMX unsigned averages/sum of absolute differences
23033
23034 (define_insn "sse2_uavgv16qi3"
23035   [(set (match_operand:V16QI 0 "register_operand" "=x")
23036         (ashiftrt:V16QI
23037          (plus:V16QI (plus:V16QI
23038                      (match_operand:V16QI 1 "register_operand" "0")
23039                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23040                      (const_vector:V16QI [(const_int 1) (const_int 1)
23041                                           (const_int 1) (const_int 1)
23042                                           (const_int 1) (const_int 1)
23043                                           (const_int 1) (const_int 1)
23044                                           (const_int 1) (const_int 1)
23045                                           (const_int 1) (const_int 1)
23046                                           (const_int 1) (const_int 1)
23047                                           (const_int 1) (const_int 1)]))
23048          (const_int 1)))]
23049   "TARGET_SSE2"
23050   "pavgb\t{%2, %0|%0, %2}"
23051   [(set_attr "type" "sseiadd")
23052    (set_attr "mode" "TI")])
23053
23054 (define_insn "sse2_uavgv8hi3"
23055   [(set (match_operand:V8HI 0 "register_operand" "=x")
23056         (ashiftrt:V8HI
23057          (plus:V8HI (plus:V8HI
23058                      (match_operand:V8HI 1 "register_operand" "0")
23059                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23060                     (const_vector:V8HI [(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)))]
23065   "TARGET_SSE2"
23066   "pavgw\t{%2, %0|%0, %2}"
23067   [(set_attr "type" "sseiadd")
23068    (set_attr "mode" "TI")])
23069
23070 ;; @@@ this isn't the right representation.
23071 (define_insn "sse2_psadbw"
23072   [(set (match_operand:V2DI 0 "register_operand" "=x")
23073         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23074                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23075                      UNSPEC_PSADBW))]
23076   "TARGET_SSE2"
23077   "psadbw\t{%2, %0|%0, %2}"
23078   [(set_attr "type" "sseiadd")
23079    (set_attr "mode" "TI")])
23080
23081
23082 ;; MMX insert/extract/shuffle
23083
23084 (define_insn "sse2_pinsrw"
23085   [(set (match_operand:V8HI 0 "register_operand" "=x")
23086         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
23087                         (vec_duplicate:V8HI
23088                          (truncate:HI
23089                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
23090                         (match_operand:SI 3 "const_0_to_255_operand" "N")))]
23091   "TARGET_SSE2"
23092   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
23093   [(set_attr "type" "ssecvt")
23094    (set_attr "mode" "TI")])
23095
23096 (define_insn "sse2_pextrw"
23097   [(set (match_operand:SI 0 "register_operand" "=r")
23098         (zero_extend:SI
23099           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23100                          (parallel
23101                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23102   "TARGET_SSE2"
23103   "pextrw\t{%2, %1, %0|%0, %1, %2}"
23104   [(set_attr "type" "ssecvt")
23105    (set_attr "mode" "TI")])
23106
23107 (define_insn "sse2_pshufd"
23108   [(set (match_operand:V4SI 0 "register_operand" "=x")
23109         (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23110                       (match_operand:SI 2 "immediate_operand" "i")]
23111                      UNSPEC_SHUFFLE))]
23112   "TARGET_SSE2"
23113   "pshufd\t{%2, %1, %0|%0, %1, %2}"
23114   [(set_attr "type" "ssecvt")
23115    (set_attr "mode" "TI")])
23116
23117 (define_insn "sse2_pshuflw"
23118   [(set (match_operand:V8HI 0 "register_operand" "=x")
23119         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23120                       (match_operand:SI 2 "immediate_operand" "i")]
23121                      UNSPEC_PSHUFLW))]
23122   "TARGET_SSE2"
23123   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23124   [(set_attr "type" "ssecvt")
23125    (set_attr "mode" "TI")])
23126
23127 (define_insn "sse2_pshufhw"
23128   [(set (match_operand:V8HI 0 "register_operand" "=x")
23129         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23130                       (match_operand:SI 2 "immediate_operand" "i")]
23131                      UNSPEC_PSHUFHW))]
23132   "TARGET_SSE2"
23133   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23134   [(set_attr "type" "ssecvt")
23135    (set_attr "mode" "TI")])
23136
23137 ;; MMX mask-generating comparisons
23138
23139 (define_insn "eqv16qi3"
23140   [(set (match_operand:V16QI 0 "register_operand" "=x")
23141         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23142                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23143   "TARGET_SSE2"
23144   "pcmpeqb\t{%2, %0|%0, %2}"
23145   [(set_attr "type" "ssecmp")
23146    (set_attr "mode" "TI")])
23147
23148 (define_insn "eqv8hi3"
23149   [(set (match_operand:V8HI 0 "register_operand" "=x")
23150         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23151                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23152   "TARGET_SSE2"
23153   "pcmpeqw\t{%2, %0|%0, %2}"
23154   [(set_attr "type" "ssecmp")
23155    (set_attr "mode" "TI")])
23156
23157 (define_insn "eqv4si3"
23158   [(set (match_operand:V4SI 0 "register_operand" "=x")
23159         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23160                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23161   "TARGET_SSE2"
23162   "pcmpeqd\t{%2, %0|%0, %2}"
23163   [(set_attr "type" "ssecmp")
23164    (set_attr "mode" "TI")])
23165
23166 (define_insn "gtv16qi3"
23167   [(set (match_operand:V16QI 0 "register_operand" "=x")
23168         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23169                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23170   "TARGET_SSE2"
23171   "pcmpgtb\t{%2, %0|%0, %2}"
23172   [(set_attr "type" "ssecmp")
23173    (set_attr "mode" "TI")])
23174
23175 (define_insn "gtv8hi3"
23176   [(set (match_operand:V8HI 0 "register_operand" "=x")
23177         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23178                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23179   "TARGET_SSE2"
23180   "pcmpgtw\t{%2, %0|%0, %2}"
23181   [(set_attr "type" "ssecmp")
23182    (set_attr "mode" "TI")])
23183
23184 (define_insn "gtv4si3"
23185   [(set (match_operand:V4SI 0 "register_operand" "=x")
23186         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23187                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23188   "TARGET_SSE2"
23189   "pcmpgtd\t{%2, %0|%0, %2}"
23190   [(set_attr "type" "ssecmp")
23191    (set_attr "mode" "TI")])
23192
23193
23194 ;; MMX max/min insns
23195
23196 (define_insn "umaxv16qi3"
23197   [(set (match_operand:V16QI 0 "register_operand" "=x")
23198         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23199                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23200   "TARGET_SSE2"
23201   "pmaxub\t{%2, %0|%0, %2}"
23202   [(set_attr "type" "sseiadd")
23203    (set_attr "mode" "TI")])
23204
23205 (define_insn "smaxv8hi3"
23206   [(set (match_operand:V8HI 0 "register_operand" "=x")
23207         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23208                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23209   "TARGET_SSE2"
23210   "pmaxsw\t{%2, %0|%0, %2}"
23211   [(set_attr "type" "sseiadd")
23212    (set_attr "mode" "TI")])
23213
23214 (define_insn "uminv16qi3"
23215   [(set (match_operand:V16QI 0 "register_operand" "=x")
23216         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23217                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23218   "TARGET_SSE2"
23219   "pminub\t{%2, %0|%0, %2}"
23220   [(set_attr "type" "sseiadd")
23221    (set_attr "mode" "TI")])
23222
23223 (define_insn "sminv8hi3"
23224   [(set (match_operand:V8HI 0 "register_operand" "=x")
23225         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23226                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23227   "TARGET_SSE2"
23228   "pminsw\t{%2, %0|%0, %2}"
23229   [(set_attr "type" "sseiadd")
23230    (set_attr "mode" "TI")])
23231
23232
23233 ;; MMX shifts
23234
23235 (define_insn "ashrv8hi3"
23236   [(set (match_operand:V8HI 0 "register_operand" "=x")
23237         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23238                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23239   "TARGET_SSE2"
23240   "psraw\t{%2, %0|%0, %2}"
23241   [(set_attr "type" "sseishft")
23242    (set_attr "mode" "TI")])
23243
23244 (define_insn "ashrv4si3"
23245   [(set (match_operand:V4SI 0 "register_operand" "=x")
23246         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23247                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23248   "TARGET_SSE2"
23249   "psrad\t{%2, %0|%0, %2}"
23250   [(set_attr "type" "sseishft")
23251    (set_attr "mode" "TI")])
23252
23253 (define_insn "lshrv8hi3"
23254   [(set (match_operand:V8HI 0 "register_operand" "=x")
23255         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23256                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23257   "TARGET_SSE2"
23258   "psrlw\t{%2, %0|%0, %2}"
23259   [(set_attr "type" "sseishft")
23260    (set_attr "mode" "TI")])
23261
23262 (define_insn "lshrv4si3"
23263   [(set (match_operand:V4SI 0 "register_operand" "=x")
23264         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23265                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23266   "TARGET_SSE2"
23267   "psrld\t{%2, %0|%0, %2}"
23268   [(set_attr "type" "sseishft")
23269    (set_attr "mode" "TI")])
23270
23271 (define_insn "lshrv2di3"
23272   [(set (match_operand:V2DI 0 "register_operand" "=x")
23273         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23274                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23275   "TARGET_SSE2"
23276   "psrlq\t{%2, %0|%0, %2}"
23277   [(set_attr "type" "sseishft")
23278    (set_attr "mode" "TI")])
23279
23280 (define_insn "ashlv8hi3"
23281   [(set (match_operand:V8HI 0 "register_operand" "=x")
23282         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23283                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23284   "TARGET_SSE2"
23285   "psllw\t{%2, %0|%0, %2}"
23286   [(set_attr "type" "sseishft")
23287    (set_attr "mode" "TI")])
23288
23289 (define_insn "ashlv4si3"
23290   [(set (match_operand:V4SI 0 "register_operand" "=x")
23291         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23292                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23293   "TARGET_SSE2"
23294   "pslld\t{%2, %0|%0, %2}"
23295   [(set_attr "type" "sseishft")
23296    (set_attr "mode" "TI")])
23297
23298 (define_insn "ashlv2di3"
23299   [(set (match_operand:V2DI 0 "register_operand" "=x")
23300         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23301                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23302   "TARGET_SSE2"
23303   "psllq\t{%2, %0|%0, %2}"
23304   [(set_attr "type" "sseishft")
23305    (set_attr "mode" "TI")])
23306
23307 (define_insn "ashrv8hi3_ti"
23308   [(set (match_operand:V8HI 0 "register_operand" "=x")
23309         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23310                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23311   "TARGET_SSE2"
23312   "psraw\t{%2, %0|%0, %2}"
23313   [(set_attr "type" "sseishft")
23314    (set_attr "mode" "TI")])
23315
23316 (define_insn "ashrv4si3_ti"
23317   [(set (match_operand:V4SI 0 "register_operand" "=x")
23318         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23319                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23320   "TARGET_SSE2"
23321   "psrad\t{%2, %0|%0, %2}"
23322   [(set_attr "type" "sseishft")
23323    (set_attr "mode" "TI")])
23324
23325 (define_insn "lshrv8hi3_ti"
23326   [(set (match_operand:V8HI 0 "register_operand" "=x")
23327         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23328                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23329   "TARGET_SSE2"
23330   "psrlw\t{%2, %0|%0, %2}"
23331   [(set_attr "type" "sseishft")
23332    (set_attr "mode" "TI")])
23333
23334 (define_insn "lshrv4si3_ti"
23335   [(set (match_operand:V4SI 0 "register_operand" "=x")
23336         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23337                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23338   "TARGET_SSE2"
23339   "psrld\t{%2, %0|%0, %2}"
23340   [(set_attr "type" "sseishft")
23341    (set_attr "mode" "TI")])
23342
23343 (define_insn "lshrv2di3_ti"
23344   [(set (match_operand:V2DI 0 "register_operand" "=x")
23345         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23346                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23347   "TARGET_SSE2"
23348   "psrlq\t{%2, %0|%0, %2}"
23349   [(set_attr "type" "sseishft")
23350    (set_attr "mode" "TI")])
23351
23352 (define_insn "ashlv8hi3_ti"
23353   [(set (match_operand:V8HI 0 "register_operand" "=x")
23354         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23355                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23356   "TARGET_SSE2"
23357   "psllw\t{%2, %0|%0, %2}"
23358   [(set_attr "type" "sseishft")
23359    (set_attr "mode" "TI")])
23360
23361 (define_insn "ashlv4si3_ti"
23362   [(set (match_operand:V4SI 0 "register_operand" "=x")
23363         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23364                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23365   "TARGET_SSE2"
23366   "pslld\t{%2, %0|%0, %2}"
23367   [(set_attr "type" "sseishft")
23368    (set_attr "mode" "TI")])
23369
23370 (define_insn "ashlv2di3_ti"
23371   [(set (match_operand:V2DI 0 "register_operand" "=x")
23372         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23373                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23374   "TARGET_SSE2"
23375   "psllq\t{%2, %0|%0, %2}"
23376   [(set_attr "type" "sseishft")
23377    (set_attr "mode" "TI")])
23378
23379 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
23380 ;; we wouldn't need here it since we never generate TImode arithmetic.
23381
23382 ;; There has to be some kind of prize for the weirdest new instruction...
23383 (define_insn "sse2_ashlti3"
23384   [(set (match_operand:TI 0 "register_operand" "=x")
23385         (unspec:TI
23386          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23387                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23388                                (const_int 8)))] UNSPEC_NOP))]
23389   "TARGET_SSE2"
23390   "pslldq\t{%2, %0|%0, %2}"
23391   [(set_attr "type" "sseishft")
23392    (set_attr "mode" "TI")])
23393
23394 (define_insn "sse2_lshrti3"
23395   [(set (match_operand:TI 0 "register_operand" "=x")
23396         (unspec:TI
23397          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23398                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23399                                 (const_int 8)))] UNSPEC_NOP))]
23400   "TARGET_SSE2"
23401   "psrldq\t{%2, %0|%0, %2}"
23402   [(set_attr "type" "sseishft")
23403    (set_attr "mode" "TI")])
23404
23405 ;; SSE unpack
23406
23407 (define_insn "sse2_unpckhpd"
23408   [(set (match_operand:V2DF 0 "register_operand" "=x")
23409         (vec_concat:V2DF
23410          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23411                         (parallel [(const_int 1)]))
23412          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23413                         (parallel [(const_int 1)]))))]
23414   "TARGET_SSE2"
23415   "unpckhpd\t{%2, %0|%0, %2}"
23416   [(set_attr "type" "ssecvt")
23417    (set_attr "mode" "V2DF")])
23418
23419 (define_insn "sse2_unpcklpd"
23420   [(set (match_operand:V2DF 0 "register_operand" "=x")
23421         (vec_concat:V2DF
23422          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23423                         (parallel [(const_int 0)]))
23424          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23425                         (parallel [(const_int 0)]))))]
23426   "TARGET_SSE2"
23427   "unpcklpd\t{%2, %0|%0, %2}"
23428   [(set_attr "type" "ssecvt")
23429    (set_attr "mode" "V2DF")])
23430
23431 ;; MMX pack/unpack insns.
23432
23433 (define_insn "sse2_packsswb"
23434   [(set (match_operand:V16QI 0 "register_operand" "=x")
23435         (vec_concat:V16QI
23436          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23437          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23438   "TARGET_SSE2"
23439   "packsswb\t{%2, %0|%0, %2}"
23440   [(set_attr "type" "ssecvt")
23441    (set_attr "mode" "TI")])
23442
23443 (define_insn "sse2_packssdw"
23444   [(set (match_operand:V8HI 0 "register_operand" "=x")
23445         (vec_concat:V8HI
23446          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23447          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23448   "TARGET_SSE2"
23449   "packssdw\t{%2, %0|%0, %2}"
23450   [(set_attr "type" "ssecvt")
23451    (set_attr "mode" "TI")])
23452
23453 (define_insn "sse2_packuswb"
23454   [(set (match_operand:V16QI 0 "register_operand" "=x")
23455         (vec_concat:V16QI
23456          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23457          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23458   "TARGET_SSE2"
23459   "packuswb\t{%2, %0|%0, %2}"
23460   [(set_attr "type" "ssecvt")
23461    (set_attr "mode" "TI")])
23462
23463 (define_insn "sse2_punpckhbw"
23464   [(set (match_operand:V16QI 0 "register_operand" "=x")
23465         (vec_merge:V16QI
23466          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23467                            (parallel [(const_int 8) (const_int 0)
23468                                       (const_int 9) (const_int 1)
23469                                       (const_int 10) (const_int 2)
23470                                       (const_int 11) (const_int 3)
23471                                       (const_int 12) (const_int 4)
23472                                       (const_int 13) (const_int 5)
23473                                       (const_int 14) (const_int 6)
23474                                       (const_int 15) (const_int 7)]))
23475          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23476                            (parallel [(const_int 0) (const_int 8)
23477                                       (const_int 1) (const_int 9)
23478                                       (const_int 2) (const_int 10)
23479                                       (const_int 3) (const_int 11)
23480                                       (const_int 4) (const_int 12)
23481                                       (const_int 5) (const_int 13)
23482                                       (const_int 6) (const_int 14)
23483                                       (const_int 7) (const_int 15)]))
23484          (const_int 21845)))]
23485   "TARGET_SSE2"
23486   "punpckhbw\t{%2, %0|%0, %2}"
23487   [(set_attr "type" "ssecvt")
23488    (set_attr "mode" "TI")])
23489
23490 (define_insn "sse2_punpckhwd"
23491   [(set (match_operand:V8HI 0 "register_operand" "=x")
23492         (vec_merge:V8HI
23493          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23494                           (parallel [(const_int 4) (const_int 0)
23495                                      (const_int 5) (const_int 1)
23496                                      (const_int 6) (const_int 2)
23497                                      (const_int 7) (const_int 3)]))
23498          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23499                           (parallel [(const_int 0) (const_int 4)
23500                                      (const_int 1) (const_int 5)
23501                                      (const_int 2) (const_int 6)
23502                                      (const_int 3) (const_int 7)]))
23503          (const_int 85)))]
23504   "TARGET_SSE2"
23505   "punpckhwd\t{%2, %0|%0, %2}"
23506   [(set_attr "type" "ssecvt")
23507    (set_attr "mode" "TI")])
23508
23509 (define_insn "sse2_punpckhdq"
23510   [(set (match_operand:V4SI 0 "register_operand" "=x")
23511         (vec_merge:V4SI
23512          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23513                           (parallel [(const_int 2) (const_int 0)
23514                                      (const_int 3) (const_int 1)]))
23515          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23516                           (parallel [(const_int 0) (const_int 2)
23517                                      (const_int 1) (const_int 3)]))
23518          (const_int 5)))]
23519   "TARGET_SSE2"
23520   "punpckhdq\t{%2, %0|%0, %2}"
23521   [(set_attr "type" "ssecvt")
23522    (set_attr "mode" "TI")])
23523
23524 (define_insn "sse2_punpcklbw"
23525   [(set (match_operand:V16QI 0 "register_operand" "=x")
23526         (vec_merge:V16QI
23527          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23528                            (parallel [(const_int 0) (const_int 8)
23529                                       (const_int 1) (const_int 9)
23530                                       (const_int 2) (const_int 10)
23531                                       (const_int 3) (const_int 11)
23532                                       (const_int 4) (const_int 12)
23533                                       (const_int 5) (const_int 13)
23534                                       (const_int 6) (const_int 14)
23535                                       (const_int 7) (const_int 15)]))
23536          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23537                            (parallel [(const_int 8) (const_int 0)
23538                                       (const_int 9) (const_int 1)
23539                                       (const_int 10) (const_int 2)
23540                                       (const_int 11) (const_int 3)
23541                                       (const_int 12) (const_int 4)
23542                                       (const_int 13) (const_int 5)
23543                                       (const_int 14) (const_int 6)
23544                                       (const_int 15) (const_int 7)]))
23545          (const_int 21845)))]
23546   "TARGET_SSE2"
23547   "punpcklbw\t{%2, %0|%0, %2}"
23548   [(set_attr "type" "ssecvt")
23549    (set_attr "mode" "TI")])
23550
23551 (define_insn "sse2_punpcklwd"
23552   [(set (match_operand:V8HI 0 "register_operand" "=x")
23553         (vec_merge:V8HI
23554          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23555                           (parallel [(const_int 0) (const_int 4)
23556                                      (const_int 1) (const_int 5)
23557                                      (const_int 2) (const_int 6)
23558                                      (const_int 3) (const_int 7)]))
23559          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23560                           (parallel [(const_int 4) (const_int 0)
23561                                      (const_int 5) (const_int 1)
23562                                      (const_int 6) (const_int 2)
23563                                      (const_int 7) (const_int 3)]))
23564          (const_int 85)))]
23565   "TARGET_SSE2"
23566   "punpcklwd\t{%2, %0|%0, %2}"
23567   [(set_attr "type" "ssecvt")
23568    (set_attr "mode" "TI")])
23569
23570 (define_insn "sse2_punpckldq"
23571   [(set (match_operand:V4SI 0 "register_operand" "=x")
23572         (vec_merge:V4SI
23573          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23574                           (parallel [(const_int 0) (const_int 2)
23575                                      (const_int 1) (const_int 3)]))
23576          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23577                           (parallel [(const_int 2) (const_int 0)
23578                                      (const_int 3) (const_int 1)]))
23579          (const_int 5)))]
23580   "TARGET_SSE2"
23581   "punpckldq\t{%2, %0|%0, %2}"
23582   [(set_attr "type" "ssecvt")
23583    (set_attr "mode" "TI")])
23584
23585 (define_insn "sse2_punpcklqdq"
23586   [(set (match_operand:V2DI 0 "register_operand" "=x")
23587         (vec_merge:V2DI
23588          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23589                           (parallel [(const_int 1)
23590                                      (const_int 0)]))
23591          (match_operand:V2DI 1 "register_operand" "0")
23592          (const_int 1)))]
23593   "TARGET_SSE2"
23594   "punpcklqdq\t{%2, %0|%0, %2}"
23595   [(set_attr "type" "ssecvt")
23596    (set_attr "mode" "TI")])
23597
23598 (define_insn "sse2_punpckhqdq"
23599   [(set (match_operand:V2DI 0 "register_operand" "=x")
23600         (vec_merge:V2DI
23601          (match_operand:V2DI 1 "register_operand" "0")
23602          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23603                           (parallel [(const_int 1)
23604                                      (const_int 0)]))
23605          (const_int 1)))]
23606   "TARGET_SSE2"
23607   "punpckhqdq\t{%2, %0|%0, %2}"
23608   [(set_attr "type" "ssecvt")
23609    (set_attr "mode" "TI")])
23610
23611 ;; SSE2 moves
23612
23613 (define_insn "sse2_movapd"
23614   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23615         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23616                      UNSPEC_MOVA))]
23617   "TARGET_SSE2
23618    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23619   "movapd\t{%1, %0|%0, %1}"
23620   [(set_attr "type" "ssemov")
23621    (set_attr "mode" "V2DF")])
23622
23623 (define_insn "sse2_movupd"
23624   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23625         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23626                      UNSPEC_MOVU))]
23627   "TARGET_SSE2
23628    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23629   "movupd\t{%1, %0|%0, %1}"
23630   [(set_attr "type" "ssecvt")
23631    (set_attr "mode" "V2DF")])
23632
23633 (define_insn "sse2_movdqa"
23634   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23635         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23636                        UNSPEC_MOVA))]
23637   "TARGET_SSE2
23638    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23639   "movdqa\t{%1, %0|%0, %1}"
23640   [(set_attr "type" "ssemov")
23641    (set_attr "mode" "TI")])
23642
23643 (define_insn "sse2_movdqu"
23644   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23645         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23646                        UNSPEC_MOVU))]
23647   "TARGET_SSE2
23648    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23649   "movdqu\t{%1, %0|%0, %1}"
23650   [(set_attr "type" "ssecvt")
23651    (set_attr "mode" "TI")])
23652
23653 (define_insn "sse2_movdq2q"
23654   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23655         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23656                        (parallel [(const_int 0)])))]
23657   "TARGET_SSE2 && !TARGET_64BIT"
23658   "@
23659    movq\t{%1, %0|%0, %1}
23660    movdq2q\t{%1, %0|%0, %1}"
23661   [(set_attr "type" "ssecvt")
23662    (set_attr "mode" "TI")])
23663
23664 (define_insn "sse2_movdq2q_rex64"
23665   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23666         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23667                        (parallel [(const_int 0)])))]
23668   "TARGET_SSE2 && TARGET_64BIT"
23669   "@
23670    movq\t{%1, %0|%0, %1}
23671    movdq2q\t{%1, %0|%0, %1}
23672    movd\t{%1, %0|%0, %1}"
23673   [(set_attr "type" "ssecvt")
23674    (set_attr "mode" "TI")])
23675
23676 (define_insn "sse2_movq2dq"
23677   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23678         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23679                          (const_int 0)))]
23680   "TARGET_SSE2 && !TARGET_64BIT"
23681   "@
23682    movq\t{%1, %0|%0, %1}
23683    movq2dq\t{%1, %0|%0, %1}"
23684   [(set_attr "type" "ssecvt,ssemov")
23685    (set_attr "mode" "TI")])
23686
23687 (define_insn "sse2_movq2dq_rex64"
23688   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23689         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23690                          (const_int 0)))]
23691   "TARGET_SSE2 && TARGET_64BIT"
23692   "@
23693    movq\t{%1, %0|%0, %1}
23694    movq2dq\t{%1, %0|%0, %1}
23695    movd\t{%1, %0|%0, %1}"
23696   [(set_attr "type" "ssecvt,ssemov,ssecvt")
23697    (set_attr "mode" "TI")])
23698
23699 (define_insn "sse2_movq"
23700   [(set (match_operand:V2DI 0 "register_operand" "=x")
23701         (vec_concat:V2DI (vec_select:DI
23702                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23703                           (parallel [(const_int 0)]))
23704                          (const_int 0)))]
23705   "TARGET_SSE2"
23706   "movq\t{%1, %0|%0, %1}"
23707   [(set_attr "type" "ssemov")
23708    (set_attr "mode" "TI")])
23709
23710 (define_insn "sse2_loadd"
23711   [(set (match_operand:V4SI 0 "register_operand" "=x")
23712         (vec_merge:V4SI
23713          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23714          (const_vector:V4SI [(const_int 0)
23715                              (const_int 0)
23716                              (const_int 0)
23717                              (const_int 0)])
23718          (const_int 1)))]
23719   "TARGET_SSE2"
23720   "movd\t{%1, %0|%0, %1}"
23721   [(set_attr "type" "ssemov")
23722    (set_attr "mode" "TI")])
23723
23724 (define_insn "sse2_stored"
23725   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23726         (vec_select:SI
23727          (match_operand:V4SI 1 "register_operand" "x")
23728          (parallel [(const_int 0)])))]
23729   "TARGET_SSE2"
23730   "movd\t{%1, %0|%0, %1}"
23731   [(set_attr "type" "ssemov")
23732    (set_attr "mode" "TI")])
23733
23734 (define_insn "sse2_movhpd"
23735   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23736         (vec_merge:V2DF
23737          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23738          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23739          (const_int 1)))]
23740   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23741   "movhpd\t{%2, %0|%0, %2}"
23742   [(set_attr "type" "ssecvt")
23743    (set_attr "mode" "V2DF")])
23744
23745 (define_expand "sse2_loadsd"
23746   [(match_operand:V2DF 0 "register_operand" "")
23747    (match_operand:DF 1 "memory_operand" "")]
23748   "TARGET_SSE2"
23749 {
23750   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
23751                                 CONST0_RTX (V2DFmode)));
23752   DONE;
23753 })
23754
23755 (define_insn "sse2_loadsd_1"
23756   [(set (match_operand:V2DF 0 "register_operand" "=x")
23757         (vec_merge:V2DF
23758          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
23759          (match_operand:V2DF 2 "const0_operand" "X")
23760          (const_int 1)))]
23761   "TARGET_SSE2"
23762   "movsd\t{%1, %0|%0, %1}"
23763   [(set_attr "type" "ssecvt")
23764    (set_attr "mode" "DF")])
23765
23766 ;; ??? We ought to be using ix86_binary_operator_ok on this pattern, so
23767 ;; that we enforce the whole matching memory thing through combine et al.
23768 ;; But that requires that things be set up properly when invoked via an
23769 ;; intrinsic, which we don't do.  Which leads to instantiate virtual regs
23770 ;; lossage, as seen compiling gcc.dg/i386-sse-2.c for x86_64 at -O0.
23771 (define_insn "sse2_movsd"
23772   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
23773         (vec_merge:V2DF
23774          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
23775          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
23776          (const_int 2)))]
23777   "TARGET_SSE2"
23778   "@movsd\t{%2, %0|%0, %2}
23779     movlpd\t{%2, %0|%0, %2}
23780     movlpd\t{%2, %0|%0, %2}"
23781   [(set_attr "type" "ssecvt")
23782    (set_attr "mode" "DF,V2DF,V2DF")])
23783
23784 (define_insn "sse2_storesd"
23785   [(set (match_operand:DF 0 "memory_operand" "=m")
23786         (vec_select:DF
23787          (match_operand:V2DF 1 "register_operand" "x")
23788          (parallel [(const_int 0)])))]
23789   "TARGET_SSE2"
23790   "movsd\t{%1, %0|%0, %1}"
23791   [(set_attr "type" "ssecvt")
23792    (set_attr "mode" "DF")])
23793
23794 (define_insn "sse2_shufpd"
23795   [(set (match_operand:V2DF 0 "register_operand" "=x")
23796         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23797                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
23798                       (match_operand:SI 3 "immediate_operand" "i")]
23799                      UNSPEC_SHUFFLE))]
23800   "TARGET_SSE2"
23801   ;; @@@ check operand order for intel/nonintel syntax
23802   "shufpd\t{%3, %2, %0|%0, %2, %3}"
23803   [(set_attr "type" "ssecvt")
23804    (set_attr "mode" "V2DF")])
23805
23806 (define_insn "sse2_clflush"
23807   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
23808                     UNSPECV_CLFLUSH)]
23809   "TARGET_SSE2"
23810   "clflush\t%a0"
23811   [(set_attr "type" "sse")
23812    (set_attr "memory" "unknown")])
23813
23814 (define_expand "sse2_mfence"
23815   [(set (match_dup 0)
23816         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23817   "TARGET_SSE2"
23818 {
23819   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23820   MEM_VOLATILE_P (operands[0]) = 1;
23821 })
23822
23823 (define_insn "*mfence_insn"
23824   [(set (match_operand:BLK 0 "" "")
23825         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23826   "TARGET_SSE2"
23827   "mfence"
23828   [(set_attr "type" "sse")
23829    (set_attr "memory" "unknown")])
23830
23831 (define_expand "sse2_lfence"
23832   [(set (match_dup 0)
23833         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23834   "TARGET_SSE2"
23835 {
23836   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23837   MEM_VOLATILE_P (operands[0]) = 1;
23838 })
23839
23840 (define_insn "*lfence_insn"
23841   [(set (match_operand:BLK 0 "" "")
23842         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23843   "TARGET_SSE2"
23844   "lfence"
23845   [(set_attr "type" "sse")
23846    (set_attr "memory" "unknown")])
23847
23848 ;; SSE3
23849
23850 (define_insn "mwait"
23851   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23852                      (match_operand:SI 1 "register_operand" "c")]
23853                     UNSPECV_MWAIT)]
23854   "TARGET_SSE3"
23855   "mwait\t%0, %1"
23856   [(set_attr "length" "3")])
23857
23858 (define_insn "monitor"
23859   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23860                      (match_operand:SI 1 "register_operand" "c")
23861                      (match_operand:SI 2 "register_operand" "d")]
23862                     UNSPECV_MONITOR)]
23863   "TARGET_SSE3"
23864   "monitor\t%0, %1, %2"
23865   [(set_attr "length" "3")])
23866
23867 ;; SSE3 arithmetic
23868
23869 (define_insn "addsubv4sf3"
23870   [(set (match_operand:V4SF 0 "register_operand" "=x")
23871         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23872                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23873                      UNSPEC_ADDSUB))]
23874   "TARGET_SSE3"
23875   "addsubps\t{%2, %0|%0, %2}"
23876   [(set_attr "type" "sseadd")
23877    (set_attr "mode" "V4SF")])
23878
23879 (define_insn "addsubv2df3"
23880   [(set (match_operand:V2DF 0 "register_operand" "=x")
23881         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23882                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23883                      UNSPEC_ADDSUB))]
23884   "TARGET_SSE3"
23885   "addsubpd\t{%2, %0|%0, %2}"
23886   [(set_attr "type" "sseadd")
23887    (set_attr "mode" "V2DF")])
23888
23889 (define_insn "haddv4sf3"
23890   [(set (match_operand:V4SF 0 "register_operand" "=x")
23891         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23892                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23893                      UNSPEC_HADD))]
23894   "TARGET_SSE3"
23895   "haddps\t{%2, %0|%0, %2}"
23896   [(set_attr "type" "sseadd")
23897    (set_attr "mode" "V4SF")])
23898
23899 (define_insn "haddv2df3"
23900   [(set (match_operand:V2DF 0 "register_operand" "=x")
23901         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23902                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23903                      UNSPEC_HADD))]
23904   "TARGET_SSE3"
23905   "haddpd\t{%2, %0|%0, %2}"
23906   [(set_attr "type" "sseadd")
23907    (set_attr "mode" "V2DF")])
23908
23909 (define_insn "hsubv4sf3"
23910   [(set (match_operand:V4SF 0 "register_operand" "=x")
23911         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23912                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23913                      UNSPEC_HSUB))]
23914   "TARGET_SSE3"
23915   "hsubps\t{%2, %0|%0, %2}"
23916   [(set_attr "type" "sseadd")
23917    (set_attr "mode" "V4SF")])
23918
23919 (define_insn "hsubv2df3"
23920   [(set (match_operand:V2DF 0 "register_operand" "=x")
23921         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23922                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23923                      UNSPEC_HSUB))]
23924   "TARGET_SSE3"
23925   "hsubpd\t{%2, %0|%0, %2}"
23926   [(set_attr "type" "sseadd")
23927    (set_attr "mode" "V2DF")])
23928
23929 (define_insn "movshdup"
23930   [(set (match_operand:V4SF 0 "register_operand" "=x")
23931         (unspec:V4SF
23932          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
23933   "TARGET_SSE3"
23934   "movshdup\t{%1, %0|%0, %1}"
23935   [(set_attr "type" "sse")
23936    (set_attr "mode" "V4SF")])
23937
23938 (define_insn "movsldup"
23939   [(set (match_operand:V4SF 0 "register_operand" "=x")
23940         (unspec:V4SF
23941          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
23942   "TARGET_SSE3"
23943   "movsldup\t{%1, %0|%0, %1}"
23944   [(set_attr "type" "sse")
23945    (set_attr "mode" "V4SF")])
23946
23947 (define_insn "lddqu"
23948   [(set (match_operand:V16QI 0 "register_operand" "=x")
23949         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
23950                        UNSPEC_LDQQU))]
23951   "TARGET_SSE3"
23952   "lddqu\t{%1, %0|%0, %1}"
23953   [(set_attr "type" "ssecvt")
23954    (set_attr "mode" "TI")])
23955
23956 (define_insn "loadddup"
23957   [(set (match_operand:V2DF 0 "register_operand" "=x")
23958         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
23959   "TARGET_SSE3"
23960   "movddup\t{%1, %0|%0, %1}"
23961   [(set_attr "type" "ssecvt")
23962    (set_attr "mode" "DF")])
23963
23964 (define_insn "movddup"
23965   [(set (match_operand:V2DF 0 "register_operand" "=x")
23966         (vec_duplicate:V2DF
23967          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
23968                         (parallel [(const_int 0)]))))]
23969   "TARGET_SSE3"
23970   "movddup\t{%1, %0|%0, %1}"
23971   [(set_attr "type" "ssecvt")
23972    (set_attr "mode" "DF")])