OSDN Git Service

* config/i386/i386.md (floathisf2, *floathisf2_1, floatsisf2,
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69
70    ; TLS support
71    (UNSPEC_TP                   15)
72    (UNSPEC_TLS_GD               16)
73    (UNSPEC_TLS_LD_BASE          17)
74
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_SIN                  21)
78    (UNSPEC_COS                  22)
79    (UNSPEC_FNSTSW               24)
80    (UNSPEC_SAHF                 25)
81    (UNSPEC_FSTCW                26)
82    (UNSPEC_ADD_CARRY            27)
83    (UNSPEC_FLDCW                28)
84
85    ; For SSE/MMX support:
86    (UNSPEC_FIX                  30)
87    (UNSPEC_MASKMOV              32)
88    (UNSPEC_MOVMSK               33)
89    (UNSPEC_MOVNT                34)
90    (UNSPEC_MOVA                 38)
91    (UNSPEC_MOVU                 39)
92    (UNSPEC_SHUFFLE              41)
93    (UNSPEC_RCP                  42)
94    (UNSPEC_RSQRT                43)
95    (UNSPEC_SFENCE               44)
96    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
97    (UNSPEC_PAVGUSB              49)
98    (UNSPEC_PFRCP                50)
99    (UNSPEC_PFRCPIT1             51)
100    (UNSPEC_PFRCPIT2             52)
101    (UNSPEC_PFRSQRT              53)
102    (UNSPEC_PFRSQIT1             54)
103    (UNSPEC_PSHUFLW              55)
104    (UNSPEC_PSHUFHW              56)
105    (UNSPEC_MFENCE               59)
106    (UNSPEC_LFENCE               60)
107    (UNSPEC_PSADBW               61)
108    (UNSPEC_ADDSUB               71)
109    (UNSPEC_HADD                 72)
110    (UNSPEC_HSUB                 73)
111    (UNSPEC_MOVSHDUP             74)
112    (UNSPEC_MOVSLDUP             75)
113    (UNSPEC_LDQQU                76)
114    (UNSPEC_MOVDDUP              77)
115
116    ; x87 Floating point
117    (UNSPEC_FPATAN               65)
118    (UNSPEC_FYL2X                66)
119    (UNSPEC_FYL2XP1              67)
120    (UNSPEC_FRNDINT              68)
121    (UNSPEC_F2XM1                69)
122
123    ; x87 Double output FP
124    (UNSPEC_SINCOS_COS           80)
125    (UNSPEC_SINCOS_SIN           81)
126    (UNSPEC_TAN_ONE              82)
127    (UNSPEC_TAN_TAN              83)
128    (UNSPEC_XTRACT_FRACT         84)
129    (UNSPEC_XTRACT_EXP           85)
130    (UNSPEC_FSCALE_FRACT         86)
131    (UNSPEC_FSCALE_EXP           87)
132    (UNSPEC_FPREM_F              88)
133    (UNSPEC_FPREM_U              89)
134    (UNSPEC_FPREM1_F             90)
135    (UNSPEC_FPREM1_U             91)
136
137    ; x87 Rounding
138    (UNSPEC_FRNDINT_FLOOR        96)
139    (UNSPEC_FRNDINT_CEIL         97)
140    (UNSPEC_FRNDINT_TRUNC        98)
141    (UNSPEC_FRNDINT_MASK_PM      99)
142
143    ; REP instruction
144    (UNSPEC_REP                  75)
145
146    (UNSPEC_EH_RETURN            76)
147   ])
148
149 (define_constants
150   [(UNSPECV_BLOCKAGE            0)
151    (UNSPECV_STACK_PROBE         10)
152    (UNSPECV_EMMS                31)
153    (UNSPECV_LDMXCSR             37)
154    (UNSPECV_STMXCSR             40)
155    (UNSPECV_FEMMS               46)
156    (UNSPECV_CLFLUSH             57)
157    (UNSPECV_ALIGN               68)
158    (UNSPECV_MONITOR             69)
159    (UNSPECV_MWAIT               70)
160   ])
161
162 ;; Registers by name.
163 (define_constants
164   [(BP_REG                       6)
165    (SP_REG                       7)
166    (FLAGS_REG                   17)
167    (FPSR_REG                    18)
168    (DIRFLAG_REG                 19)
169   ])
170
171 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
172 ;; from i386.c.
173
174 ;; In C guard expressions, put expressions which may be compile-time
175 ;; constants first.  This allows for better optimization.  For
176 ;; example, write "TARGET_64BIT && reload_completed", not
177 ;; "reload_completed && TARGET_64BIT".
178
179 \f
180 ;; Processor type.  This attribute must exactly match the processor_type
181 ;; enumeration in i386.h.
182 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
183   (const (symbol_ref "ix86_tune")))
184
185 ;; A basic instruction type.  Refinements due to arguments to be
186 ;; provided in other attributes.
187 (define_attr "type"
188   "other,multi,
189    alu,alu1,negnot,imov,imovx,lea,
190    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
191    icmp,test,ibr,setcc,icmov,
192    push,pop,call,callv,leave,
193    str,cld,
194    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint,
195    sselog,sseiadd,sseishft,sseimul,
196    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
197    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
198   (const_string "other"))
199
200 ;; Main data type used by the insn
201 (define_attr "mode"
202   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
203   (const_string "unknown"))
204
205 ;; The CPU unit operations uses.
206 (define_attr "unit" "integer,i387,sse,mmx,unknown"
207   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint")
208            (const_string "i387")
209          (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
210                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
211            (const_string "sse")
212          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
213            (const_string "mmx")
214          (eq_attr "type" "other")
215            (const_string "unknown")]
216          (const_string "integer")))
217
218 ;; The (bounding maximum) length of an instruction immediate.
219 (define_attr "length_immediate" ""
220   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
221            (const_int 0)
222          (eq_attr "unit" "i387,sse,mmx")
223            (const_int 0)
224          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
225                           imul,icmp,push,pop")
226            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
227          (eq_attr "type" "imov,test")
228            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
229          (eq_attr "type" "call")
230            (if_then_else (match_operand 0 "constant_call_address_operand" "")
231              (const_int 4)
232              (const_int 0))
233          (eq_attr "type" "callv")
234            (if_then_else (match_operand 1 "constant_call_address_operand" "")
235              (const_int 4)
236              (const_int 0))
237          ;; We don't know the size before shorten_branches.  Expect
238          ;; the instruction to fit for better scheduling.
239          (eq_attr "type" "ibr")
240            (const_int 1)
241          ]
242          (symbol_ref "/* Update immediate_length and other attributes! */
243                       abort(),1")))
244
245 ;; The (bounding maximum) length of an instruction address.
246 (define_attr "length_address" ""
247   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
248            (const_int 0)
249          (and (eq_attr "type" "call")
250               (match_operand 0 "constant_call_address_operand" ""))
251              (const_int 0)
252          (and (eq_attr "type" "callv")
253               (match_operand 1 "constant_call_address_operand" ""))
254              (const_int 0)
255          ]
256          (symbol_ref "ix86_attr_length_address_default (insn)")))
257
258 ;; Set when length prefix is used.
259 (define_attr "prefix_data16" ""
260   (if_then_else (ior (eq_attr "mode" "HI")
261                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
262     (const_int 1)
263     (const_int 0)))
264
265 ;; Set when string REP prefix is used.
266 (define_attr "prefix_rep" "" 
267   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
268     (const_int 1)
269     (const_int 0)))
270
271 ;; Set when 0f opcode prefix is used.
272 (define_attr "prefix_0f" ""
273   (if_then_else 
274     (ior (eq_attr "type" "imovx,setcc,icmov")
275          (eq_attr "unit" "sse,mmx"))
276     (const_int 1)
277     (const_int 0)))
278
279 ;; Set when REX opcode prefix is used.
280 (define_attr "prefix_rex" ""
281   (cond [(and (eq_attr "mode" "DI")
282               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
283            (const_int 1)
284          (and (eq_attr "mode" "QI")
285               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
286                   (const_int 0)))
287            (const_int 1)
288          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
289              (const_int 0))
290            (const_int 1)
291         ]
292         (const_int 0)))
293
294 ;; Set when modrm byte is used.
295 (define_attr "modrm" ""
296   (cond [(eq_attr "type" "str,cld,leave")
297            (const_int 0)
298          (eq_attr "unit" "i387")
299            (const_int 0)
300          (and (eq_attr "type" "incdec")
301               (ior (match_operand:SI 1 "register_operand" "")
302                    (match_operand:HI 1 "register_operand" "")))
303            (const_int 0)
304          (and (eq_attr "type" "push")
305               (not (match_operand 1 "memory_operand" "")))
306            (const_int 0)
307          (and (eq_attr "type" "pop")
308               (not (match_operand 0 "memory_operand" "")))
309            (const_int 0)
310          (and (eq_attr "type" "imov")
311               (and (match_operand 0 "register_operand" "")
312                    (match_operand 1 "immediate_operand" "")))
313            (const_int 0)
314          (and (eq_attr "type" "call")
315               (match_operand 0 "constant_call_address_operand" ""))
316              (const_int 0)
317          (and (eq_attr "type" "callv")
318               (match_operand 1 "constant_call_address_operand" ""))
319              (const_int 0)
320          ]
321          (const_int 1)))
322
323 ;; The (bounding maximum) length of an instruction in bytes.
324 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
325 ;; Later we may want to split them and compute proper length as for
326 ;; other insns.
327 (define_attr "length" ""
328   (cond [(eq_attr "type" "other,multi,fistp,frndint")
329            (const_int 16)
330          (eq_attr "type" "fcmp")
331            (const_int 4)
332          (eq_attr "unit" "i387")
333            (plus (const_int 2)
334                  (plus (attr "prefix_data16")
335                        (attr "length_address")))]
336          (plus (plus (attr "modrm")
337                      (plus (attr "prefix_0f")
338                            (plus (attr "prefix_rex")
339                                  (const_int 1))))
340                (plus (attr "prefix_rep")
341                      (plus (attr "prefix_data16")
342                            (plus (attr "length_immediate")
343                                  (attr "length_address")))))))
344
345 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
346 ;; `store' if there is a simple memory reference therein, or `unknown'
347 ;; if the instruction is complex.
348
349 (define_attr "memory" "none,load,store,both,unknown"
350   (cond [(eq_attr "type" "other,multi,str")
351            (const_string "unknown")
352          (eq_attr "type" "lea,fcmov,fpspc,cld")
353            (const_string "none")
354          (eq_attr "type" "fistp,leave")
355            (const_string "both")
356          (eq_attr "type" "frndint")
357            (const_string "load")
358          (eq_attr "type" "push")
359            (if_then_else (match_operand 1 "memory_operand" "")
360              (const_string "both")
361              (const_string "store"))
362          (eq_attr "type" "pop")
363            (if_then_else (match_operand 0 "memory_operand" "")
364              (const_string "both")
365              (const_string "load"))
366          (eq_attr "type" "setcc")
367            (if_then_else (match_operand 0 "memory_operand" "")
368              (const_string "store")
369              (const_string "none"))
370          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
371            (if_then_else (ior (match_operand 0 "memory_operand" "")
372                               (match_operand 1 "memory_operand" ""))
373              (const_string "load")
374              (const_string "none"))
375          (eq_attr "type" "ibr")
376            (if_then_else (match_operand 0 "memory_operand" "")
377              (const_string "load")
378              (const_string "none"))
379          (eq_attr "type" "call")
380            (if_then_else (match_operand 0 "constant_call_address_operand" "")
381              (const_string "none")
382              (const_string "load"))
383          (eq_attr "type" "callv")
384            (if_then_else (match_operand 1 "constant_call_address_operand" "")
385              (const_string "none")
386              (const_string "load"))
387          (and (eq_attr "type" "alu1,negnot,ishift1")
388               (match_operand 1 "memory_operand" ""))
389            (const_string "both")
390          (and (match_operand 0 "memory_operand" "")
391               (match_operand 1 "memory_operand" ""))
392            (const_string "both")
393          (match_operand 0 "memory_operand" "")
394            (const_string "store")
395          (match_operand 1 "memory_operand" "")
396            (const_string "load")
397          (and (eq_attr "type"
398                  "!alu1,negnot,ishift1,
399                    imov,imovx,icmp,test,
400                    fmov,fcmp,fsgn,
401                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
402                    mmx,mmxmov,mmxcmp,mmxcvt")
403               (match_operand 2 "memory_operand" ""))
404            (const_string "load")
405          (and (eq_attr "type" "icmov")
406               (match_operand 3 "memory_operand" ""))
407            (const_string "load")
408         ]
409         (const_string "none")))
410
411 ;; Indicates if an instruction has both an immediate and a displacement.
412
413 (define_attr "imm_disp" "false,true,unknown"
414   (cond [(eq_attr "type" "other,multi")
415            (const_string "unknown")
416          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
417               (and (match_operand 0 "memory_displacement_operand" "")
418                    (match_operand 1 "immediate_operand" "")))
419            (const_string "true")
420          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
421               (and (match_operand 0 "memory_displacement_operand" "")
422                    (match_operand 2 "immediate_operand" "")))
423            (const_string "true")
424         ]
425         (const_string "false")))
426
427 ;; Indicates if an FP operation has an integer source.
428
429 (define_attr "fp_int_src" "false,true"
430   (const_string "false"))
431
432 ;; Defines rounding mode of an FP operation.
433
434 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
435   (const_string "any"))
436
437 ;; Describe a user's asm statement.
438 (define_asm_attributes
439   [(set_attr "length" "128")
440    (set_attr "type" "multi")])
441 \f
442 ;; Scheduling descriptions
443
444 (include "pentium.md")
445 (include "ppro.md")
446 (include "k6.md")
447 (include "athlon.md")
448
449 \f
450 ;; Operand and operator predicates
451
452 (include "predicates.md")
453
454 \f
455 ;; Compare instructions.
456
457 ;; All compare insns have expanders that save the operands away without
458 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
459 ;; after the cmp) will actually emit the cmpM.
460
461 (define_expand "cmpdi"
462   [(set (reg:CC FLAGS_REG)
463         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
464                     (match_operand:DI 1 "x86_64_general_operand" "")))]
465   ""
466 {
467   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
468     operands[0] = force_reg (DImode, operands[0]);
469   ix86_compare_op0 = operands[0];
470   ix86_compare_op1 = operands[1];
471   DONE;
472 })
473
474 (define_expand "cmpsi"
475   [(set (reg:CC FLAGS_REG)
476         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
477                     (match_operand:SI 1 "general_operand" "")))]
478   ""
479 {
480   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
481     operands[0] = force_reg (SImode, operands[0]);
482   ix86_compare_op0 = operands[0];
483   ix86_compare_op1 = operands[1];
484   DONE;
485 })
486
487 (define_expand "cmphi"
488   [(set (reg:CC FLAGS_REG)
489         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
490                     (match_operand:HI 1 "general_operand" "")))]
491   ""
492 {
493   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494     operands[0] = force_reg (HImode, operands[0]);
495   ix86_compare_op0 = operands[0];
496   ix86_compare_op1 = operands[1];
497   DONE;
498 })
499
500 (define_expand "cmpqi"
501   [(set (reg:CC FLAGS_REG)
502         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
503                     (match_operand:QI 1 "general_operand" "")))]
504   "TARGET_QIMODE_MATH"
505 {
506   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
507     operands[0] = force_reg (QImode, operands[0]);
508   ix86_compare_op0 = operands[0];
509   ix86_compare_op1 = operands[1];
510   DONE;
511 })
512
513 (define_insn "cmpdi_ccno_1_rex64"
514   [(set (reg FLAGS_REG)
515         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
516                  (match_operand:DI 1 "const0_operand" "n,n")))]
517   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
518   "@
519    test{q}\t{%0, %0|%0, %0}
520    cmp{q}\t{%1, %0|%0, %1}"
521   [(set_attr "type" "test,icmp")
522    (set_attr "length_immediate" "0,1")
523    (set_attr "mode" "DI")])
524
525 (define_insn "*cmpdi_minus_1_rex64"
526   [(set (reg FLAGS_REG)
527         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
528                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
529                  (const_int 0)))]
530   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
531   "cmp{q}\t{%1, %0|%0, %1}"
532   [(set_attr "type" "icmp")
533    (set_attr "mode" "DI")])
534
535 (define_expand "cmpdi_1_rex64"
536   [(set (reg:CC FLAGS_REG)
537         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
538                     (match_operand:DI 1 "general_operand" "")))]
539   "TARGET_64BIT"
540   "")
541
542 (define_insn "cmpdi_1_insn_rex64"
543   [(set (reg FLAGS_REG)
544         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
545                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
546   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
547   "cmp{q}\t{%1, %0|%0, %1}"
548   [(set_attr "type" "icmp")
549    (set_attr "mode" "DI")])
550
551
552 (define_insn "*cmpsi_ccno_1"
553   [(set (reg FLAGS_REG)
554         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
555                  (match_operand:SI 1 "const0_operand" "n,n")))]
556   "ix86_match_ccmode (insn, CCNOmode)"
557   "@
558    test{l}\t{%0, %0|%0, %0}
559    cmp{l}\t{%1, %0|%0, %1}"
560   [(set_attr "type" "test,icmp")
561    (set_attr "length_immediate" "0,1")
562    (set_attr "mode" "SI")])
563
564 (define_insn "*cmpsi_minus_1"
565   [(set (reg FLAGS_REG)
566         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
567                            (match_operand:SI 1 "general_operand" "ri,mr"))
568                  (const_int 0)))]
569   "ix86_match_ccmode (insn, CCGOCmode)"
570   "cmp{l}\t{%1, %0|%0, %1}"
571   [(set_attr "type" "icmp")
572    (set_attr "mode" "SI")])
573
574 (define_expand "cmpsi_1"
575   [(set (reg:CC FLAGS_REG)
576         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
577                     (match_operand:SI 1 "general_operand" "ri,mr")))]
578   ""
579   "")
580
581 (define_insn "*cmpsi_1_insn"
582   [(set (reg FLAGS_REG)
583         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
584                  (match_operand:SI 1 "general_operand" "ri,mr")))]
585   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
586     && ix86_match_ccmode (insn, CCmode)"
587   "cmp{l}\t{%1, %0|%0, %1}"
588   [(set_attr "type" "icmp")
589    (set_attr "mode" "SI")])
590
591 (define_insn "*cmphi_ccno_1"
592   [(set (reg FLAGS_REG)
593         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
594                  (match_operand:HI 1 "const0_operand" "n,n")))]
595   "ix86_match_ccmode (insn, CCNOmode)"
596   "@
597    test{w}\t{%0, %0|%0, %0}
598    cmp{w}\t{%1, %0|%0, %1}"
599   [(set_attr "type" "test,icmp")
600    (set_attr "length_immediate" "0,1")
601    (set_attr "mode" "HI")])
602
603 (define_insn "*cmphi_minus_1"
604   [(set (reg FLAGS_REG)
605         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
606                            (match_operand:HI 1 "general_operand" "ri,mr"))
607                  (const_int 0)))]
608   "ix86_match_ccmode (insn, CCGOCmode)"
609   "cmp{w}\t{%1, %0|%0, %1}"
610   [(set_attr "type" "icmp")
611    (set_attr "mode" "HI")])
612
613 (define_insn "*cmphi_1"
614   [(set (reg FLAGS_REG)
615         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
616                  (match_operand:HI 1 "general_operand" "ri,mr")))]
617   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
618    && ix86_match_ccmode (insn, CCmode)"
619   "cmp{w}\t{%1, %0|%0, %1}"
620   [(set_attr "type" "icmp")
621    (set_attr "mode" "HI")])
622
623 (define_insn "*cmpqi_ccno_1"
624   [(set (reg FLAGS_REG)
625         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
626                  (match_operand:QI 1 "const0_operand" "n,n")))]
627   "ix86_match_ccmode (insn, CCNOmode)"
628   "@
629    test{b}\t{%0, %0|%0, %0}
630    cmp{b}\t{$0, %0|%0, 0}"
631   [(set_attr "type" "test,icmp")
632    (set_attr "length_immediate" "0,1")
633    (set_attr "mode" "QI")])
634
635 (define_insn "*cmpqi_1"
636   [(set (reg FLAGS_REG)
637         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
638                  (match_operand:QI 1 "general_operand" "qi,mq")))]
639   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
640     && ix86_match_ccmode (insn, CCmode)"
641   "cmp{b}\t{%1, %0|%0, %1}"
642   [(set_attr "type" "icmp")
643    (set_attr "mode" "QI")])
644
645 (define_insn "*cmpqi_minus_1"
646   [(set (reg FLAGS_REG)
647         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
648                            (match_operand:QI 1 "general_operand" "qi,mq"))
649                  (const_int 0)))]
650   "ix86_match_ccmode (insn, CCGOCmode)"
651   "cmp{b}\t{%1, %0|%0, %1}"
652   [(set_attr "type" "icmp")
653    (set_attr "mode" "QI")])
654
655 (define_insn "*cmpqi_ext_1"
656   [(set (reg FLAGS_REG)
657         (compare
658           (match_operand:QI 0 "general_operand" "Qm")
659           (subreg:QI
660             (zero_extract:SI
661               (match_operand 1 "ext_register_operand" "Q")
662               (const_int 8)
663               (const_int 8)) 0)))]
664   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
665   "cmp{b}\t{%h1, %0|%0, %h1}"
666   [(set_attr "type" "icmp")
667    (set_attr "mode" "QI")])
668
669 (define_insn "*cmpqi_ext_1_rex64"
670   [(set (reg FLAGS_REG)
671         (compare
672           (match_operand:QI 0 "register_operand" "Q")
673           (subreg:QI
674             (zero_extract:SI
675               (match_operand 1 "ext_register_operand" "Q")
676               (const_int 8)
677               (const_int 8)) 0)))]
678   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
679   "cmp{b}\t{%h1, %0|%0, %h1}"
680   [(set_attr "type" "icmp")
681    (set_attr "mode" "QI")])
682
683 (define_insn "*cmpqi_ext_2"
684   [(set (reg FLAGS_REG)
685         (compare
686           (subreg:QI
687             (zero_extract:SI
688               (match_operand 0 "ext_register_operand" "Q")
689               (const_int 8)
690               (const_int 8)) 0)
691           (match_operand:QI 1 "const0_operand" "n")))]
692   "ix86_match_ccmode (insn, CCNOmode)"
693   "test{b}\t%h0, %h0"
694   [(set_attr "type" "test")
695    (set_attr "length_immediate" "0")
696    (set_attr "mode" "QI")])
697
698 (define_expand "cmpqi_ext_3"
699   [(set (reg:CC FLAGS_REG)
700         (compare:CC
701           (subreg:QI
702             (zero_extract:SI
703               (match_operand 0 "ext_register_operand" "")
704               (const_int 8)
705               (const_int 8)) 0)
706           (match_operand:QI 1 "general_operand" "")))]
707   ""
708   "")
709
710 (define_insn "cmpqi_ext_3_insn"
711   [(set (reg FLAGS_REG)
712         (compare
713           (subreg:QI
714             (zero_extract:SI
715               (match_operand 0 "ext_register_operand" "Q")
716               (const_int 8)
717               (const_int 8)) 0)
718           (match_operand:QI 1 "general_operand" "Qmn")))]
719   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720   "cmp{b}\t{%1, %h0|%h0, %1}"
721   [(set_attr "type" "icmp")
722    (set_attr "mode" "QI")])
723
724 (define_insn "cmpqi_ext_3_insn_rex64"
725   [(set (reg FLAGS_REG)
726         (compare
727           (subreg:QI
728             (zero_extract:SI
729               (match_operand 0 "ext_register_operand" "Q")
730               (const_int 8)
731               (const_int 8)) 0)
732           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
733   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
734   "cmp{b}\t{%1, %h0|%h0, %1}"
735   [(set_attr "type" "icmp")
736    (set_attr "mode" "QI")])
737
738 (define_insn "*cmpqi_ext_4"
739   [(set (reg FLAGS_REG)
740         (compare
741           (subreg:QI
742             (zero_extract:SI
743               (match_operand 0 "ext_register_operand" "Q")
744               (const_int 8)
745               (const_int 8)) 0)
746           (subreg:QI
747             (zero_extract:SI
748               (match_operand 1 "ext_register_operand" "Q")
749               (const_int 8)
750               (const_int 8)) 0)))]
751   "ix86_match_ccmode (insn, CCmode)"
752   "cmp{b}\t{%h1, %h0|%h0, %h1}"
753   [(set_attr "type" "icmp")
754    (set_attr "mode" "QI")])
755
756 ;; These implement float point compares.
757 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
758 ;; which would allow mix and match FP modes on the compares.  Which is what
759 ;; the old patterns did, but with many more of them.
760
761 (define_expand "cmpxf"
762   [(set (reg:CC FLAGS_REG)
763         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
764                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
765   "TARGET_80387"
766 {
767   ix86_compare_op0 = operands[0];
768   ix86_compare_op1 = operands[1];
769   DONE;
770 })
771
772 (define_expand "cmpdf"
773   [(set (reg:CC FLAGS_REG)
774         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
775                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
776   "TARGET_80387 || TARGET_SSE2"
777 {
778   ix86_compare_op0 = operands[0];
779   ix86_compare_op1 = operands[1];
780   DONE;
781 })
782
783 (define_expand "cmpsf"
784   [(set (reg:CC FLAGS_REG)
785         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
786                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
787   "TARGET_80387 || TARGET_SSE"
788 {
789   ix86_compare_op0 = operands[0];
790   ix86_compare_op1 = operands[1];
791   DONE;
792 })
793
794 ;; FP compares, step 1:
795 ;; Set the FP condition codes.
796 ;;
797 ;; CCFPmode     compare with exceptions
798 ;; CCFPUmode    compare with no exceptions
799
800 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
801 ;; used to manage the reg stack popping would not be preserved.
802
803 (define_insn "*cmpfp_0_sf"
804   [(set (match_operand:HI 0 "register_operand" "=a")
805         (unspec:HI
806           [(compare:CCFP
807              (match_operand:SF 1 "register_operand" "f")
808              (match_operand:SF 2 "const0_operand" "X"))]
809         UNSPEC_FNSTSW))]
810   "TARGET_80387"
811   "* return output_fp_compare (insn, operands, 0, 0);"
812   [(set_attr "type" "multi")
813    (set_attr "mode" "SF")])
814
815 (define_insn "*cmpfp_0_df"
816   [(set (match_operand:HI 0 "register_operand" "=a")
817         (unspec:HI
818           [(compare:CCFP
819              (match_operand:DF 1 "register_operand" "f")
820              (match_operand:DF 2 "const0_operand" "X"))]
821         UNSPEC_FNSTSW))]
822   "TARGET_80387"
823   "* return output_fp_compare (insn, operands, 0, 0);"
824   [(set_attr "type" "multi")
825    (set_attr "mode" "DF")])
826
827 (define_insn "*cmpfp_0_xf"
828   [(set (match_operand:HI 0 "register_operand" "=a")
829         (unspec:HI
830           [(compare:CCFP
831              (match_operand:XF 1 "register_operand" "f")
832              (match_operand:XF 2 "const0_operand" "X"))]
833         UNSPEC_FNSTSW))]
834   "TARGET_80387"
835   "* return output_fp_compare (insn, operands, 0, 0);"
836   [(set_attr "type" "multi")
837    (set_attr "mode" "XF")])
838
839 (define_insn "*cmpfp_sf"
840   [(set (match_operand:HI 0 "register_operand" "=a")
841         (unspec:HI
842           [(compare:CCFP
843              (match_operand:SF 1 "register_operand" "f")
844              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
845           UNSPEC_FNSTSW))]
846   "TARGET_80387"
847   "* return output_fp_compare (insn, operands, 0, 0);"
848   [(set_attr "type" "multi")
849    (set_attr "mode" "SF")])
850
851 (define_insn "*cmpfp_df"
852   [(set (match_operand:HI 0 "register_operand" "=a")
853         (unspec:HI
854           [(compare:CCFP
855              (match_operand:DF 1 "register_operand" "f")
856              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
857           UNSPEC_FNSTSW))]
858   "TARGET_80387"
859   "* return output_fp_compare (insn, operands, 0, 0);"
860   [(set_attr "type" "multi")
861    (set_attr "mode" "DF")])
862
863 (define_insn "*cmpfp_xf"
864   [(set (match_operand:HI 0 "register_operand" "=a")
865         (unspec:HI
866           [(compare:CCFP
867              (match_operand:XF 1 "register_operand" "f")
868              (match_operand:XF 2 "register_operand" "f"))]
869           UNSPEC_FNSTSW))]
870   "TARGET_80387"
871   "* return output_fp_compare (insn, operands, 0, 0);"
872   [(set_attr "type" "multi")
873    (set_attr "mode" "XF")])
874
875 (define_insn "*cmpfp_u"
876   [(set (match_operand:HI 0 "register_operand" "=a")
877         (unspec:HI
878           [(compare:CCFPU
879              (match_operand 1 "register_operand" "f")
880              (match_operand 2 "register_operand" "f"))]
881           UNSPEC_FNSTSW))]
882   "TARGET_80387
883    && FLOAT_MODE_P (GET_MODE (operands[1]))
884    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
885   "* return output_fp_compare (insn, operands, 0, 1);"
886   [(set_attr "type" "multi")
887    (set (attr "mode")
888      (cond [(match_operand:SF 1 "" "")
889               (const_string "SF")
890             (match_operand:DF 1 "" "")
891               (const_string "DF")
892            ]
893            (const_string "XF")))])
894
895 (define_insn "*cmpfp_si"
896   [(set (match_operand:HI 0 "register_operand" "=a")
897         (unspec:HI
898           [(compare:CCFP
899              (match_operand 1 "register_operand" "f")
900              (match_operator 3 "float_operator"
901                [(match_operand:SI 2 "memory_operand" "m")]))]
902           UNSPEC_FNSTSW))]
903   "TARGET_80387 && TARGET_USE_FIOP
904    && FLOAT_MODE_P (GET_MODE (operands[1]))
905    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
906   "* return output_fp_compare (insn, operands, 0, 0);"
907   [(set_attr "type" "multi")
908    (set_attr "fp_int_src" "true")
909    (set_attr "mode" "SI")])
910
911 ;; FP compares, step 2
912 ;; Move the fpsw to ax.
913
914 (define_insn "x86_fnstsw_1"
915   [(set (match_operand:HI 0 "register_operand" "=a")
916         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
917   "TARGET_80387"
918   "fnstsw\t%0"
919   [(set_attr "length" "2")
920    (set_attr "mode" "SI")
921    (set_attr "unit" "i387")])
922
923 ;; FP compares, step 3
924 ;; Get ax into flags, general case.
925
926 (define_insn "x86_sahf_1"
927   [(set (reg:CC FLAGS_REG)
928         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
929   "!TARGET_64BIT"
930   "sahf"
931   [(set_attr "length" "1")
932    (set_attr "athlon_decode" "vector")
933    (set_attr "mode" "SI")])
934
935 ;; Pentium Pro can do steps 1 through 3 in one go.
936
937 (define_insn "*cmpfp_i"
938   [(set (reg:CCFP FLAGS_REG)
939         (compare:CCFP (match_operand 0 "register_operand" "f")
940                       (match_operand 1 "register_operand" "f")))]
941   "TARGET_80387 && TARGET_CMOVE
942    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
943    && FLOAT_MODE_P (GET_MODE (operands[0]))
944    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
945   "* return output_fp_compare (insn, operands, 1, 0);"
946   [(set_attr "type" "fcmp")
947    (set (attr "mode")
948      (cond [(match_operand:SF 1 "" "")
949               (const_string "SF")
950             (match_operand:DF 1 "" "")
951               (const_string "DF")
952            ]
953            (const_string "XF")))
954    (set_attr "athlon_decode" "vector")])
955
956 (define_insn "*cmpfp_i_sse"
957   [(set (reg:CCFP FLAGS_REG)
958         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
959                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
960   "TARGET_80387
961    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
962    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
963   "* return output_fp_compare (insn, operands, 1, 0);"
964   [(set_attr "type" "fcmp,ssecomi")
965    (set (attr "mode")
966      (if_then_else (match_operand:SF 1 "" "")
967         (const_string "SF")
968         (const_string "DF")))
969    (set_attr "athlon_decode" "vector")])
970
971 (define_insn "*cmpfp_i_sse_only"
972   [(set (reg:CCFP FLAGS_REG)
973         (compare:CCFP (match_operand 0 "register_operand" "x")
974                       (match_operand 1 "nonimmediate_operand" "xm")))]
975   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
976    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
977   "* return output_fp_compare (insn, operands, 1, 0);"
978   [(set_attr "type" "ssecomi")
979    (set (attr "mode")
980      (if_then_else (match_operand:SF 1 "" "")
981         (const_string "SF")
982         (const_string "DF")))
983    (set_attr "athlon_decode" "vector")])
984
985 (define_insn "*cmpfp_iu"
986   [(set (reg:CCFPU FLAGS_REG)
987         (compare:CCFPU (match_operand 0 "register_operand" "f")
988                        (match_operand 1 "register_operand" "f")))]
989   "TARGET_80387 && TARGET_CMOVE
990    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
991    && FLOAT_MODE_P (GET_MODE (operands[0]))
992    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
993   "* return output_fp_compare (insn, operands, 1, 1);"
994   [(set_attr "type" "fcmp")
995    (set (attr "mode")
996      (cond [(match_operand:SF 1 "" "")
997               (const_string "SF")
998             (match_operand:DF 1 "" "")
999               (const_string "DF")
1000            ]
1001            (const_string "XF")))
1002    (set_attr "athlon_decode" "vector")])
1003
1004 (define_insn "*cmpfp_iu_sse"
1005   [(set (reg:CCFPU FLAGS_REG)
1006         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1007                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1008   "TARGET_80387
1009    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1010    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1011   "* return output_fp_compare (insn, operands, 1, 1);"
1012   [(set_attr "type" "fcmp,ssecomi")
1013    (set (attr "mode")
1014      (if_then_else (match_operand:SF 1 "" "")
1015         (const_string "SF")
1016         (const_string "DF")))
1017    (set_attr "athlon_decode" "vector")])
1018
1019 (define_insn "*cmpfp_iu_sse_only"
1020   [(set (reg:CCFPU FLAGS_REG)
1021         (compare:CCFPU (match_operand 0 "register_operand" "x")
1022                        (match_operand 1 "nonimmediate_operand" "xm")))]
1023   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1024    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025   "* return output_fp_compare (insn, operands, 1, 1);"
1026   [(set_attr "type" "ssecomi")
1027    (set (attr "mode")
1028      (if_then_else (match_operand:SF 1 "" "")
1029         (const_string "SF")
1030         (const_string "DF")))
1031    (set_attr "athlon_decode" "vector")])
1032 \f
1033 ;; Move instructions.
1034
1035 ;; General case of fullword move.
1036
1037 (define_expand "movsi"
1038   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1039         (match_operand:SI 1 "general_operand" ""))]
1040   ""
1041   "ix86_expand_move (SImode, operands); DONE;")
1042
1043 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1044 ;; general_operand.
1045 ;;
1046 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1047 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1048 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1049 ;; targets without our curiosities, and it is just as easy to represent
1050 ;; this differently.
1051
1052 (define_insn "*pushsi2"
1053   [(set (match_operand:SI 0 "push_operand" "=<")
1054         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1055   "!TARGET_64BIT"
1056   "push{l}\t%1"
1057   [(set_attr "type" "push")
1058    (set_attr "mode" "SI")])
1059
1060 ;; For 64BIT abi we always round up to 8 bytes.
1061 (define_insn "*pushsi2_rex64"
1062   [(set (match_operand:SI 0 "push_operand" "=X")
1063         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1064   "TARGET_64BIT"
1065   "push{q}\t%q1"
1066   [(set_attr "type" "push")
1067    (set_attr "mode" "SI")])
1068
1069 (define_insn "*pushsi2_prologue"
1070   [(set (match_operand:SI 0 "push_operand" "=<")
1071         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1072    (clobber (mem:BLK (scratch)))]
1073   "!TARGET_64BIT"
1074   "push{l}\t%1"
1075   [(set_attr "type" "push")
1076    (set_attr "mode" "SI")])
1077
1078 (define_insn "*popsi1_epilogue"
1079   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1080         (mem:SI (reg:SI SP_REG)))
1081    (set (reg:SI SP_REG)
1082         (plus:SI (reg:SI SP_REG) (const_int 4)))
1083    (clobber (mem:BLK (scratch)))]
1084   "!TARGET_64BIT"
1085   "pop{l}\t%0"
1086   [(set_attr "type" "pop")
1087    (set_attr "mode" "SI")])
1088
1089 (define_insn "popsi1"
1090   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1091         (mem:SI (reg:SI SP_REG)))
1092    (set (reg:SI SP_REG)
1093         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1094   "!TARGET_64BIT"
1095   "pop{l}\t%0"
1096   [(set_attr "type" "pop")
1097    (set_attr "mode" "SI")])
1098
1099 (define_insn "*movsi_xor"
1100   [(set (match_operand:SI 0 "register_operand" "=r")
1101         (match_operand:SI 1 "const0_operand" "i"))
1102    (clobber (reg:CC FLAGS_REG))]
1103   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1104   "xor{l}\t{%0, %0|%0, %0}"
1105   [(set_attr "type" "alu1")
1106    (set_attr "mode" "SI")
1107    (set_attr "length_immediate" "0")])
1108  
1109 (define_insn "*movsi_or"
1110   [(set (match_operand:SI 0 "register_operand" "=r")
1111         (match_operand:SI 1 "immediate_operand" "i"))
1112    (clobber (reg:CC FLAGS_REG))]
1113   "reload_completed
1114    && operands[1] == constm1_rtx
1115    && (TARGET_PENTIUM || optimize_size)"
1116 {
1117   operands[1] = constm1_rtx;
1118   return "or{l}\t{%1, %0|%0, %1}";
1119 }
1120   [(set_attr "type" "alu1")
1121    (set_attr "mode" "SI")
1122    (set_attr "length_immediate" "1")])
1123
1124 (define_insn "*movsi_1"
1125   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1126         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1127   "(TARGET_INTER_UNIT_MOVES || optimize_size)
1128    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1129 {
1130   switch (get_attr_type (insn))
1131     {
1132     case TYPE_SSEMOV:
1133       if (get_attr_mode (insn) == MODE_TI)
1134         return "movdqa\t{%1, %0|%0, %1}";
1135       return "movd\t{%1, %0|%0, %1}";
1136
1137     case TYPE_MMXMOV:
1138       if (get_attr_mode (insn) == MODE_DI)
1139         return "movq\t{%1, %0|%0, %1}";
1140       return "movd\t{%1, %0|%0, %1}";
1141
1142     case TYPE_LEA:
1143       return "lea{l}\t{%1, %0|%0, %1}";
1144
1145     default:
1146       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1147         abort();
1148       return "mov{l}\t{%1, %0|%0, %1}";
1149     }
1150 }
1151   [(set (attr "type")
1152      (cond [(eq_attr "alternative" "2,3,4")
1153               (const_string "mmxmov")
1154             (eq_attr "alternative" "5,6,7")
1155               (const_string "ssemov")
1156             (and (ne (symbol_ref "flag_pic") (const_int 0))
1157                  (match_operand:SI 1 "symbolic_operand" ""))
1158               (const_string "lea")
1159            ]
1160            (const_string "imov")))
1161    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1162
1163 (define_insn "*movsi_1_nointernunit"
1164   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1165         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1166   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1167    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1168 {
1169   switch (get_attr_type (insn))
1170     {
1171     case TYPE_SSEMOV:
1172       if (get_attr_mode (insn) == MODE_TI)
1173         return "movdqa\t{%1, %0|%0, %1}";
1174       return "movd\t{%1, %0|%0, %1}";
1175
1176     case TYPE_MMXMOV:
1177       if (get_attr_mode (insn) == MODE_DI)
1178         return "movq\t{%1, %0|%0, %1}";
1179       return "movd\t{%1, %0|%0, %1}";
1180
1181     case TYPE_LEA:
1182       return "lea{l}\t{%1, %0|%0, %1}";
1183
1184     default:
1185       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1186         abort();
1187       return "mov{l}\t{%1, %0|%0, %1}";
1188     }
1189 }
1190   [(set (attr "type")
1191      (cond [(eq_attr "alternative" "2,3,4")
1192               (const_string "mmxmov")
1193             (eq_attr "alternative" "5,6,7")
1194               (const_string "ssemov")
1195             (and (ne (symbol_ref "flag_pic") (const_int 0))
1196                  (match_operand:SI 1 "symbolic_operand" ""))
1197               (const_string "lea")
1198            ]
1199            (const_string "imov")))
1200    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1201
1202 ;; Stores and loads of ax to arbitrary constant address.
1203 ;; We fake an second form of instruction to force reload to load address
1204 ;; into register when rax is not available
1205 (define_insn "*movabssi_1_rex64"
1206   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1207         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1208   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1209   "@
1210    movabs{l}\t{%1, %P0|%P0, %1}
1211    mov{l}\t{%1, %a0|%a0, %1}"
1212   [(set_attr "type" "imov")
1213    (set_attr "modrm" "0,*")
1214    (set_attr "length_address" "8,0")
1215    (set_attr "length_immediate" "0,*")
1216    (set_attr "memory" "store")
1217    (set_attr "mode" "SI")])
1218
1219 (define_insn "*movabssi_2_rex64"
1220   [(set (match_operand:SI 0 "register_operand" "=a,r")
1221         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1222   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1223   "@
1224    movabs{l}\t{%P1, %0|%0, %P1}
1225    mov{l}\t{%a1, %0|%0, %a1}"
1226   [(set_attr "type" "imov")
1227    (set_attr "modrm" "0,*")
1228    (set_attr "length_address" "8,0")
1229    (set_attr "length_immediate" "0")
1230    (set_attr "memory" "load")
1231    (set_attr "mode" "SI")])
1232
1233 (define_insn "*swapsi"
1234   [(set (match_operand:SI 0 "register_operand" "+r")
1235         (match_operand:SI 1 "register_operand" "+r"))
1236    (set (match_dup 1)
1237         (match_dup 0))]
1238   ""
1239   "xchg{l}\t%1, %0"
1240   [(set_attr "type" "imov")
1241    (set_attr "pent_pair" "np")
1242    (set_attr "athlon_decode" "vector")
1243    (set_attr "mode" "SI")
1244    (set_attr "modrm" "0")])
1245
1246 (define_expand "movhi"
1247   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1248         (match_operand:HI 1 "general_operand" ""))]
1249   ""
1250   "ix86_expand_move (HImode, operands); DONE;")
1251
1252 (define_insn "*pushhi2"
1253   [(set (match_operand:HI 0 "push_operand" "=<,<")
1254         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1255   "!TARGET_64BIT"
1256   "@
1257    push{w}\t{|WORD PTR }%1
1258    push{w}\t%1"
1259   [(set_attr "type" "push")
1260    (set_attr "mode" "HI")])
1261
1262 ;; For 64BIT abi we always round up to 8 bytes.
1263 (define_insn "*pushhi2_rex64"
1264   [(set (match_operand:HI 0 "push_operand" "=X")
1265         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1266   "TARGET_64BIT"
1267   "push{q}\t%q1"
1268   [(set_attr "type" "push")
1269    (set_attr "mode" "QI")])
1270
1271 (define_insn "*movhi_1"
1272   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1273         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1274   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1275 {
1276   switch (get_attr_type (insn))
1277     {
1278     case TYPE_IMOVX:
1279       /* movzwl is faster than movw on p2 due to partial word stalls,
1280          though not as fast as an aligned movl.  */
1281       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1282     default:
1283       if (get_attr_mode (insn) == MODE_SI)
1284         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1285       else
1286         return "mov{w}\t{%1, %0|%0, %1}";
1287     }
1288 }
1289   [(set (attr "type")
1290      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1291               (const_string "imov")
1292             (and (eq_attr "alternative" "0")
1293                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1294                           (const_int 0))
1295                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1296                           (const_int 0))))
1297               (const_string "imov")
1298             (and (eq_attr "alternative" "1,2")
1299                  (match_operand:HI 1 "aligned_operand" ""))
1300               (const_string "imov")
1301             (and (ne (symbol_ref "TARGET_MOVX")
1302                      (const_int 0))
1303                  (eq_attr "alternative" "0,2"))
1304               (const_string "imovx")
1305            ]
1306            (const_string "imov")))
1307     (set (attr "mode")
1308       (cond [(eq_attr "type" "imovx")
1309                (const_string "SI")
1310              (and (eq_attr "alternative" "1,2")
1311                   (match_operand:HI 1 "aligned_operand" ""))
1312                (const_string "SI")
1313              (and (eq_attr "alternative" "0")
1314                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1315                            (const_int 0))
1316                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1317                            (const_int 0))))
1318                (const_string "SI")
1319             ]
1320             (const_string "HI")))])
1321
1322 ;; Stores and loads of ax to arbitrary constant address.
1323 ;; We fake an second form of instruction to force reload to load address
1324 ;; into register when rax is not available
1325 (define_insn "*movabshi_1_rex64"
1326   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1327         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1328   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1329   "@
1330    movabs{w}\t{%1, %P0|%P0, %1}
1331    mov{w}\t{%1, %a0|%a0, %1}"
1332   [(set_attr "type" "imov")
1333    (set_attr "modrm" "0,*")
1334    (set_attr "length_address" "8,0")
1335    (set_attr "length_immediate" "0,*")
1336    (set_attr "memory" "store")
1337    (set_attr "mode" "HI")])
1338
1339 (define_insn "*movabshi_2_rex64"
1340   [(set (match_operand:HI 0 "register_operand" "=a,r")
1341         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1342   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1343   "@
1344    movabs{w}\t{%P1, %0|%0, %P1}
1345    mov{w}\t{%a1, %0|%0, %a1}"
1346   [(set_attr "type" "imov")
1347    (set_attr "modrm" "0,*")
1348    (set_attr "length_address" "8,0")
1349    (set_attr "length_immediate" "0")
1350    (set_attr "memory" "load")
1351    (set_attr "mode" "HI")])
1352
1353 (define_insn "*swaphi_1"
1354   [(set (match_operand:HI 0 "register_operand" "+r")
1355         (match_operand:HI 1 "register_operand" "+r"))
1356    (set (match_dup 1)
1357         (match_dup 0))]
1358   "TARGET_PARTIAL_REG_STALL"
1359   "xchg{w}\t%1, %0"
1360   [(set_attr "type" "imov")
1361    (set_attr "pent_pair" "np")
1362    (set_attr "mode" "HI")
1363    (set_attr "modrm" "0")])
1364
1365 (define_insn "*swaphi_2"
1366   [(set (match_operand:HI 0 "register_operand" "+r")
1367         (match_operand:HI 1 "register_operand" "+r"))
1368    (set (match_dup 1)
1369         (match_dup 0))]
1370   "! TARGET_PARTIAL_REG_STALL"
1371   "xchg{l}\t%k1, %k0"
1372   [(set_attr "type" "imov")
1373    (set_attr "pent_pair" "np")
1374    (set_attr "mode" "SI")
1375    (set_attr "modrm" "0")])
1376
1377 (define_expand "movstricthi"
1378   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1379         (match_operand:HI 1 "general_operand" ""))]
1380   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1381 {
1382   /* Don't generate memory->memory moves, go through a register */
1383   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1384     operands[1] = force_reg (HImode, operands[1]);
1385 })
1386
1387 (define_insn "*movstricthi_1"
1388   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1389         (match_operand:HI 1 "general_operand" "rn,m"))]
1390   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1391    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1392   "mov{w}\t{%1, %0|%0, %1}"
1393   [(set_attr "type" "imov")
1394    (set_attr "mode" "HI")])
1395
1396 (define_insn "*movstricthi_xor"
1397   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1398         (match_operand:HI 1 "const0_operand" "i"))
1399    (clobber (reg:CC FLAGS_REG))]
1400   "reload_completed
1401    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1402   "xor{w}\t{%0, %0|%0, %0}"
1403   [(set_attr "type" "alu1")
1404    (set_attr "mode" "HI")
1405    (set_attr "length_immediate" "0")])
1406
1407 (define_expand "movqi"
1408   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1409         (match_operand:QI 1 "general_operand" ""))]
1410   ""
1411   "ix86_expand_move (QImode, operands); DONE;")
1412
1413 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1414 ;; "push a byte".  But actually we use pushw, which has the effect
1415 ;; of rounding the amount pushed up to a halfword.
1416
1417 (define_insn "*pushqi2"
1418   [(set (match_operand:QI 0 "push_operand" "=X,X")
1419         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1420   "!TARGET_64BIT"
1421   "@
1422    push{w}\t{|word ptr }%1
1423    push{w}\t%w1"
1424   [(set_attr "type" "push")
1425    (set_attr "mode" "HI")])
1426
1427 ;; For 64BIT abi we always round up to 8 bytes.
1428 (define_insn "*pushqi2_rex64"
1429   [(set (match_operand:QI 0 "push_operand" "=X")
1430         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1431   "TARGET_64BIT"
1432   "push{q}\t%q1"
1433   [(set_attr "type" "push")
1434    (set_attr "mode" "QI")])
1435
1436 ;; Situation is quite tricky about when to choose full sized (SImode) move
1437 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1438 ;; partial register dependency machines (such as AMD Athlon), where QImode
1439 ;; moves issue extra dependency and for partial register stalls machines
1440 ;; that don't use QImode patterns (and QImode move cause stall on the next
1441 ;; instruction).
1442 ;;
1443 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1444 ;; register stall machines with, where we use QImode instructions, since
1445 ;; partial register stall can be caused there.  Then we use movzx.
1446 (define_insn "*movqi_1"
1447   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1448         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1449   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1450 {
1451   switch (get_attr_type (insn))
1452     {
1453     case TYPE_IMOVX:
1454       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1455         abort ();
1456       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1457     default:
1458       if (get_attr_mode (insn) == MODE_SI)
1459         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1460       else
1461         return "mov{b}\t{%1, %0|%0, %1}";
1462     }
1463 }
1464   [(set (attr "type")
1465      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1466               (const_string "imov")
1467             (and (eq_attr "alternative" "3")
1468                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1469                           (const_int 0))
1470                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1471                           (const_int 0))))
1472               (const_string "imov")
1473             (eq_attr "alternative" "3,5")
1474               (const_string "imovx")
1475             (and (ne (symbol_ref "TARGET_MOVX")
1476                      (const_int 0))
1477                  (eq_attr "alternative" "2"))
1478               (const_string "imovx")
1479            ]
1480            (const_string "imov")))
1481    (set (attr "mode")
1482       (cond [(eq_attr "alternative" "3,4,5")
1483                (const_string "SI")
1484              (eq_attr "alternative" "6")
1485                (const_string "QI")
1486              (eq_attr "type" "imovx")
1487                (const_string "SI")
1488              (and (eq_attr "type" "imov")
1489                   (and (eq_attr "alternative" "0,1,2")
1490                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1491                            (const_int 0))))
1492                (const_string "SI")
1493              ;; Avoid partial register stalls when not using QImode arithmetic
1494              (and (eq_attr "type" "imov")
1495                   (and (eq_attr "alternative" "0,1,2")
1496                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1497                                 (const_int 0))
1498                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1499                                 (const_int 0)))))
1500                (const_string "SI")
1501            ]
1502            (const_string "QI")))])
1503
1504 (define_expand "reload_outqi"
1505   [(parallel [(match_operand:QI 0 "" "=m")
1506               (match_operand:QI 1 "register_operand" "r")
1507               (match_operand:QI 2 "register_operand" "=&q")])]
1508   ""
1509 {
1510   rtx op0, op1, op2;
1511   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1512
1513   if (reg_overlap_mentioned_p (op2, op0))
1514     abort ();
1515   if (! q_regs_operand (op1, QImode))
1516     {
1517       emit_insn (gen_movqi (op2, op1));
1518       op1 = op2;
1519     }
1520   emit_insn (gen_movqi (op0, op1));
1521   DONE;
1522 })
1523
1524 (define_insn "*swapqi"
1525   [(set (match_operand:QI 0 "register_operand" "+r")
1526         (match_operand:QI 1 "register_operand" "+r"))
1527    (set (match_dup 1)
1528         (match_dup 0))]
1529   ""
1530   "xchg{b}\t%1, %0"
1531   [(set_attr "type" "imov")
1532    (set_attr "pent_pair" "np")
1533    (set_attr "mode" "QI")
1534    (set_attr "modrm" "0")])
1535
1536 (define_expand "movstrictqi"
1537   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1538         (match_operand:QI 1 "general_operand" ""))]
1539   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1540 {
1541   /* Don't generate memory->memory moves, go through a register.  */
1542   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1543     operands[1] = force_reg (QImode, operands[1]);
1544 })
1545
1546 (define_insn "*movstrictqi_1"
1547   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1548         (match_operand:QI 1 "general_operand" "*qn,m"))]
1549   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1550    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1551   "mov{b}\t{%1, %0|%0, %1}"
1552   [(set_attr "type" "imov")
1553    (set_attr "mode" "QI")])
1554
1555 (define_insn "*movstrictqi_xor"
1556   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1557         (match_operand:QI 1 "const0_operand" "i"))
1558    (clobber (reg:CC FLAGS_REG))]
1559   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1560   "xor{b}\t{%0, %0|%0, %0}"
1561   [(set_attr "type" "alu1")
1562    (set_attr "mode" "QI")
1563    (set_attr "length_immediate" "0")])
1564
1565 (define_insn "*movsi_extv_1"
1566   [(set (match_operand:SI 0 "register_operand" "=R")
1567         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1568                          (const_int 8)
1569                          (const_int 8)))]
1570   ""
1571   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1572   [(set_attr "type" "imovx")
1573    (set_attr "mode" "SI")])
1574
1575 (define_insn "*movhi_extv_1"
1576   [(set (match_operand:HI 0 "register_operand" "=R")
1577         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1578                          (const_int 8)
1579                          (const_int 8)))]
1580   ""
1581   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1582   [(set_attr "type" "imovx")
1583    (set_attr "mode" "SI")])
1584
1585 (define_insn "*movqi_extv_1"
1586   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1587         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1588                          (const_int 8)
1589                          (const_int 8)))]
1590   "!TARGET_64BIT"
1591 {
1592   switch (get_attr_type (insn))
1593     {
1594     case TYPE_IMOVX:
1595       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1596     default:
1597       return "mov{b}\t{%h1, %0|%0, %h1}";
1598     }
1599 }
1600   [(set (attr "type")
1601      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1602                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1603                              (ne (symbol_ref "TARGET_MOVX")
1604                                  (const_int 0))))
1605         (const_string "imovx")
1606         (const_string "imov")))
1607    (set (attr "mode")
1608      (if_then_else (eq_attr "type" "imovx")
1609         (const_string "SI")
1610         (const_string "QI")))])
1611
1612 (define_insn "*movqi_extv_1_rex64"
1613   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1614         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1615                          (const_int 8)
1616                          (const_int 8)))]
1617   "TARGET_64BIT"
1618 {
1619   switch (get_attr_type (insn))
1620     {
1621     case TYPE_IMOVX:
1622       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1623     default:
1624       return "mov{b}\t{%h1, %0|%0, %h1}";
1625     }
1626 }
1627   [(set (attr "type")
1628      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1629                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1630                              (ne (symbol_ref "TARGET_MOVX")
1631                                  (const_int 0))))
1632         (const_string "imovx")
1633         (const_string "imov")))
1634    (set (attr "mode")
1635      (if_then_else (eq_attr "type" "imovx")
1636         (const_string "SI")
1637         (const_string "QI")))])
1638
1639 ;; Stores and loads of ax to arbitrary constant address.
1640 ;; We fake an second form of instruction to force reload to load address
1641 ;; into register when rax is not available
1642 (define_insn "*movabsqi_1_rex64"
1643   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1644         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1645   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1646   "@
1647    movabs{b}\t{%1, %P0|%P0, %1}
1648    mov{b}\t{%1, %a0|%a0, %1}"
1649   [(set_attr "type" "imov")
1650    (set_attr "modrm" "0,*")
1651    (set_attr "length_address" "8,0")
1652    (set_attr "length_immediate" "0,*")
1653    (set_attr "memory" "store")
1654    (set_attr "mode" "QI")])
1655
1656 (define_insn "*movabsqi_2_rex64"
1657   [(set (match_operand:QI 0 "register_operand" "=a,r")
1658         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1659   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1660   "@
1661    movabs{b}\t{%P1, %0|%0, %P1}
1662    mov{b}\t{%a1, %0|%0, %a1}"
1663   [(set_attr "type" "imov")
1664    (set_attr "modrm" "0,*")
1665    (set_attr "length_address" "8,0")
1666    (set_attr "length_immediate" "0")
1667    (set_attr "memory" "load")
1668    (set_attr "mode" "QI")])
1669
1670 (define_insn "*movsi_extzv_1"
1671   [(set (match_operand:SI 0 "register_operand" "=R")
1672         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1673                          (const_int 8)
1674                          (const_int 8)))]
1675   ""
1676   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1677   [(set_attr "type" "imovx")
1678    (set_attr "mode" "SI")])
1679
1680 (define_insn "*movqi_extzv_2"
1681   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1682         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1683                                     (const_int 8)
1684                                     (const_int 8)) 0))]
1685   "!TARGET_64BIT"
1686 {
1687   switch (get_attr_type (insn))
1688     {
1689     case TYPE_IMOVX:
1690       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1691     default:
1692       return "mov{b}\t{%h1, %0|%0, %h1}";
1693     }
1694 }
1695   [(set (attr "type")
1696      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1697                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1698                              (ne (symbol_ref "TARGET_MOVX")
1699                                  (const_int 0))))
1700         (const_string "imovx")
1701         (const_string "imov")))
1702    (set (attr "mode")
1703      (if_then_else (eq_attr "type" "imovx")
1704         (const_string "SI")
1705         (const_string "QI")))])
1706
1707 (define_insn "*movqi_extzv_2_rex64"
1708   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1709         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1710                                     (const_int 8)
1711                                     (const_int 8)) 0))]
1712   "TARGET_64BIT"
1713 {
1714   switch (get_attr_type (insn))
1715     {
1716     case TYPE_IMOVX:
1717       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1718     default:
1719       return "mov{b}\t{%h1, %0|%0, %h1}";
1720     }
1721 }
1722   [(set (attr "type")
1723      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1724                         (ne (symbol_ref "TARGET_MOVX")
1725                             (const_int 0)))
1726         (const_string "imovx")
1727         (const_string "imov")))
1728    (set (attr "mode")
1729      (if_then_else (eq_attr "type" "imovx")
1730         (const_string "SI")
1731         (const_string "QI")))])
1732
1733 (define_insn "movsi_insv_1"
1734   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1735                          (const_int 8)
1736                          (const_int 8))
1737         (match_operand:SI 1 "general_operand" "Qmn"))]
1738   "!TARGET_64BIT"
1739   "mov{b}\t{%b1, %h0|%h0, %b1}"
1740   [(set_attr "type" "imov")
1741    (set_attr "mode" "QI")])
1742
1743 (define_insn "movdi_insv_1_rex64"
1744   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1745                          (const_int 8)
1746                          (const_int 8))
1747         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1748   "TARGET_64BIT"
1749   "mov{b}\t{%b1, %h0|%h0, %b1}"
1750   [(set_attr "type" "imov")
1751    (set_attr "mode" "QI")])
1752
1753 (define_insn "*movqi_insv_2"
1754   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1755                          (const_int 8)
1756                          (const_int 8))
1757         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1758                      (const_int 8)))]
1759   ""
1760   "mov{b}\t{%h1, %h0|%h0, %h1}"
1761   [(set_attr "type" "imov")
1762    (set_attr "mode" "QI")])
1763
1764 (define_expand "movdi"
1765   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1766         (match_operand:DI 1 "general_operand" ""))]
1767   ""
1768   "ix86_expand_move (DImode, operands); DONE;")
1769
1770 (define_insn "*pushdi"
1771   [(set (match_operand:DI 0 "push_operand" "=<")
1772         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1773   "!TARGET_64BIT"
1774   "#")
1775
1776 (define_insn "pushdi2_rex64"
1777   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1778         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1779   "TARGET_64BIT"
1780   "@
1781    push{q}\t%1
1782    #"
1783   [(set_attr "type" "push,multi")
1784    (set_attr "mode" "DI")])
1785
1786 ;; Convert impossible pushes of immediate to existing instructions.
1787 ;; First try to get scratch register and go through it.  In case this
1788 ;; fails, push sign extended lower part first and then overwrite
1789 ;; upper part by 32bit move.
1790 (define_peephole2
1791   [(match_scratch:DI 2 "r")
1792    (set (match_operand:DI 0 "push_operand" "")
1793         (match_operand:DI 1 "immediate_operand" ""))]
1794   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1795    && !x86_64_immediate_operand (operands[1], DImode)"
1796   [(set (match_dup 2) (match_dup 1))
1797    (set (match_dup 0) (match_dup 2))]
1798   "")
1799
1800 ;; We need to define this as both peepholer and splitter for case
1801 ;; peephole2 pass is not run.
1802 ;; "&& 1" is needed to keep it from matching the previous pattern.
1803 (define_peephole2
1804   [(set (match_operand:DI 0 "push_operand" "")
1805         (match_operand:DI 1 "immediate_operand" ""))]
1806   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1807    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1808   [(set (match_dup 0) (match_dup 1))
1809    (set (match_dup 2) (match_dup 3))]
1810   "split_di (operands + 1, 1, operands + 2, operands + 3);
1811    operands[1] = gen_lowpart (DImode, operands[2]);
1812    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1813                                                     GEN_INT (4)));
1814   ")
1815
1816 (define_split
1817   [(set (match_operand:DI 0 "push_operand" "")
1818         (match_operand:DI 1 "immediate_operand" ""))]
1819   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1820    && !symbolic_operand (operands[1], DImode)
1821    && !x86_64_immediate_operand (operands[1], DImode)"
1822   [(set (match_dup 0) (match_dup 1))
1823    (set (match_dup 2) (match_dup 3))]
1824   "split_di (operands + 1, 1, operands + 2, operands + 3);
1825    operands[1] = gen_lowpart (DImode, operands[2]);
1826    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1827                                                     GEN_INT (4)));
1828   ")
1829
1830 (define_insn "*pushdi2_prologue_rex64"
1831   [(set (match_operand:DI 0 "push_operand" "=<")
1832         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1833    (clobber (mem:BLK (scratch)))]
1834   "TARGET_64BIT"
1835   "push{q}\t%1"
1836   [(set_attr "type" "push")
1837    (set_attr "mode" "DI")])
1838
1839 (define_insn "*popdi1_epilogue_rex64"
1840   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1841         (mem:DI (reg:DI SP_REG)))
1842    (set (reg:DI SP_REG)
1843         (plus:DI (reg:DI SP_REG) (const_int 8)))
1844    (clobber (mem:BLK (scratch)))]
1845   "TARGET_64BIT"
1846   "pop{q}\t%0"
1847   [(set_attr "type" "pop")
1848    (set_attr "mode" "DI")])
1849
1850 (define_insn "popdi1"
1851   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1852         (mem:DI (reg:DI SP_REG)))
1853    (set (reg:DI SP_REG)
1854         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1855   "TARGET_64BIT"
1856   "pop{q}\t%0"
1857   [(set_attr "type" "pop")
1858    (set_attr "mode" "DI")])
1859
1860 (define_insn "*movdi_xor_rex64"
1861   [(set (match_operand:DI 0 "register_operand" "=r")
1862         (match_operand:DI 1 "const0_operand" "i"))
1863    (clobber (reg:CC FLAGS_REG))]
1864   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1865    && reload_completed"
1866   "xor{l}\t{%k0, %k0|%k0, %k0}"
1867   [(set_attr "type" "alu1")
1868    (set_attr "mode" "SI")
1869    (set_attr "length_immediate" "0")])
1870
1871 (define_insn "*movdi_or_rex64"
1872   [(set (match_operand:DI 0 "register_operand" "=r")
1873         (match_operand:DI 1 "const_int_operand" "i"))
1874    (clobber (reg:CC FLAGS_REG))]
1875   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1876    && reload_completed
1877    && operands[1] == constm1_rtx"
1878 {
1879   operands[1] = constm1_rtx;
1880   return "or{q}\t{%1, %0|%0, %1}";
1881 }
1882   [(set_attr "type" "alu1")
1883    (set_attr "mode" "DI")
1884    (set_attr "length_immediate" "1")])
1885
1886 (define_insn "*movdi_2"
1887   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1888         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1889   "!TARGET_64BIT
1890    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1891   "@
1892    #
1893    #
1894    movq\t{%1, %0|%0, %1}
1895    movq\t{%1, %0|%0, %1}
1896    movq\t{%1, %0|%0, %1}
1897    movdqa\t{%1, %0|%0, %1}
1898    movq\t{%1, %0|%0, %1}"
1899   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1900    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1901
1902 (define_split
1903   [(set (match_operand:DI 0 "push_operand" "")
1904         (match_operand:DI 1 "general_operand" ""))]
1905   "!TARGET_64BIT && reload_completed
1906    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1907   [(const_int 0)]
1908   "ix86_split_long_move (operands); DONE;")
1909
1910 ;; %%% This multiword shite has got to go.
1911 (define_split
1912   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1913         (match_operand:DI 1 "general_operand" ""))]
1914   "!TARGET_64BIT && reload_completed
1915    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1916    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1917   [(const_int 0)]
1918   "ix86_split_long_move (operands); DONE;")
1919
1920 (define_insn "*movdi_1_rex64"
1921   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y,!*Y,!*y")
1922         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm,*y,*Y"))]
1923   "TARGET_64BIT
1924    && (TARGET_INTER_UNIT_MOVES || optimize_size)
1925    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1926 {
1927   switch (get_attr_type (insn))
1928     {
1929     case TYPE_SSECVT:
1930       if (which_alternative == 11)
1931         return "movq2dq\t{%1, %0|%0, %1}";
1932       else
1933         return "movdq2q\t{%1, %0|%0, %1}";
1934     case TYPE_SSEMOV:
1935       if (get_attr_mode (insn) == MODE_TI)
1936           return "movdqa\t{%1, %0|%0, %1}";
1937       /* FALLTHRU */
1938     case TYPE_MMXMOV:
1939       /* Moves from and into integer register is done using movd opcode with
1940          REX prefix.  */
1941       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1942           return "movd\t{%1, %0|%0, %1}";
1943       return "movq\t{%1, %0|%0, %1}";
1944     case TYPE_MULTI:
1945       return "#";
1946     case TYPE_LEA:
1947       return "lea{q}\t{%a1, %0|%0, %a1}";
1948     default:
1949       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1950         abort ();
1951       if (get_attr_mode (insn) == MODE_SI)
1952         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1953       else if (which_alternative == 2)
1954         return "movabs{q}\t{%1, %0|%0, %1}";
1955       else
1956         return "mov{q}\t{%1, %0|%0, %1}";
1957     }
1958 }
1959   [(set (attr "type")
1960      (cond [(eq_attr "alternative" "5,6,7")
1961               (const_string "mmxmov")
1962             (eq_attr "alternative" "8,9,10")
1963               (const_string "ssemov")
1964             (eq_attr "alternative" "11,12")
1965               (const_string "ssecvt")
1966             (eq_attr "alternative" "4")
1967               (const_string "multi")
1968             (and (ne (symbol_ref "flag_pic") (const_int 0))
1969                  (match_operand:DI 1 "symbolic_operand" ""))
1970               (const_string "lea")
1971            ]
1972            (const_string "imov")))
1973    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
1974    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
1975    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
1976
1977 (define_insn "*movdi_1_rex64_nointerunit"
1978   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
1979         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
1980   "TARGET_64BIT
1981    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
1982    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1983 {
1984   switch (get_attr_type (insn))
1985     {
1986     case TYPE_SSEMOV:
1987       if (get_attr_mode (insn) == MODE_TI)
1988           return "movdqa\t{%1, %0|%0, %1}";
1989       /* FALLTHRU */
1990     case TYPE_MMXMOV:
1991       return "movq\t{%1, %0|%0, %1}";
1992     case TYPE_MULTI:
1993       return "#";
1994     case TYPE_LEA:
1995       return "lea{q}\t{%a1, %0|%0, %a1}";
1996     default:
1997       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1998         abort ();
1999       if (get_attr_mode (insn) == MODE_SI)
2000         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2001       else if (which_alternative == 2)
2002         return "movabs{q}\t{%1, %0|%0, %1}";
2003       else
2004         return "mov{q}\t{%1, %0|%0, %1}";
2005     }
2006 }
2007   [(set (attr "type")
2008      (cond [(eq_attr "alternative" "5,6,7")
2009               (const_string "mmxmov")
2010             (eq_attr "alternative" "8,9,10")
2011               (const_string "ssemov")
2012             (eq_attr "alternative" "4")
2013               (const_string "multi")
2014             (and (ne (symbol_ref "flag_pic") (const_int 0))
2015                  (match_operand:DI 1 "symbolic_operand" ""))
2016               (const_string "lea")
2017            ]
2018            (const_string "imov")))
2019    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2020    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2021    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2022
2023 ;; Stores and loads of ax to arbitrary constant address.
2024 ;; We fake an second form of instruction to force reload to load address
2025 ;; into register when rax is not available
2026 (define_insn "*movabsdi_1_rex64"
2027   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2028         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2029   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2030   "@
2031    movabs{q}\t{%1, %P0|%P0, %1}
2032    mov{q}\t{%1, %a0|%a0, %1}"
2033   [(set_attr "type" "imov")
2034    (set_attr "modrm" "0,*")
2035    (set_attr "length_address" "8,0")
2036    (set_attr "length_immediate" "0,*")
2037    (set_attr "memory" "store")
2038    (set_attr "mode" "DI")])
2039
2040 (define_insn "*movabsdi_2_rex64"
2041   [(set (match_operand:DI 0 "register_operand" "=a,r")
2042         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2043   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2044   "@
2045    movabs{q}\t{%P1, %0|%0, %P1}
2046    mov{q}\t{%a1, %0|%0, %a1}"
2047   [(set_attr "type" "imov")
2048    (set_attr "modrm" "0,*")
2049    (set_attr "length_address" "8,0")
2050    (set_attr "length_immediate" "0")
2051    (set_attr "memory" "load")
2052    (set_attr "mode" "DI")])
2053
2054 ;; Convert impossible stores of immediate to existing instructions.
2055 ;; First try to get scratch register and go through it.  In case this
2056 ;; fails, move by 32bit parts.
2057 (define_peephole2
2058   [(match_scratch:DI 2 "r")
2059    (set (match_operand:DI 0 "memory_operand" "")
2060         (match_operand:DI 1 "immediate_operand" ""))]
2061   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2062    && !x86_64_immediate_operand (operands[1], DImode)"
2063   [(set (match_dup 2) (match_dup 1))
2064    (set (match_dup 0) (match_dup 2))]
2065   "")
2066
2067 ;; We need to define this as both peepholer and splitter for case
2068 ;; peephole2 pass is not run.
2069 ;; "&& 1" is needed to keep it from matching the previous pattern.
2070 (define_peephole2
2071   [(set (match_operand:DI 0 "memory_operand" "")
2072         (match_operand:DI 1 "immediate_operand" ""))]
2073   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2074    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2075   [(set (match_dup 2) (match_dup 3))
2076    (set (match_dup 4) (match_dup 5))]
2077   "split_di (operands, 2, operands + 2, operands + 4);")
2078
2079 (define_split
2080   [(set (match_operand:DI 0 "memory_operand" "")
2081         (match_operand:DI 1 "immediate_operand" ""))]
2082   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2083    && !symbolic_operand (operands[1], DImode)
2084    && !x86_64_immediate_operand (operands[1], DImode)"
2085   [(set (match_dup 2) (match_dup 3))
2086    (set (match_dup 4) (match_dup 5))]
2087   "split_di (operands, 2, operands + 2, operands + 4);")
2088
2089 (define_insn "*swapdi_rex64"
2090   [(set (match_operand:DI 0 "register_operand" "+r")
2091         (match_operand:DI 1 "register_operand" "+r"))
2092    (set (match_dup 1)
2093         (match_dup 0))]
2094   "TARGET_64BIT"
2095   "xchg{q}\t%1, %0"
2096   [(set_attr "type" "imov")
2097    (set_attr "pent_pair" "np")
2098    (set_attr "athlon_decode" "vector")
2099    (set_attr "mode" "DI")
2100    (set_attr "modrm" "0")])
2101
2102   
2103 (define_expand "movsf"
2104   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2105         (match_operand:SF 1 "general_operand" ""))]
2106   ""
2107   "ix86_expand_move (SFmode, operands); DONE;")
2108
2109 (define_insn "*pushsf"
2110   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2111         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2112   "!TARGET_64BIT"
2113 {
2114   switch (which_alternative)
2115     {
2116     case 1:
2117       return "push{l}\t%1";
2118
2119     default:
2120       /* This insn should be already split before reg-stack.  */
2121       abort ();
2122     }
2123 }
2124   [(set_attr "type" "multi,push,multi")
2125    (set_attr "mode" "SF,SI,SF")])
2126
2127 (define_insn "*pushsf_rex64"
2128   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2129         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2130   "TARGET_64BIT"
2131 {
2132   switch (which_alternative)
2133     {
2134     case 1:
2135       return "push{q}\t%q1";
2136
2137     default:
2138       /* This insn should be already split before reg-stack.  */
2139       abort ();
2140     }
2141 }
2142   [(set_attr "type" "multi,push,multi")
2143    (set_attr "mode" "SF,DI,SF")])
2144
2145 (define_split
2146   [(set (match_operand:SF 0 "push_operand" "")
2147         (match_operand:SF 1 "memory_operand" ""))]
2148   "reload_completed
2149    && GET_CODE (operands[1]) == MEM
2150    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2151    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2152   [(set (match_dup 0)
2153         (match_dup 1))]
2154   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2155
2156
2157 ;; %%% Kill this when call knows how to work this out.
2158 (define_split
2159   [(set (match_operand:SF 0 "push_operand" "")
2160         (match_operand:SF 1 "any_fp_register_operand" ""))]
2161   "!TARGET_64BIT"
2162   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2163    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2164
2165 (define_split
2166   [(set (match_operand:SF 0 "push_operand" "")
2167         (match_operand:SF 1 "any_fp_register_operand" ""))]
2168   "TARGET_64BIT"
2169   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2170    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2171
2172 (define_insn "*movsf_1"
2173   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
2174         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2175   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2176    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2177    && (reload_in_progress || reload_completed
2178        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2179        || GET_CODE (operands[1]) != CONST_DOUBLE
2180        || memory_operand (operands[0], SFmode))" 
2181 {
2182   switch (which_alternative)
2183     {
2184     case 0:
2185       return output_387_reg_move (insn, operands);
2186
2187     case 1:
2188       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2189         return "fstp%z0\t%y0";
2190       else
2191         return "fst%z0\t%y0";
2192
2193     case 2:
2194       return standard_80387_constant_opcode (operands[1]);
2195
2196     case 3:
2197     case 4:
2198       return "mov{l}\t{%1, %0|%0, %1}";
2199     case 5:
2200       if (get_attr_mode (insn) == MODE_TI)
2201         return "pxor\t%0, %0";
2202       else
2203         return "xorps\t%0, %0";
2204     case 6:
2205       if (get_attr_mode (insn) == MODE_V4SF)
2206         return "movaps\t{%1, %0|%0, %1}";
2207       else
2208         return "movss\t{%1, %0|%0, %1}";
2209     case 7:
2210     case 8:
2211       return "movss\t{%1, %0|%0, %1}";
2212
2213     case 9:
2214     case 10:
2215       return "movd\t{%1, %0|%0, %1}";
2216
2217     case 11:
2218       return "movq\t{%1, %0|%0, %1}";
2219
2220     default:
2221       abort();
2222     }
2223 }
2224   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2225    (set (attr "mode")
2226         (cond [(eq_attr "alternative" "3,4,9,10")
2227                  (const_string "SI")
2228                (eq_attr "alternative" "5")
2229                  (if_then_else
2230                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2231                                  (const_int 0))
2232                              (ne (symbol_ref "TARGET_SSE2")
2233                                  (const_int 0)))
2234                         (eq (symbol_ref "optimize_size")
2235                             (const_int 0)))
2236                    (const_string "TI")
2237                    (const_string "V4SF"))
2238                /* For architectures resolving dependencies on
2239                   whole SSE registers use APS move to break dependency
2240                   chains, otherwise use short move to avoid extra work. 
2241
2242                   Do the same for architectures resolving dependencies on
2243                   the parts.  While in DF mode it is better to always handle
2244                   just register parts, the SF mode is different due to lack
2245                   of instructions to load just part of the register.  It is
2246                   better to maintain the whole registers in single format
2247                   to avoid problems on using packed logical operations.  */
2248                (eq_attr "alternative" "6")
2249                  (if_then_else
2250                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2251                             (const_int 0))
2252                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2253                             (const_int 0)))
2254                    (const_string "V4SF")
2255                    (const_string "SF"))
2256                (eq_attr "alternative" "11")
2257                  (const_string "DI")]
2258                (const_string "SF")))])
2259
2260 (define_insn "*movsf_1_nointerunit"
2261   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!m,!*y")
2262         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2263   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2264    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2265    && (reload_in_progress || reload_completed
2266        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2267        || GET_CODE (operands[1]) != CONST_DOUBLE
2268        || memory_operand (operands[0], SFmode))" 
2269 {
2270   switch (which_alternative)
2271     {
2272     case 0:
2273       return output_387_reg_move (insn, operands);
2274
2275     case 1:
2276       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2277         return "fstp%z0\t%y0";
2278       else
2279         return "fst%z0\t%y0";
2280
2281     case 2:
2282       return standard_80387_constant_opcode (operands[1]);
2283
2284     case 3:
2285     case 4:
2286       return "mov{l}\t{%1, %0|%0, %1}";
2287     case 5:
2288       if (get_attr_mode (insn) == MODE_TI)
2289         return "pxor\t%0, %0";
2290       else
2291         return "xorps\t%0, %0";
2292     case 6:
2293       if (get_attr_mode (insn) == MODE_V4SF)
2294         return "movaps\t{%1, %0|%0, %1}";
2295       else
2296         return "movss\t{%1, %0|%0, %1}";
2297     case 7:
2298     case 8:
2299       return "movss\t{%1, %0|%0, %1}";
2300
2301     case 9:
2302     case 10:
2303       return "movd\t{%1, %0|%0, %1}";
2304
2305     case 11:
2306       return "movq\t{%1, %0|%0, %1}";
2307
2308     default:
2309       abort();
2310     }
2311 }
2312   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2313    (set (attr "mode")
2314         (cond [(eq_attr "alternative" "3,4,9,10")
2315                  (const_string "SI")
2316                (eq_attr "alternative" "5")
2317                  (if_then_else
2318                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2319                                  (const_int 0))
2320                              (ne (symbol_ref "TARGET_SSE2")
2321                                  (const_int 0)))
2322                         (eq (symbol_ref "optimize_size")
2323                             (const_int 0)))
2324                    (const_string "TI")
2325                    (const_string "V4SF"))
2326                /* For architectures resolving dependencies on
2327                   whole SSE registers use APS move to break dependency
2328                   chains, otherwise use short move to avoid extra work. 
2329
2330                   Do the same for architectures resolving dependencies on
2331                   the parts.  While in DF mode it is better to always handle
2332                   just register parts, the SF mode is different due to lack
2333                   of instructions to load just part of the register.  It is
2334                   better to maintain the whole registers in single format
2335                   to avoid problems on using packed logical operations.  */
2336                (eq_attr "alternative" "6")
2337                  (if_then_else
2338                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2339                             (const_int 0))
2340                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2341                             (const_int 0)))
2342                    (const_string "V4SF")
2343                    (const_string "SF"))
2344                (eq_attr "alternative" "11")
2345                  (const_string "DI")]
2346                (const_string "SF")))])
2347
2348 (define_insn "*swapsf"
2349   [(set (match_operand:SF 0 "register_operand" "+f")
2350         (match_operand:SF 1 "register_operand" "+f"))
2351    (set (match_dup 1)
2352         (match_dup 0))]
2353   "reload_completed || !TARGET_SSE"
2354 {
2355   if (STACK_TOP_P (operands[0]))
2356     return "fxch\t%1";
2357   else
2358     return "fxch\t%0";
2359 }
2360   [(set_attr "type" "fxch")
2361    (set_attr "mode" "SF")])
2362
2363 (define_expand "movdf"
2364   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2365         (match_operand:DF 1 "general_operand" ""))]
2366   ""
2367   "ix86_expand_move (DFmode, operands); DONE;")
2368
2369 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2370 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2371 ;; On the average, pushdf using integers can be still shorter.  Allow this
2372 ;; pattern for optimize_size too.
2373
2374 (define_insn "*pushdf_nointeger"
2375   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2376         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2377   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2378 {
2379   /* This insn should be already split before reg-stack.  */
2380   abort ();
2381 }
2382   [(set_attr "type" "multi")
2383    (set_attr "mode" "DF,SI,SI,DF")])
2384
2385 (define_insn "*pushdf_integer"
2386   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2387         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2388   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2389 {
2390   /* This insn should be already split before reg-stack.  */
2391   abort ();
2392 }
2393   [(set_attr "type" "multi")
2394    (set_attr "mode" "DF,SI,DF")])
2395
2396 ;; %%% Kill this when call knows how to work this out.
2397 (define_split
2398   [(set (match_operand:DF 0 "push_operand" "")
2399         (match_operand:DF 1 "any_fp_register_operand" ""))]
2400   "!TARGET_64BIT && reload_completed"
2401   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2402    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2403   "")
2404
2405 (define_split
2406   [(set (match_operand:DF 0 "push_operand" "")
2407         (match_operand:DF 1 "any_fp_register_operand" ""))]
2408   "TARGET_64BIT && reload_completed"
2409   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2410    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2411   "")
2412
2413 (define_split
2414   [(set (match_operand:DF 0 "push_operand" "")
2415         (match_operand:DF 1 "general_operand" ""))]
2416   "reload_completed"
2417   [(const_int 0)]
2418   "ix86_split_long_move (operands); DONE;")
2419
2420 ;; Moving is usually shorter when only FP registers are used. This separate
2421 ;; movdf pattern avoids the use of integer registers for FP operations
2422 ;; when optimizing for size.
2423
2424 (define_insn "*movdf_nointeger"
2425   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2426         (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2427   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2428    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2429    && (reload_in_progress || reload_completed
2430        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2431        || GET_CODE (operands[1]) != CONST_DOUBLE
2432        || memory_operand (operands[0], DFmode))" 
2433 {
2434   switch (which_alternative)
2435     {
2436     case 0:
2437       return output_387_reg_move (insn, operands);
2438
2439     case 1:
2440       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2441         return "fstp%z0\t%y0";
2442       else
2443         return "fst%z0\t%y0";
2444
2445     case 2:
2446       return standard_80387_constant_opcode (operands[1]);
2447
2448     case 3:
2449     case 4:
2450       return "#";
2451     case 5:
2452       switch (get_attr_mode (insn))
2453         {
2454         case MODE_V4SF:
2455           return "xorps\t%0, %0";
2456         case MODE_V2DF:
2457           return "xorpd\t%0, %0";
2458         case MODE_TI:
2459           return "pxor\t%0, %0";
2460         default:
2461           abort ();
2462         }
2463     case 6:
2464       switch (get_attr_mode (insn))
2465         {
2466         case MODE_V4SF:
2467           return "movaps\t{%1, %0|%0, %1}";
2468         case MODE_V2DF:
2469           return "movapd\t{%1, %0|%0, %1}";
2470         case MODE_DF:
2471           return "movsd\t{%1, %0|%0, %1}";
2472         default:
2473           abort ();
2474         }
2475     case 7:
2476       if (get_attr_mode (insn) == MODE_V2DF)
2477         return "movlpd\t{%1, %0|%0, %1}";
2478       else
2479         return "movsd\t{%1, %0|%0, %1}";
2480     case 8:
2481       return "movsd\t{%1, %0|%0, %1}";
2482
2483     default:
2484       abort();
2485     }
2486 }
2487   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2488    (set (attr "mode")
2489         (cond [(eq_attr "alternative" "3,4")
2490                  (const_string "SI")
2491                /* xorps is one byte shorter.  */
2492                (eq_attr "alternative" "5")
2493                  (cond [(ne (symbol_ref "optimize_size")
2494                             (const_int 0))
2495                           (const_string "V4SF")
2496                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2497                             (const_int 0))
2498                           (const_string "TI")]
2499                        (const_string "V2DF"))
2500                /* For architectures resolving dependencies on
2501                   whole SSE registers use APD move to break dependency
2502                   chains, otherwise use short move to avoid extra work.
2503
2504                   movaps encodes one byte shorter.  */
2505                (eq_attr "alternative" "6")
2506                  (cond
2507                   [(ne (symbol_ref "optimize_size")
2508                        (const_int 0))
2509                      (const_string "V4SF")
2510                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2511                        (const_int 0))
2512                      (const_string "V2DF")]
2513                    (const_string "DF"))
2514                /* For architectures resolving dependencies on register
2515                   parts we may avoid extra work to zero out upper part
2516                   of register.  */
2517                (eq_attr "alternative" "7")
2518                  (if_then_else
2519                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2520                        (const_int 0))
2521                    (const_string "V2DF")
2522                    (const_string "DF"))]
2523                (const_string "DF")))])
2524
2525 (define_insn "*movdf_integer"
2526   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2527         (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2528   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2529    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2530    && (reload_in_progress || reload_completed
2531        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2532        || GET_CODE (operands[1]) != CONST_DOUBLE
2533        || memory_operand (operands[0], DFmode))" 
2534 {
2535   switch (which_alternative)
2536     {
2537     case 0:
2538       return output_387_reg_move (insn, operands);
2539
2540     case 1:
2541       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2542         return "fstp%z0\t%y0";
2543       else
2544         return "fst%z0\t%y0";
2545
2546     case 2:
2547       return standard_80387_constant_opcode (operands[1]);
2548
2549     case 3:
2550     case 4:
2551       return "#";
2552
2553     case 5:
2554       switch (get_attr_mode (insn))
2555         {
2556         case MODE_V4SF:
2557           return "xorps\t%0, %0";
2558         case MODE_V2DF:
2559           return "xorpd\t%0, %0";
2560         case MODE_TI:
2561           return "pxor\t%0, %0";
2562         default:
2563           abort ();
2564         }
2565     case 6:
2566       switch (get_attr_mode (insn))
2567         {
2568         case MODE_V4SF:
2569           return "movaps\t{%1, %0|%0, %1}";
2570         case MODE_V2DF:
2571           return "movapd\t{%1, %0|%0, %1}";
2572         case MODE_DF:
2573           return "movsd\t{%1, %0|%0, %1}";
2574         default:
2575           abort ();
2576         }
2577     case 7:
2578       if (get_attr_mode (insn) == MODE_V2DF)
2579         return "movlpd\t{%1, %0|%0, %1}";
2580       else
2581         return "movsd\t{%1, %0|%0, %1}";
2582     case 8:
2583       return "movsd\t{%1, %0|%0, %1}";
2584
2585     default:
2586       abort();
2587     }
2588 }
2589   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2590    (set (attr "mode")
2591         (cond [(eq_attr "alternative" "3,4")
2592                  (const_string "SI")
2593                /* xorps is one byte shorter.  */
2594                (eq_attr "alternative" "5")
2595                  (cond [(ne (symbol_ref "optimize_size")
2596                             (const_int 0))
2597                           (const_string "V4SF")
2598                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2599                             (const_int 0))
2600                           (const_string "TI")]
2601                        (const_string "V2DF"))
2602                /* For architectures resolving dependencies on
2603                   whole SSE registers use APD move to break dependency
2604                   chains, otherwise use short move to avoid extra work.  
2605
2606                   movaps encodes one byte shorter.  */
2607                (eq_attr "alternative" "6")
2608                  (cond
2609                   [(ne (symbol_ref "optimize_size")
2610                        (const_int 0))
2611                      (const_string "V4SF")
2612                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2613                        (const_int 0))
2614                      (const_string "V2DF")]
2615                    (const_string "DF"))
2616                /* For architectures resolving dependencies on register
2617                   parts we may avoid extra work to zero out upper part
2618                   of register.  */
2619                (eq_attr "alternative" "7")
2620                  (if_then_else
2621                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2622                        (const_int 0))
2623                    (const_string "V2DF")
2624                    (const_string "DF"))]
2625                (const_string "DF")))])
2626
2627 (define_split
2628   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2629         (match_operand:DF 1 "general_operand" ""))]
2630   "reload_completed
2631    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2632    && ! (ANY_FP_REG_P (operands[0]) || 
2633          (GET_CODE (operands[0]) == SUBREG
2634           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2635    && ! (ANY_FP_REG_P (operands[1]) || 
2636          (GET_CODE (operands[1]) == SUBREG
2637           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2638   [(const_int 0)]
2639   "ix86_split_long_move (operands); DONE;")
2640
2641 (define_insn "*swapdf"
2642   [(set (match_operand:DF 0 "register_operand" "+f")
2643         (match_operand:DF 1 "register_operand" "+f"))
2644    (set (match_dup 1)
2645         (match_dup 0))]
2646   "reload_completed || !TARGET_SSE2"
2647 {
2648   if (STACK_TOP_P (operands[0]))
2649     return "fxch\t%1";
2650   else
2651     return "fxch\t%0";
2652 }
2653   [(set_attr "type" "fxch")
2654    (set_attr "mode" "DF")])
2655
2656 (define_expand "movxf"
2657   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2658         (match_operand:XF 1 "general_operand" ""))]
2659   ""
2660   "ix86_expand_move (XFmode, operands); DONE;")
2661
2662 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2663 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2664 ;; Pushing using integer instructions is longer except for constants
2665 ;; and direct memory references.
2666 ;; (assuming that any given constant is pushed only once, but this ought to be
2667 ;;  handled elsewhere).
2668
2669 (define_insn "*pushxf_nointeger"
2670   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2671         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2672   "optimize_size"
2673 {
2674   /* This insn should be already split before reg-stack.  */
2675   abort ();
2676 }
2677   [(set_attr "type" "multi")
2678    (set_attr "mode" "XF,SI,SI")])
2679
2680 (define_insn "*pushxf_integer"
2681   [(set (match_operand:XF 0 "push_operand" "=<,<")
2682         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2683   "!optimize_size"
2684 {
2685   /* This insn should be already split before reg-stack.  */
2686   abort ();
2687 }
2688   [(set_attr "type" "multi")
2689    (set_attr "mode" "XF,SI")])
2690
2691 (define_split
2692   [(set (match_operand 0 "push_operand" "")
2693         (match_operand 1 "general_operand" ""))]
2694   "reload_completed
2695    && (GET_MODE (operands[0]) == XFmode
2696        || GET_MODE (operands[0]) == DFmode)
2697    && !ANY_FP_REG_P (operands[1])"
2698   [(const_int 0)]
2699   "ix86_split_long_move (operands); DONE;")
2700
2701 (define_split
2702   [(set (match_operand:XF 0 "push_operand" "")
2703         (match_operand:XF 1 "any_fp_register_operand" ""))]
2704   "!TARGET_64BIT"
2705   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2706    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2707   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2708
2709 (define_split
2710   [(set (match_operand:XF 0 "push_operand" "")
2711         (match_operand:XF 1 "any_fp_register_operand" ""))]
2712   "TARGET_64BIT"
2713   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2714    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2715   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2716
2717 ;; Do not use integer registers when optimizing for size
2718 (define_insn "*movxf_nointeger"
2719   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2720         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2721   "optimize_size
2722    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2723    && (reload_in_progress || reload_completed
2724        || GET_CODE (operands[1]) != CONST_DOUBLE
2725        || memory_operand (operands[0], XFmode))" 
2726 {
2727   switch (which_alternative)
2728     {
2729     case 0:
2730       return output_387_reg_move (insn, operands);
2731
2732     case 1:
2733       /* There is no non-popping store to memory for XFmode.  So if
2734          we need one, follow the store with a load.  */
2735       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2736         return "fstp%z0\t%y0\;fld%z0\t%y0";
2737       else
2738         return "fstp%z0\t%y0";
2739
2740     case 2:
2741       return standard_80387_constant_opcode (operands[1]);
2742
2743     case 3: case 4:
2744       return "#";
2745     }
2746   abort();
2747 }
2748   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2749    (set_attr "mode" "XF,XF,XF,SI,SI")])
2750
2751 (define_insn "*movxf_integer"
2752   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2753         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2754   "!optimize_size
2755    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2756    && (reload_in_progress || reload_completed
2757        || GET_CODE (operands[1]) != CONST_DOUBLE
2758        || memory_operand (operands[0], XFmode))" 
2759 {
2760   switch (which_alternative)
2761     {
2762     case 0:
2763       return output_387_reg_move (insn, operands);
2764
2765     case 1:
2766       /* There is no non-popping store to memory for XFmode.  So if
2767          we need one, follow the store with a load.  */
2768       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2769         return "fstp%z0\t%y0\;fld%z0\t%y0";
2770       else
2771         return "fstp%z0\t%y0";
2772
2773     case 2:
2774       return standard_80387_constant_opcode (operands[1]);
2775
2776     case 3: case 4:
2777       return "#";
2778     }
2779   abort();
2780 }
2781   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2782    (set_attr "mode" "XF,XF,XF,SI,SI")])
2783
2784 (define_split
2785   [(set (match_operand 0 "nonimmediate_operand" "")
2786         (match_operand 1 "general_operand" ""))]
2787   "reload_completed
2788    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2789    && GET_MODE (operands[0]) == XFmode
2790    && ! (ANY_FP_REG_P (operands[0]) || 
2791          (GET_CODE (operands[0]) == SUBREG
2792           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2793    && ! (ANY_FP_REG_P (operands[1]) || 
2794          (GET_CODE (operands[1]) == SUBREG
2795           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2796   [(const_int 0)]
2797   "ix86_split_long_move (operands); DONE;")
2798
2799 (define_split
2800   [(set (match_operand 0 "register_operand" "")
2801         (match_operand 1 "memory_operand" ""))]
2802   "reload_completed
2803    && GET_CODE (operands[1]) == MEM
2804    && (GET_MODE (operands[0]) == XFmode
2805        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2806    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2807    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2808   [(set (match_dup 0) (match_dup 1))]
2809 {
2810   rtx c = get_pool_constant (XEXP (operands[1], 0));
2811   rtx r = operands[0];
2812
2813   if (GET_CODE (r) == SUBREG)
2814     r = SUBREG_REG (r);
2815
2816   if (SSE_REG_P (r))
2817     {
2818       if (!standard_sse_constant_p (c))
2819         FAIL;
2820     }
2821   else if (FP_REG_P (r))
2822     {
2823       if (!standard_80387_constant_p (c))
2824         FAIL;
2825     }
2826   else if (MMX_REG_P (r))
2827     FAIL;
2828
2829   operands[1] = c;
2830 })
2831
2832 (define_insn "swapxf"
2833   [(set (match_operand:XF 0 "register_operand" "+f")
2834         (match_operand:XF 1 "register_operand" "+f"))
2835    (set (match_dup 1)
2836         (match_dup 0))]
2837   ""
2838 {
2839   if (STACK_TOP_P (operands[0]))
2840     return "fxch\t%1";
2841   else
2842     return "fxch\t%0";
2843 }
2844   [(set_attr "type" "fxch")
2845    (set_attr "mode" "XF")])
2846 \f
2847 ;; Zero extension instructions
2848
2849 (define_expand "zero_extendhisi2"
2850   [(set (match_operand:SI 0 "register_operand" "")
2851      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2852   ""
2853 {
2854   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2855     {
2856       operands[1] = force_reg (HImode, operands[1]);
2857       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2858       DONE;
2859     }
2860 })
2861
2862 (define_insn "zero_extendhisi2_and"
2863   [(set (match_operand:SI 0 "register_operand" "=r")
2864      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2865    (clobber (reg:CC FLAGS_REG))]
2866   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2867   "#"
2868   [(set_attr "type" "alu1")
2869    (set_attr "mode" "SI")])
2870
2871 (define_split
2872   [(set (match_operand:SI 0 "register_operand" "")
2873         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2874    (clobber (reg:CC FLAGS_REG))]
2875   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2876   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2877               (clobber (reg:CC FLAGS_REG))])]
2878   "")
2879
2880 (define_insn "*zero_extendhisi2_movzwl"
2881   [(set (match_operand:SI 0 "register_operand" "=r")
2882      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2883   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2884   "movz{wl|x}\t{%1, %0|%0, %1}"
2885   [(set_attr "type" "imovx")
2886    (set_attr "mode" "SI")])
2887
2888 (define_expand "zero_extendqihi2"
2889   [(parallel
2890     [(set (match_operand:HI 0 "register_operand" "")
2891        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2892      (clobber (reg:CC FLAGS_REG))])]
2893   ""
2894   "")
2895
2896 (define_insn "*zero_extendqihi2_and"
2897   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2898      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2899    (clobber (reg:CC FLAGS_REG))]
2900   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2901   "#"
2902   [(set_attr "type" "alu1")
2903    (set_attr "mode" "HI")])
2904
2905 (define_insn "*zero_extendqihi2_movzbw_and"
2906   [(set (match_operand:HI 0 "register_operand" "=r,r")
2907      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2908    (clobber (reg:CC FLAGS_REG))]
2909   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2910   "#"
2911   [(set_attr "type" "imovx,alu1")
2912    (set_attr "mode" "HI")])
2913
2914 (define_insn "*zero_extendqihi2_movzbw"
2915   [(set (match_operand:HI 0 "register_operand" "=r")
2916      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2917   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2918   "movz{bw|x}\t{%1, %0|%0, %1}"
2919   [(set_attr "type" "imovx")
2920    (set_attr "mode" "HI")])
2921
2922 ;; For the movzbw case strip only the clobber
2923 (define_split
2924   [(set (match_operand:HI 0 "register_operand" "")
2925         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2926    (clobber (reg:CC FLAGS_REG))]
2927   "reload_completed 
2928    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2929    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2930   [(set (match_operand:HI 0 "register_operand" "")
2931         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2932
2933 ;; When source and destination does not overlap, clear destination
2934 ;; first and then do the movb
2935 (define_split
2936   [(set (match_operand:HI 0 "register_operand" "")
2937         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2938    (clobber (reg:CC FLAGS_REG))]
2939   "reload_completed
2940    && ANY_QI_REG_P (operands[0])
2941    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2942    && !reg_overlap_mentioned_p (operands[0], operands[1])"
2943   [(set (match_dup 0) (const_int 0))
2944    (set (strict_low_part (match_dup 2)) (match_dup 1))]
2945   "operands[2] = gen_lowpart (QImode, operands[0]);")
2946
2947 ;; Rest is handled by single and.
2948 (define_split
2949   [(set (match_operand:HI 0 "register_operand" "")
2950         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
2951    (clobber (reg:CC FLAGS_REG))]
2952   "reload_completed
2953    && true_regnum (operands[0]) == true_regnum (operands[1])"
2954   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
2955               (clobber (reg:CC FLAGS_REG))])]
2956   "")
2957
2958 (define_expand "zero_extendqisi2"
2959   [(parallel
2960     [(set (match_operand:SI 0 "register_operand" "")
2961        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2962      (clobber (reg:CC FLAGS_REG))])]
2963   ""
2964   "")
2965
2966 (define_insn "*zero_extendqisi2_and"
2967   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
2968      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2969    (clobber (reg:CC FLAGS_REG))]
2970   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2971   "#"
2972   [(set_attr "type" "alu1")
2973    (set_attr "mode" "SI")])
2974
2975 (define_insn "*zero_extendqisi2_movzbw_and"
2976   [(set (match_operand:SI 0 "register_operand" "=r,r")
2977      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2978    (clobber (reg:CC FLAGS_REG))]
2979   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2980   "#"
2981   [(set_attr "type" "imovx,alu1")
2982    (set_attr "mode" "SI")])
2983
2984 (define_insn "*zero_extendqisi2_movzbw"
2985   [(set (match_operand:SI 0 "register_operand" "=r")
2986      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2987   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2988   "movz{bl|x}\t{%1, %0|%0, %1}"
2989   [(set_attr "type" "imovx")
2990    (set_attr "mode" "SI")])
2991
2992 ;; For the movzbl case strip only the clobber
2993 (define_split
2994   [(set (match_operand:SI 0 "register_operand" "")
2995         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2996    (clobber (reg:CC FLAGS_REG))]
2997   "reload_completed 
2998    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2999    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3000   [(set (match_dup 0)
3001         (zero_extend:SI (match_dup 1)))])
3002
3003 ;; When source and destination does not overlap, clear destination
3004 ;; first and then do the movb
3005 (define_split
3006   [(set (match_operand:SI 0 "register_operand" "")
3007         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3008    (clobber (reg:CC FLAGS_REG))]
3009   "reload_completed
3010    && ANY_QI_REG_P (operands[0])
3011    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3012    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3013    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3014   [(set (match_dup 0) (const_int 0))
3015    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3016   "operands[2] = gen_lowpart (QImode, operands[0]);")
3017
3018 ;; Rest is handled by single and.
3019 (define_split
3020   [(set (match_operand:SI 0 "register_operand" "")
3021         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3022    (clobber (reg:CC FLAGS_REG))]
3023   "reload_completed
3024    && true_regnum (operands[0]) == true_regnum (operands[1])"
3025   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3026               (clobber (reg:CC FLAGS_REG))])]
3027   "")
3028
3029 ;; %%% Kill me once multi-word ops are sane.
3030 (define_expand "zero_extendsidi2"
3031   [(set (match_operand:DI 0 "register_operand" "=r")
3032      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3033   ""
3034   "if (!TARGET_64BIT)
3035      {
3036        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3037        DONE;
3038      }
3039   ")
3040
3041 (define_insn "zero_extendsidi2_32"
3042   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3043         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3044    (clobber (reg:CC FLAGS_REG))]
3045   "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3046   "@
3047    #
3048    #
3049    #
3050    movd\t{%1, %0|%0, %1}
3051    movd\t{%1, %0|%0, %1}"
3052   [(set_attr "mode" "SI,SI,SI,DI,TI")
3053    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3054
3055 (define_insn "*zero_extendsidi2_32_1"
3056   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3057         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3058    (clobber (reg:CC FLAGS_REG))]
3059   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3060   "@
3061    #
3062    #
3063    #
3064    movd\t{%1, %0|%0, %1}
3065    movd\t{%1, %0|%0, %1}"
3066   [(set_attr "mode" "SI,SI,SI,DI,TI")
3067    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3068
3069 (define_insn "zero_extendsidi2_rex64"
3070   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3071      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3072   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3073   "@
3074    mov\t{%k1, %k0|%k0, %k1}
3075    #
3076    movd\t{%1, %0|%0, %1}
3077    movd\t{%1, %0|%0, %1}"
3078   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3079    (set_attr "mode" "SI,DI,DI,TI")])
3080
3081 (define_insn "*zero_extendsidi2_rex64_1"
3082   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3083      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3084   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3085   "@
3086    mov\t{%k1, %k0|%k0, %k1}
3087    #
3088    movd\t{%1, %0|%0, %1}
3089    movd\t{%1, %0|%0, %1}"
3090   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3091    (set_attr "mode" "SI,DI,SI,SI")])
3092
3093 (define_split
3094   [(set (match_operand:DI 0 "memory_operand" "")
3095      (zero_extend:DI (match_dup 0)))]
3096   "TARGET_64BIT"
3097   [(set (match_dup 4) (const_int 0))]
3098   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3099
3100 (define_split 
3101   [(set (match_operand:DI 0 "register_operand" "")
3102         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3103    (clobber (reg:CC FLAGS_REG))]
3104   "!TARGET_64BIT && reload_completed
3105    && true_regnum (operands[0]) == true_regnum (operands[1])"
3106   [(set (match_dup 4) (const_int 0))]
3107   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3108
3109 (define_split 
3110   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3111         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3112    (clobber (reg:CC FLAGS_REG))]
3113   "!TARGET_64BIT && reload_completed
3114    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3115   [(set (match_dup 3) (match_dup 1))
3116    (set (match_dup 4) (const_int 0))]
3117   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3118
3119 (define_insn "zero_extendhidi2"
3120   [(set (match_operand:DI 0 "register_operand" "=r,r")
3121      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3122   "TARGET_64BIT"
3123   "@
3124    movz{wl|x}\t{%1, %k0|%k0, %1}
3125    movz{wq|x}\t{%1, %0|%0, %1}"
3126   [(set_attr "type" "imovx")
3127    (set_attr "mode" "SI,DI")])
3128
3129 (define_insn "zero_extendqidi2"
3130   [(set (match_operand:DI 0 "register_operand" "=r,r")
3131      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3132   "TARGET_64BIT"
3133   "@
3134    movz{bl|x}\t{%1, %k0|%k0, %1}
3135    movz{bq|x}\t{%1, %0|%0, %1}"
3136   [(set_attr "type" "imovx")
3137    (set_attr "mode" "SI,DI")])
3138 \f
3139 ;; Sign extension instructions
3140
3141 (define_expand "extendsidi2"
3142   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3143                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3144               (clobber (reg:CC FLAGS_REG))
3145               (clobber (match_scratch:SI 2 ""))])]
3146   ""
3147 {
3148   if (TARGET_64BIT)
3149     {
3150       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3151       DONE;
3152     }
3153 })
3154
3155 (define_insn "*extendsidi2_1"
3156   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3157         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3158    (clobber (reg:CC FLAGS_REG))
3159    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3160   "!TARGET_64BIT"
3161   "#")
3162
3163 (define_insn "extendsidi2_rex64"
3164   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3165         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3166   "TARGET_64BIT"
3167   "@
3168    {cltq|cdqe}
3169    movs{lq|x}\t{%1,%0|%0, %1}"
3170   [(set_attr "type" "imovx")
3171    (set_attr "mode" "DI")
3172    (set_attr "prefix_0f" "0")
3173    (set_attr "modrm" "0,1")])
3174
3175 (define_insn "extendhidi2"
3176   [(set (match_operand:DI 0 "register_operand" "=r")
3177         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3178   "TARGET_64BIT"
3179   "movs{wq|x}\t{%1,%0|%0, %1}"
3180   [(set_attr "type" "imovx")
3181    (set_attr "mode" "DI")])
3182
3183 (define_insn "extendqidi2"
3184   [(set (match_operand:DI 0 "register_operand" "=r")
3185         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3186   "TARGET_64BIT"
3187   "movs{bq|x}\t{%1,%0|%0, %1}"
3188    [(set_attr "type" "imovx")
3189     (set_attr "mode" "DI")])
3190
3191 ;; Extend to memory case when source register does die.
3192 (define_split 
3193   [(set (match_operand:DI 0 "memory_operand" "")
3194         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3195    (clobber (reg:CC FLAGS_REG))
3196    (clobber (match_operand:SI 2 "register_operand" ""))]
3197   "(reload_completed
3198     && dead_or_set_p (insn, operands[1])
3199     && !reg_mentioned_p (operands[1], operands[0]))"
3200   [(set (match_dup 3) (match_dup 1))
3201    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3202               (clobber (reg:CC FLAGS_REG))])
3203    (set (match_dup 4) (match_dup 1))]
3204   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3205
3206 ;; Extend to memory case when source register does not die.
3207 (define_split 
3208   [(set (match_operand:DI 0 "memory_operand" "")
3209         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3210    (clobber (reg:CC FLAGS_REG))
3211    (clobber (match_operand:SI 2 "register_operand" ""))]
3212   "reload_completed"
3213   [(const_int 0)]
3214 {
3215   split_di (&operands[0], 1, &operands[3], &operands[4]);
3216
3217   emit_move_insn (operands[3], operands[1]);
3218
3219   /* Generate a cltd if possible and doing so it profitable.  */
3220   if (true_regnum (operands[1]) == 0
3221       && true_regnum (operands[2]) == 1
3222       && (optimize_size || TARGET_USE_CLTD))
3223     {
3224       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3225     }
3226   else
3227     {
3228       emit_move_insn (operands[2], operands[1]);
3229       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3230     }
3231   emit_move_insn (operands[4], operands[2]);
3232   DONE;
3233 })
3234
3235 ;; Extend to register case.  Optimize case where source and destination
3236 ;; registers match and cases where we can use cltd.
3237 (define_split 
3238   [(set (match_operand:DI 0 "register_operand" "")
3239         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3240    (clobber (reg:CC FLAGS_REG))
3241    (clobber (match_scratch:SI 2 ""))]
3242   "reload_completed"
3243   [(const_int 0)]
3244 {
3245   split_di (&operands[0], 1, &operands[3], &operands[4]);
3246
3247   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3248     emit_move_insn (operands[3], operands[1]);
3249
3250   /* Generate a cltd if possible and doing so it profitable.  */
3251   if (true_regnum (operands[3]) == 0
3252       && (optimize_size || TARGET_USE_CLTD))
3253     {
3254       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3255       DONE;
3256     }
3257
3258   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3259     emit_move_insn (operands[4], operands[1]);
3260
3261   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3262   DONE;
3263 })
3264
3265 (define_insn "extendhisi2"
3266   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3267         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3268   ""
3269 {
3270   switch (get_attr_prefix_0f (insn))
3271     {
3272     case 0:
3273       return "{cwtl|cwde}";
3274     default:
3275       return "movs{wl|x}\t{%1,%0|%0, %1}";
3276     }
3277 }
3278   [(set_attr "type" "imovx")
3279    (set_attr "mode" "SI")
3280    (set (attr "prefix_0f")
3281      ;; movsx is short decodable while cwtl is vector decoded.
3282      (if_then_else (and (eq_attr "cpu" "!k6")
3283                         (eq_attr "alternative" "0"))
3284         (const_string "0")
3285         (const_string "1")))
3286    (set (attr "modrm")
3287      (if_then_else (eq_attr "prefix_0f" "0")
3288         (const_string "0")
3289         (const_string "1")))])
3290
3291 (define_insn "*extendhisi2_zext"
3292   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3293         (zero_extend:DI
3294           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3295   "TARGET_64BIT"
3296 {
3297   switch (get_attr_prefix_0f (insn))
3298     {
3299     case 0:
3300       return "{cwtl|cwde}";
3301     default:
3302       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3303     }
3304 }
3305   [(set_attr "type" "imovx")
3306    (set_attr "mode" "SI")
3307    (set (attr "prefix_0f")
3308      ;; movsx is short decodable while cwtl is vector decoded.
3309      (if_then_else (and (eq_attr "cpu" "!k6")
3310                         (eq_attr "alternative" "0"))
3311         (const_string "0")
3312         (const_string "1")))
3313    (set (attr "modrm")
3314      (if_then_else (eq_attr "prefix_0f" "0")
3315         (const_string "0")
3316         (const_string "1")))])
3317
3318 (define_insn "extendqihi2"
3319   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3320         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3321   ""
3322 {
3323   switch (get_attr_prefix_0f (insn))
3324     {
3325     case 0:
3326       return "{cbtw|cbw}";
3327     default:
3328       return "movs{bw|x}\t{%1,%0|%0, %1}";
3329     }
3330 }
3331   [(set_attr "type" "imovx")
3332    (set_attr "mode" "HI")
3333    (set (attr "prefix_0f")
3334      ;; movsx is short decodable while cwtl is vector decoded.
3335      (if_then_else (and (eq_attr "cpu" "!k6")
3336                         (eq_attr "alternative" "0"))
3337         (const_string "0")
3338         (const_string "1")))
3339    (set (attr "modrm")
3340      (if_then_else (eq_attr "prefix_0f" "0")
3341         (const_string "0")
3342         (const_string "1")))])
3343
3344 (define_insn "extendqisi2"
3345   [(set (match_operand:SI 0 "register_operand" "=r")
3346         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3347   ""
3348   "movs{bl|x}\t{%1,%0|%0, %1}"
3349    [(set_attr "type" "imovx")
3350     (set_attr "mode" "SI")])
3351
3352 (define_insn "*extendqisi2_zext"
3353   [(set (match_operand:DI 0 "register_operand" "=r")
3354         (zero_extend:DI
3355           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3356   "TARGET_64BIT"
3357   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3358    [(set_attr "type" "imovx")
3359     (set_attr "mode" "SI")])
3360 \f
3361 ;; Conversions between float and double.
3362
3363 ;; These are all no-ops in the model used for the 80387.  So just
3364 ;; emit moves.
3365
3366 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3367 (define_insn "*dummy_extendsfdf2"
3368   [(set (match_operand:DF 0 "push_operand" "=<")
3369         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3370   "0"
3371   "#")
3372
3373 (define_split
3374   [(set (match_operand:DF 0 "push_operand" "")
3375         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3376   "!TARGET_64BIT"
3377   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3378    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3379
3380 (define_split
3381   [(set (match_operand:DF 0 "push_operand" "")
3382         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3383   "TARGET_64BIT"
3384   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3385    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3386
3387 (define_insn "*dummy_extendsfxf2"
3388   [(set (match_operand:XF 0 "push_operand" "=<")
3389         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3390   "0"
3391   "#")
3392
3393 (define_split
3394   [(set (match_operand:XF 0 "push_operand" "")
3395         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3396   ""
3397   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3398    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3399   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3400
3401 (define_split
3402   [(set (match_operand:XF 0 "push_operand" "")
3403         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3404   "TARGET_64BIT"
3405   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3406    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3407   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3408
3409 (define_split
3410   [(set (match_operand:XF 0 "push_operand" "")
3411         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3412   ""
3413   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3414    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3415   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3416
3417 (define_split
3418   [(set (match_operand:XF 0 "push_operand" "")
3419         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3420   "TARGET_64BIT"
3421   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3422    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3423   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3424
3425 (define_expand "extendsfdf2"
3426   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3427         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3428   "TARGET_80387 || TARGET_SSE2"
3429 {
3430   /* ??? Needed for compress_float_constant since all fp constants
3431      are LEGITIMATE_CONSTANT_P.  */
3432   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3433     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3434   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3435     operands[1] = force_reg (SFmode, operands[1]);
3436 })
3437
3438 (define_insn "*extendsfdf2_1"
3439   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3440         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3441   "(TARGET_80387 || TARGET_SSE2)
3442    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3443 {
3444   switch (which_alternative)
3445     {
3446     case 0:
3447       return output_387_reg_move (insn, operands);
3448
3449     case 1:
3450       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3451         return "fstp%z0\t%y0";
3452       else
3453         return "fst%z0\t%y0";
3454
3455     case 2:
3456       return "cvtss2sd\t{%1, %0|%0, %1}";
3457
3458     default:
3459       abort ();
3460     }
3461 }
3462   [(set_attr "type" "fmov,fmov,ssecvt")
3463    (set_attr "mode" "SF,XF,DF")])
3464
3465 (define_insn "*extendsfdf2_1_sse_only"
3466   [(set (match_operand:DF 0 "register_operand" "=Y")
3467         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3468   "!TARGET_80387 && TARGET_SSE2
3469    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3470   "cvtss2sd\t{%1, %0|%0, %1}"
3471   [(set_attr "type" "ssecvt")
3472    (set_attr "mode" "DF")])
3473
3474 (define_expand "extendsfxf2"
3475   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3476         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3477   "TARGET_80387"
3478 {
3479   /* ??? Needed for compress_float_constant since all fp constants
3480      are LEGITIMATE_CONSTANT_P.  */
3481   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3482     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3483   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3484     operands[1] = force_reg (SFmode, operands[1]);
3485 })
3486
3487 (define_insn "*extendsfxf2_1"
3488   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3489         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3490   "TARGET_80387
3491    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3492 {
3493   switch (which_alternative)
3494     {
3495     case 0:
3496       return output_387_reg_move (insn, operands);
3497
3498     case 1:
3499       /* There is no non-popping store to memory for XFmode.  So if
3500          we need one, follow the store with a load.  */
3501       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3502         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3503       else
3504         return "fstp%z0\t%y0";
3505
3506     default:
3507       abort ();
3508     }
3509 }
3510   [(set_attr "type" "fmov")
3511    (set_attr "mode" "SF,XF")])
3512
3513 (define_expand "extenddfxf2"
3514   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3515         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3516   "TARGET_80387"
3517 {
3518   /* ??? Needed for compress_float_constant since all fp constants
3519      are LEGITIMATE_CONSTANT_P.  */
3520   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3521     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3522   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3523     operands[1] = force_reg (DFmode, operands[1]);
3524 })
3525
3526 (define_insn "*extenddfxf2_1"
3527   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3528         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3529   "TARGET_80387
3530    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3531 {
3532   switch (which_alternative)
3533     {
3534     case 0:
3535       return output_387_reg_move (insn, operands);
3536
3537     case 1:
3538       /* There is no non-popping store to memory for XFmode.  So if
3539          we need one, follow the store with a load.  */
3540       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3541         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3542       else
3543         return "fstp%z0\t%y0";
3544
3545     default:
3546       abort ();
3547     }
3548 }
3549   [(set_attr "type" "fmov")
3550    (set_attr "mode" "DF,XF")])
3551
3552 ;; %%% This seems bad bad news.
3553 ;; This cannot output into an f-reg because there is no way to be sure
3554 ;; of truncating in that case.  Otherwise this is just like a simple move
3555 ;; insn.  So we pretend we can output to a reg in order to get better
3556 ;; register preferencing, but we really use a stack slot.
3557
3558 (define_expand "truncdfsf2"
3559   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3560                    (float_truncate:SF
3561                     (match_operand:DF 1 "register_operand" "")))
3562               (clobber (match_dup 2))])]
3563   "TARGET_80387 || TARGET_SSE2"
3564   "
3565    if (!TARGET_80387)
3566      {
3567         emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3568         DONE;
3569      }
3570    else if (flag_unsafe_math_optimizations)
3571      {
3572         rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3573         emit_insn (gen_truncdfsf2_noop (reg, operands[1]));
3574         if (reg != operands[0])
3575           emit_move_insn (operands[0], reg);
3576         DONE;
3577      }
3578    else
3579      operands[2] = assign_386_stack_local (SFmode, 0);
3580 ")
3581
3582 (define_insn "truncdfsf2_noop"
3583   [(set (match_operand:SF 0 "register_operand" "=f")
3584         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3585   "TARGET_80387 && flag_unsafe_math_optimizations"
3586 {
3587   return output_387_reg_move (insn, operands);
3588 }
3589   [(set_attr "type" "fmov")
3590    (set_attr "mode" "SF")])
3591
3592 (define_insn "*truncdfsf2_1"
3593   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3594         (float_truncate:SF
3595          (match_operand:DF 1 "register_operand" "f,f,f,f")))
3596    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3597   "TARGET_80387 && !TARGET_SSE2"
3598 {
3599   switch (which_alternative)
3600     {
3601     case 0:
3602       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3603         return "fstp%z0\t%y0";
3604       else
3605         return "fst%z0\t%y0";
3606     default:
3607       abort ();
3608     }
3609 }
3610   [(set_attr "type" "fmov,multi,multi,multi")
3611    (set_attr "mode" "SF,SF,SF,SF")])
3612
3613 (define_insn "*truncdfsf2_1_sse"
3614   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3615         (float_truncate:SF
3616          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3617    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3618   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3619 {
3620   switch (which_alternative)
3621     {
3622     case 0:
3623       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3624         return "fstp%z0\t%y0";
3625       else
3626         return "fst%z0\t%y0";
3627     case 4:
3628       return "#";
3629     default:
3630       abort ();
3631     }
3632 }
3633   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3634    (set_attr "mode" "SF,SF,SF,SF,DF")])
3635
3636 (define_insn "*truncdfsf2_1_sse_nooverlap"
3637   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3638         (float_truncate:SF
3639          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3640    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3641   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3642 {
3643   switch (which_alternative)
3644     {
3645     case 0:
3646       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3647         return "fstp%z0\t%y0";
3648       else
3649         return "fst%z0\t%y0";
3650     case 4:
3651       return "#";
3652     default:
3653       abort ();
3654     }
3655 }
3656   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3657    (set_attr "mode" "SF,SF,SF,SF,DF")])
3658
3659 (define_insn "*truncdfsf2_2"
3660   [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3661         (float_truncate:SF
3662          (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3663   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3664    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3665 {
3666   switch (which_alternative)
3667     {
3668     case 0:
3669     case 1:
3670       return "cvtsd2ss\t{%1, %0|%0, %1}";
3671     case 2:
3672       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3673         return "fstp%z0\t%y0";
3674       else
3675         return "fst%z0\t%y0";
3676     default:
3677       abort ();
3678     }
3679 }
3680   [(set_attr "type" "ssecvt,ssecvt,fmov")
3681    (set_attr "athlon_decode" "vector,double,*")
3682    (set_attr "mode" "SF,SF,SF")])
3683
3684 (define_insn "*truncdfsf2_2_nooverlap"
3685   [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3686         (float_truncate:SF
3687          (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3688   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3689    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3690 {
3691   switch (which_alternative)
3692     {
3693     case 0:
3694       return "#";
3695     case 1:
3696       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3697         return "fstp%z0\t%y0";
3698       else
3699         return "fst%z0\t%y0";
3700     default:
3701       abort ();
3702     }
3703 }
3704   [(set_attr "type" "ssecvt,fmov")
3705    (set_attr "mode" "DF,SF")])
3706
3707 (define_insn "*truncdfsf2_3"
3708   [(set (match_operand:SF 0 "memory_operand" "=m")
3709         (float_truncate:SF
3710          (match_operand:DF 1 "register_operand" "f")))]
3711   "TARGET_80387"
3712 {
3713   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3714     return "fstp%z0\t%y0";
3715   else
3716     return "fst%z0\t%y0";
3717 }
3718   [(set_attr "type" "fmov")
3719    (set_attr "mode" "SF")])
3720
3721 (define_insn "truncdfsf2_sse_only"
3722   [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3723         (float_truncate:SF
3724          (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3725   "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3726   "cvtsd2ss\t{%1, %0|%0, %1}"
3727   [(set_attr "type" "ssecvt")
3728    (set_attr "athlon_decode" "vector,double")
3729    (set_attr "mode" "SF")])
3730
3731 (define_insn "*truncdfsf2_sse_only_nooverlap"
3732   [(set (match_operand:SF 0 "register_operand" "=&Y")
3733         (float_truncate:SF
3734          (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3735   "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3736   "#"
3737   [(set_attr "type" "ssecvt")
3738    (set_attr "mode" "DF")])
3739
3740 (define_split
3741   [(set (match_operand:SF 0 "memory_operand" "")
3742         (float_truncate:SF
3743          (match_operand:DF 1 "register_operand" "")))
3744    (clobber (match_operand:SF 2 "memory_operand" ""))]
3745   "TARGET_80387"
3746   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3747   "")
3748
3749 ; Avoid possible reformatting penalty on the destination by first
3750 ; zeroing it out
3751 (define_split
3752   [(set (match_operand:SF 0 "register_operand" "")
3753         (float_truncate:SF
3754          (match_operand:DF 1 "nonimmediate_operand" "")))
3755    (clobber (match_operand 2 "" ""))]
3756   "TARGET_80387 && reload_completed
3757    && SSE_REG_P (operands[0])
3758    && !STACK_REG_P (operands[1])"
3759   [(const_int 0)]
3760 {
3761   rtx src, dest;
3762   if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3763     emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3764   else
3765     {
3766       dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3767       src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3768       /* simplify_gen_subreg refuses to widen memory references.  */
3769       if (GET_CODE (src) == SUBREG)
3770         alter_subreg (&src);
3771       if (reg_overlap_mentioned_p (operands[0], operands[1]))
3772         abort ();
3773       emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3774       emit_insn (gen_cvtsd2ss (dest, dest, src));
3775     }
3776   DONE;
3777 })
3778
3779 (define_split
3780   [(set (match_operand:SF 0 "register_operand" "")
3781         (float_truncate:SF
3782          (match_operand:DF 1 "nonimmediate_operand" "")))]
3783   "TARGET_80387 && reload_completed
3784    && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3785   [(const_int 0)]
3786 {
3787   rtx src, dest;
3788   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3789   src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3790   /* simplify_gen_subreg refuses to widen memory references.  */
3791   if (GET_CODE (src) == SUBREG)
3792     alter_subreg (&src);
3793   if (reg_overlap_mentioned_p (operands[0], operands[1]))
3794     abort ();
3795   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3796   emit_insn (gen_cvtsd2ss (dest, dest, src));
3797   DONE;
3798 })
3799
3800 (define_split
3801   [(set (match_operand:SF 0 "register_operand" "")
3802         (float_truncate:SF
3803          (match_operand:DF 1 "fp_register_operand" "")))
3804    (clobber (match_operand:SF 2 "memory_operand" ""))]
3805   "TARGET_80387 && reload_completed"
3806   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3807    (set (match_dup 0) (match_dup 2))]
3808   "")
3809
3810 (define_expand "truncxfsf2"
3811   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3812                    (float_truncate:SF
3813                     (match_operand:XF 1 "register_operand" "")))
3814               (clobber (match_dup 2))])]
3815   "TARGET_80387"
3816   "
3817   if (flag_unsafe_math_optimizations)
3818     {
3819       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3820       emit_insn (gen_truncxfsf2_noop (reg, operands[1]));
3821       if (reg != operands[0])
3822         emit_move_insn (operands[0], reg);
3823       DONE;
3824     }
3825   else
3826     operands[2] = assign_386_stack_local (SFmode, 0);
3827   ")
3828
3829 (define_insn "truncxfsf2_noop"
3830   [(set (match_operand:SF 0 "register_operand" "=f")
3831         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3832   "TARGET_80387 && flag_unsafe_math_optimizations"
3833 {
3834   return output_387_reg_move (insn, operands);
3835 }
3836   [(set_attr "type" "fmov")
3837    (set_attr "mode" "SF")])
3838
3839 (define_insn "*truncxfsf2_1"
3840   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3841         (float_truncate:SF
3842          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3843    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3844   "TARGET_80387"
3845 {
3846   switch (which_alternative)
3847     {
3848     case 0:
3849       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3850         return "fstp%z0\t%y0";
3851       else
3852         return "fst%z0\t%y0";
3853     default:
3854       abort();
3855     }
3856 }
3857   [(set_attr "type" "fmov,multi,multi,multi")
3858    (set_attr "mode" "SF")])
3859
3860 (define_insn "*truncxfsf2_2"
3861   [(set (match_operand:SF 0 "memory_operand" "=m")
3862         (float_truncate:SF
3863          (match_operand:XF 1 "register_operand" "f")))]
3864   "TARGET_80387"
3865 {
3866   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3867     return "fstp%z0\t%y0";
3868   else
3869     return "fst%z0\t%y0";
3870 }
3871   [(set_attr "type" "fmov")
3872    (set_attr "mode" "SF")])
3873
3874 (define_split
3875   [(set (match_operand:SF 0 "memory_operand" "")
3876         (float_truncate:SF
3877          (match_operand:XF 1 "register_operand" "")))
3878    (clobber (match_operand:SF 2 "memory_operand" ""))]
3879   "TARGET_80387"
3880   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3881   "")
3882
3883 (define_split
3884   [(set (match_operand:SF 0 "register_operand" "")
3885         (float_truncate:SF
3886          (match_operand:XF 1 "register_operand" "")))
3887    (clobber (match_operand:SF 2 "memory_operand" ""))]
3888   "TARGET_80387 && reload_completed"
3889   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3890    (set (match_dup 0) (match_dup 2))]
3891   "")
3892
3893 (define_expand "truncxfdf2"
3894   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3895                    (float_truncate:DF
3896                     (match_operand:XF 1 "register_operand" "")))
3897               (clobber (match_dup 2))])]
3898   "TARGET_80387"
3899   "
3900   if (flag_unsafe_math_optimizations)
3901     {
3902       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3903       emit_insn (gen_truncxfdf2_noop (reg, operands[1]));
3904       if (reg != operands[0])
3905         emit_move_insn (operands[0], reg);
3906       DONE;
3907     }
3908   else
3909     operands[2] = assign_386_stack_local (DFmode, 0);
3910   ")
3911
3912 (define_insn "truncxfdf2_noop"
3913   [(set (match_operand:DF 0 "register_operand" "=f")
3914         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3915   "TARGET_80387 && flag_unsafe_math_optimizations"
3916 {
3917   return output_387_reg_move (insn, operands);
3918 }
3919   [(set_attr "type" "fmov")
3920    (set_attr "mode" "DF")])
3921
3922 (define_insn "*truncxfdf2_1"
3923   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3924         (float_truncate:DF
3925          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3926    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3927   "TARGET_80387"
3928 {
3929   switch (which_alternative)
3930     {
3931     case 0:
3932       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3933         return "fstp%z0\t%y0";
3934       else
3935         return "fst%z0\t%y0";
3936     default:
3937       abort();
3938     }
3939   abort ();
3940 }
3941   [(set_attr "type" "fmov,multi,multi,multi")
3942    (set_attr "mode" "DF")])
3943
3944 (define_insn "*truncxfdf2_2"
3945   [(set (match_operand:DF 0 "memory_operand" "=m")
3946         (float_truncate:DF
3947           (match_operand:XF 1 "register_operand" "f")))]
3948   "TARGET_80387"
3949 {
3950   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3951     return "fstp%z0\t%y0";
3952   else
3953     return "fst%z0\t%y0";
3954 }
3955   [(set_attr "type" "fmov")
3956    (set_attr "mode" "DF")])
3957
3958 (define_split
3959   [(set (match_operand:DF 0 "memory_operand" "")
3960         (float_truncate:DF
3961          (match_operand:XF 1 "register_operand" "")))
3962    (clobber (match_operand:DF 2 "memory_operand" ""))]
3963   "TARGET_80387"
3964   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3965   "")
3966
3967 (define_split
3968   [(set (match_operand:DF 0 "register_operand" "")
3969         (float_truncate:DF
3970          (match_operand:XF 1 "register_operand" "")))
3971    (clobber (match_operand:DF 2 "memory_operand" ""))]
3972   "TARGET_80387 && reload_completed"
3973   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3974    (set (match_dup 0) (match_dup 2))]
3975   "")
3976
3977 \f
3978 ;; %%% Break up all these bad boys.
3979
3980 ;; Signed conversion to DImode.
3981
3982 (define_expand "fix_truncxfdi2"
3983   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3984                    (fix:DI (match_operand:XF 1 "register_operand" "")))
3985               (clobber (reg:CC FLAGS_REG))])]
3986   "TARGET_80387"
3987   "")
3988
3989 (define_expand "fix_truncdfdi2"
3990   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3991                    (fix:DI (match_operand:DF 1 "register_operand" "")))
3992               (clobber (reg:CC FLAGS_REG))])]
3993   "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
3994 {
3995   if (TARGET_64BIT && TARGET_SSE2)
3996    {
3997      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
3998      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
3999      if (out != operands[0])
4000         emit_move_insn (operands[0], out);
4001      DONE;
4002    }
4003 })
4004
4005 (define_expand "fix_truncsfdi2"
4006   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4007                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4008               (clobber (reg:CC FLAGS_REG))])] 
4009   "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4010 {
4011   if (TARGET_SSE && TARGET_64BIT)
4012    {
4013      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4014      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4015      if (out != operands[0])
4016         emit_move_insn (operands[0], out);
4017      DONE;
4018    }
4019 })
4020
4021 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4022 ;; of the machinery.
4023 (define_insn_and_split "*fix_truncdi_1"
4024   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4025         (fix:DI (match_operand 1 "register_operand" "f,f")))
4026    (clobber (reg:CC FLAGS_REG))]
4027   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4028    && !reload_completed && !reload_in_progress
4029    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4030   "#"
4031   "&& 1"
4032   [(const_int 0)]
4033 {
4034   ix86_optimize_mode_switching = 1;
4035   operands[2] = assign_386_stack_local (HImode, 1);
4036   operands[3] = assign_386_stack_local (HImode, 2);
4037   if (memory_operand (operands[0], VOIDmode))
4038     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4039                                        operands[2], operands[3]));
4040   else
4041     {
4042       operands[4] = assign_386_stack_local (DImode, 0);
4043       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4044                                            operands[2], operands[3],
4045                                            operands[4]));
4046     }
4047   DONE;
4048 }
4049   [(set_attr "type" "fistp")
4050    (set_attr "i387_cw" "trunc")
4051    (set_attr "mode" "DI")])
4052
4053 (define_insn "fix_truncdi_nomemory"
4054   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4055         (fix:DI (match_operand 1 "register_operand" "f,f")))
4056    (use (match_operand:HI 2 "memory_operand" "m,m"))
4057    (use (match_operand:HI 3 "memory_operand" "m,m"))
4058    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4059    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4060   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4061    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4062   "#"
4063   [(set_attr "type" "fistp")
4064    (set_attr "i387_cw" "trunc")
4065    (set_attr "mode" "DI")])
4066
4067 (define_insn "fix_truncdi_memory"
4068   [(set (match_operand:DI 0 "memory_operand" "=m")
4069         (fix:DI (match_operand 1 "register_operand" "f")))
4070    (use (match_operand:HI 2 "memory_operand" "m"))
4071    (use (match_operand:HI 3 "memory_operand" "m"))
4072    (clobber (match_scratch:DF 4 "=&1f"))]
4073   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4074    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4075   "* return output_fix_trunc (insn, operands);"
4076   [(set_attr "type" "fistp")
4077    (set_attr "i387_cw" "trunc")
4078    (set_attr "mode" "DI")])
4079
4080 (define_split 
4081   [(set (match_operand:DI 0 "register_operand" "")
4082         (fix:DI (match_operand 1 "register_operand" "")))
4083    (use (match_operand:HI 2 "memory_operand" ""))
4084    (use (match_operand:HI 3 "memory_operand" ""))
4085    (clobber (match_operand:DI 4 "memory_operand" ""))
4086    (clobber (match_scratch 5 ""))]
4087   "reload_completed"
4088   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4089               (use (match_dup 2))
4090               (use (match_dup 3))
4091               (clobber (match_dup 5))])
4092    (set (match_dup 0) (match_dup 4))]
4093   "")
4094
4095 (define_split 
4096   [(set (match_operand:DI 0 "memory_operand" "")
4097         (fix:DI (match_operand 1 "register_operand" "")))
4098    (use (match_operand:HI 2 "memory_operand" ""))
4099    (use (match_operand:HI 3 "memory_operand" ""))
4100    (clobber (match_operand:DI 4 "memory_operand" ""))
4101    (clobber (match_scratch 5 ""))]
4102   "reload_completed"
4103   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4104               (use (match_dup 2))
4105               (use (match_dup 3))
4106               (clobber (match_dup 5))])]
4107   "")
4108
4109 ;; When SSE available, it is always faster to use it!
4110 (define_insn "fix_truncsfdi_sse"
4111   [(set (match_operand:DI 0 "register_operand" "=r,r")
4112         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4113   "TARGET_64BIT && TARGET_SSE"
4114   "cvttss2si{q}\t{%1, %0|%0, %1}"
4115   [(set_attr "type" "sseicvt")
4116    (set_attr "mode" "SF")
4117    (set_attr "athlon_decode" "double,vector")])
4118
4119 ;; Avoid vector decoded form of the instruction.
4120 (define_peephole2
4121   [(match_scratch:SF 2 "x")
4122    (set (match_operand:DI 0 "register_operand" "")
4123         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4124   "TARGET_K8 && !optimize_size"
4125   [(set (match_dup 2) (match_dup 1))
4126    (set (match_dup 0) (fix:DI (match_dup 2)))]
4127   "")
4128
4129 (define_insn "fix_truncdfdi_sse"
4130   [(set (match_operand:DI 0 "register_operand" "=r,r")
4131         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4132   "TARGET_64BIT && TARGET_SSE2"
4133   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4134   [(set_attr "type" "sseicvt,sseicvt")
4135    (set_attr "mode" "DF")
4136    (set_attr "athlon_decode" "double,vector")])
4137
4138 ;; Avoid vector decoded form of the instruction.
4139 (define_peephole2
4140   [(match_scratch:DF 2 "Y")
4141    (set (match_operand:DI 0 "register_operand" "")
4142         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4143   "TARGET_K8 && !optimize_size"
4144   [(set (match_dup 2) (match_dup 1))
4145    (set (match_dup 0) (fix:DI (match_dup 2)))]
4146   "")
4147
4148 ;; Signed conversion to SImode.
4149
4150 (define_expand "fix_truncxfsi2"
4151   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4152                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4153               (clobber (reg:CC FLAGS_REG))])]
4154   "TARGET_80387"
4155   "")
4156
4157 (define_expand "fix_truncdfsi2"
4158   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4159                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4160               (clobber (reg:CC FLAGS_REG))])]
4161   "TARGET_80387 || TARGET_SSE2"
4162 {
4163   if (TARGET_SSE2)
4164    {
4165      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4166      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4167      if (out != operands[0])
4168         emit_move_insn (operands[0], out);
4169      DONE;
4170    }
4171 })
4172
4173 (define_expand "fix_truncsfsi2"
4174   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4175                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4176               (clobber (reg:CC FLAGS_REG))])] 
4177   "TARGET_80387 || TARGET_SSE"
4178 {
4179   if (TARGET_SSE)
4180    {
4181      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4182      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4183      if (out != operands[0])
4184         emit_move_insn (operands[0], out);
4185      DONE;
4186    }
4187 })
4188
4189 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4190 ;; of the machinery.
4191 (define_insn_and_split "*fix_truncsi_1"
4192   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4193         (fix:SI (match_operand 1 "register_operand" "f,f")))
4194    (clobber (reg:CC FLAGS_REG))]
4195   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4196    && !reload_completed && !reload_in_progress
4197    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4198   "#"
4199   "&& 1"
4200   [(const_int 0)]
4201 {
4202   ix86_optimize_mode_switching = 1;
4203   operands[2] = assign_386_stack_local (HImode, 1);
4204   operands[3] = assign_386_stack_local (HImode, 2);
4205   if (memory_operand (operands[0], VOIDmode))
4206     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4207                                        operands[2], operands[3]));
4208   else
4209     {
4210       operands[4] = assign_386_stack_local (SImode, 0);
4211       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4212                                            operands[2], operands[3],
4213                                            operands[4]));
4214     }
4215   DONE;
4216 }
4217   [(set_attr "type" "fistp")
4218    (set_attr "i387_cw" "trunc")
4219    (set_attr "mode" "SI")])
4220
4221 (define_insn "fix_truncsi_nomemory"
4222   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4223         (fix:SI (match_operand 1 "register_operand" "f,f")))
4224    (use (match_operand:HI 2 "memory_operand" "m,m"))
4225    (use (match_operand:HI 3 "memory_operand" "m,m"))
4226    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4227   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4228    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4229   "#"
4230   [(set_attr "type" "fistp")
4231    (set_attr "i387_cw" "trunc")
4232    (set_attr "mode" "SI")])
4233
4234 (define_insn "fix_truncsi_memory"
4235   [(set (match_operand:SI 0 "memory_operand" "=m")
4236         (fix:SI (match_operand 1 "register_operand" "f")))
4237    (use (match_operand:HI 2 "memory_operand" "m"))
4238    (use (match_operand:HI 3 "memory_operand" "m"))]
4239   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4240    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4241   "* return output_fix_trunc (insn, operands);"
4242   [(set_attr "type" "fistp")
4243    (set_attr "i387_cw" "trunc")
4244    (set_attr "mode" "SI")])
4245
4246 ;; When SSE available, it is always faster to use it!
4247 (define_insn "fix_truncsfsi_sse"
4248   [(set (match_operand:SI 0 "register_operand" "=r,r")
4249         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4250   "TARGET_SSE"
4251   "cvttss2si\t{%1, %0|%0, %1}"
4252   [(set_attr "type" "sseicvt")
4253    (set_attr "mode" "DF")
4254    (set_attr "athlon_decode" "double,vector")])
4255
4256 ;; Avoid vector decoded form of the instruction.
4257 (define_peephole2
4258   [(match_scratch:SF 2 "x")
4259    (set (match_operand:SI 0 "register_operand" "")
4260         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4261   "TARGET_K8 && !optimize_size"
4262   [(set (match_dup 2) (match_dup 1))
4263    (set (match_dup 0) (fix:SI (match_dup 2)))]
4264   "")
4265
4266 (define_insn "fix_truncdfsi_sse"
4267   [(set (match_operand:SI 0 "register_operand" "=r,r")
4268         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4269   "TARGET_SSE2"
4270   "cvttsd2si\t{%1, %0|%0, %1}"
4271   [(set_attr "type" "sseicvt")
4272    (set_attr "mode" "DF")
4273    (set_attr "athlon_decode" "double,vector")])
4274
4275 ;; Avoid vector decoded form of the instruction.
4276 (define_peephole2
4277   [(match_scratch:DF 2 "Y")
4278    (set (match_operand:SI 0 "register_operand" "")
4279         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4280   "TARGET_K8 && !optimize_size"
4281   [(set (match_dup 2) (match_dup 1))
4282    (set (match_dup 0) (fix:SI (match_dup 2)))]
4283   "")
4284
4285 (define_split 
4286   [(set (match_operand:SI 0 "register_operand" "")
4287         (fix:SI (match_operand 1 "register_operand" "")))
4288    (use (match_operand:HI 2 "memory_operand" ""))
4289    (use (match_operand:HI 3 "memory_operand" ""))
4290    (clobber (match_operand:SI 4 "memory_operand" ""))]
4291   "reload_completed"
4292   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4293               (use (match_dup 2))
4294               (use (match_dup 3))])
4295    (set (match_dup 0) (match_dup 4))]
4296   "")
4297
4298 (define_split 
4299   [(set (match_operand:SI 0 "memory_operand" "")
4300         (fix:SI (match_operand 1 "register_operand" "")))
4301    (use (match_operand:HI 2 "memory_operand" ""))
4302    (use (match_operand:HI 3 "memory_operand" ""))
4303    (clobber (match_operand:SI 4 "memory_operand" ""))]
4304   "reload_completed"
4305   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4306               (use (match_dup 2))
4307               (use (match_dup 3))])]
4308   "")
4309
4310 ;; Signed conversion to HImode.
4311
4312 (define_expand "fix_truncxfhi2"
4313   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4314                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4315               (clobber (reg:CC FLAGS_REG))])] 
4316   "TARGET_80387"
4317   "")
4318
4319 (define_expand "fix_truncdfhi2"
4320   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4321                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4322               (clobber (reg:CC FLAGS_REG))])]
4323   "TARGET_80387 && !TARGET_SSE2"
4324   "")
4325
4326 (define_expand "fix_truncsfhi2"
4327   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4328                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4329                (clobber (reg:CC FLAGS_REG))])]
4330   "TARGET_80387 && !TARGET_SSE"
4331   "")
4332
4333 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4334 ;; of the machinery.
4335 (define_insn_and_split "*fix_trunchi_1"
4336   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4337         (fix:HI (match_operand 1 "register_operand" "f,f")))
4338    (clobber (reg:CC FLAGS_REG))]
4339   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4340    && !reload_completed && !reload_in_progress
4341    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4342   "#"
4343   "&& 1"
4344   [(const_int 0)]
4345 {
4346   ix86_optimize_mode_switching = 1;
4347   operands[2] = assign_386_stack_local (HImode, 1);
4348   operands[3] = assign_386_stack_local (HImode, 2);
4349   if (memory_operand (operands[0], VOIDmode))
4350     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4351                                        operands[2], operands[3]));
4352   else
4353     {
4354       operands[4] = assign_386_stack_local (HImode, 0);
4355       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4356                                            operands[2], operands[3],
4357                                            operands[4]));
4358     }
4359   DONE;
4360 }
4361   [(set_attr "type" "fistp")
4362    (set_attr "i387_cw" "trunc")
4363    (set_attr "mode" "HI")])
4364
4365 (define_insn "fix_trunchi_nomemory"
4366   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4367         (fix:HI (match_operand 1 "register_operand" "f,f")))
4368    (use (match_operand:HI 2 "memory_operand" "m,m"))
4369    (use (match_operand:HI 3 "memory_operand" "m,m"))
4370    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4371   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4372    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4373   "#"
4374   [(set_attr "type" "fistp")
4375    (set_attr "i387_cw" "trunc")
4376    (set_attr "mode" "HI")])
4377
4378 (define_insn "fix_trunchi_memory"
4379   [(set (match_operand:HI 0 "memory_operand" "=m")
4380         (fix:HI (match_operand 1 "register_operand" "f")))
4381    (use (match_operand:HI 2 "memory_operand" "m"))
4382    (use (match_operand:HI 3 "memory_operand" "m"))]
4383   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4384    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4385   "* return output_fix_trunc (insn, operands);"
4386   [(set_attr "type" "fistp")
4387    (set_attr "i387_cw" "trunc")
4388    (set_attr "mode" "HI")])
4389
4390 (define_split 
4391   [(set (match_operand:HI 0 "memory_operand" "")
4392         (fix:HI (match_operand 1 "register_operand" "")))
4393    (use (match_operand:HI 2 "memory_operand" ""))
4394    (use (match_operand:HI 3 "memory_operand" ""))
4395    (clobber (match_operand:HI 4 "memory_operand" ""))]
4396   "reload_completed"
4397   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4398               (use (match_dup 2))
4399               (use (match_dup 3))])]
4400   "")
4401
4402 (define_split 
4403   [(set (match_operand:HI 0 "register_operand" "")
4404         (fix:HI (match_operand 1 "register_operand" "")))
4405    (use (match_operand:HI 2 "memory_operand" ""))
4406    (use (match_operand:HI 3 "memory_operand" ""))
4407    (clobber (match_operand:HI 4 "memory_operand" ""))]
4408   "reload_completed"
4409   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4410               (use (match_dup 2))
4411               (use (match_dup 3))
4412               (clobber (match_dup 4))])
4413    (set (match_dup 0) (match_dup 4))]
4414   "")
4415
4416 (define_insn "x86_fnstcw_1"
4417   [(set (match_operand:HI 0 "memory_operand" "=m")
4418         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4419   "TARGET_80387"
4420   "fnstcw\t%0"
4421   [(set_attr "length" "2")
4422    (set_attr "mode" "HI")
4423    (set_attr "unit" "i387")])
4424
4425 (define_insn "x86_fldcw_1"
4426   [(set (reg:HI FPSR_REG)
4427         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4428   "TARGET_80387"
4429   "fldcw\t%0"
4430   [(set_attr "length" "2")
4431    (set_attr "mode" "HI")
4432    (set_attr "unit" "i387")
4433    (set_attr "athlon_decode" "vector")])
4434 \f
4435 ;; Conversion between fixed point and floating point.
4436
4437 ;; Even though we only accept memory inputs, the backend _really_
4438 ;; wants to be able to do this between registers.
4439
4440 (define_expand "floathisf2"
4441   [(set (match_operand:SF 0 "register_operand" "")
4442         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4443   "TARGET_80387 || TARGET_SSE_MATH"
4444 {
4445   if (TARGET_SSE_MATH)
4446     {
4447       emit_insn (gen_floatsisf2 (operands[0],
4448                                  convert_to_mode (SImode, operands[1], 0)));
4449       DONE;
4450     }
4451 })
4452
4453 (define_insn "*floathisf2_i387"
4454   [(set (match_operand:SF 0 "register_operand" "=f,f")
4455         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4456   "TARGET_80387 && !TARGET_SSE_MATH"
4457   "@
4458    fild%z1\t%1
4459    #"
4460   [(set_attr "type" "fmov,multi")
4461    (set_attr "mode" "SF")
4462    (set_attr "fp_int_src" "true")])
4463
4464 (define_expand "floatsisf2"
4465   [(set (match_operand:SF 0 "register_operand" "")
4466         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4467   "TARGET_80387 || TARGET_SSE_MATH"
4468   "")
4469
4470 (define_insn "*floatsisf2_mixed"
4471   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4472         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4473   "TARGET_MIX_SSE_I387"
4474   "@
4475    fild%z1\t%1
4476    #
4477    cvtsi2ss\t{%1, %0|%0, %1}
4478    cvtsi2ss\t{%1, %0|%0, %1}"
4479   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4480    (set_attr "mode" "SF")
4481    (set_attr "athlon_decode" "*,*,vector,double")
4482    (set_attr "fp_int_src" "true")])
4483
4484 (define_insn "*floatsisf2_sse"
4485   [(set (match_operand:SF 0 "register_operand" "=x,x")
4486         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4487   "TARGET_SSE_MATH"
4488   "cvtsi2ss\t{%1, %0|%0, %1}"
4489   [(set_attr "type" "sseicvt")
4490    (set_attr "mode" "SF")
4491    (set_attr "athlon_decode" "vector,double")
4492    (set_attr "fp_int_src" "true")])
4493
4494 ; Avoid possible reformatting penalty on the destination by first
4495 ; zeroing it out
4496 (define_split
4497   [(set (match_operand:SF 0 "register_operand" "")
4498         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4499   "reload_completed
4500    && TARGET_SSE_MATH && TARGET_SSE_PARTIAL_REGS
4501    && SSE_REG_P (operands[0])"
4502   [(const_int 0)]
4503 {
4504   rtx dest;
4505   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4506   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4507   emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4508   DONE;
4509 })
4510
4511 (define_insn "*floatsisf2_i387"
4512   [(set (match_operand:SF 0 "register_operand" "=f,f")
4513         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4514   "TARGET_80387"
4515   "@
4516    fild%z1\t%1
4517    #"
4518   [(set_attr "type" "fmov,multi")
4519    (set_attr "mode" "SF")
4520    (set_attr "fp_int_src" "true")])
4521
4522 (define_expand "floatdisf2"
4523   [(set (match_operand:SF 0 "register_operand" "")
4524         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4525   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4526   "")
4527
4528 (define_insn "*floatdisf2_mixed"
4529   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4530         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4531   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4532   "@
4533    fild%z1\t%1
4534    #
4535    cvtsi2ss{q}\t{%1, %0|%0, %1}
4536    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4537   [(set_attr "type" "fmov,multi,sseicvt,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_sse"
4543   [(set (match_operand:SF 0 "register_operand" "=x,x")
4544         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4545   "TARGET_64BIT && TARGET_SSE_MATH"
4546   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4547   [(set_attr "type" "sseicvt")
4548    (set_attr "mode" "SF")
4549    (set_attr "athlon_decode" "vector,double")
4550    (set_attr "fp_int_src" "true")])
4551
4552 ; Avoid possible reformatting penalty on the destination by first
4553 ; zeroing it out
4554 (define_split
4555   [(set (match_operand:SF 0 "register_operand" "")
4556         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4557   "reload_completed
4558    && TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE_PARTIAL_REGS
4559    && SSE_REG_P (operands[0])"
4560   [(const_int 0)]
4561 {
4562   rtx dest;
4563   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4564   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4565   emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4566   DONE;
4567 })
4568
4569 (define_insn "*floatdisf2_i387"
4570   [(set (match_operand:SF 0 "register_operand" "=f,f")
4571         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4572   "TARGET_80387"
4573   "@
4574    fild%z1\t%1
4575    #"
4576   [(set_attr "type" "fmov,multi")
4577    (set_attr "mode" "SF")
4578    (set_attr "fp_int_src" "true")])
4579
4580 (define_expand "floathidf2"
4581   [(set (match_operand:DF 0 "register_operand" "")
4582         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4583   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4584 {
4585   if (TARGET_SSE2 && TARGET_SSE_MATH)
4586     {
4587       emit_insn (gen_floatsidf2 (operands[0],
4588                                  convert_to_mode (SImode, operands[1], 0)));
4589       DONE;
4590     }
4591 })
4592
4593 (define_insn "*floathidf2_i387"
4594   [(set (match_operand:DF 0 "register_operand" "=f,f")
4595         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4596   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
4597   "@
4598    fild%z1\t%1
4599    #"
4600   [(set_attr "type" "fmov,multi")
4601    (set_attr "mode" "DF")
4602    (set_attr "fp_int_src" "true")])
4603
4604 (define_expand "floatsidf2"
4605   [(set (match_operand:DF 0 "register_operand" "")
4606         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4607   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4608   "")
4609
4610 (define_insn "*floatsidf2_mixed"
4611   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4612         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4613   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4614   "@
4615    fild%z1\t%1
4616    #
4617    cvtsi2sd\t{%1, %0|%0, %1}
4618    cvtsi2sd\t{%1, %0|%0, %1}"
4619   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4620    (set_attr "mode" "DF")
4621    (set_attr "athlon_decode" "*,*,double,direct")
4622    (set_attr "fp_int_src" "true")])
4623
4624 (define_insn "*floatsidf2_sse"
4625   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4626         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4627   "TARGET_SSE2 && TARGET_SSE_MATH"
4628   "cvtsi2sd\t{%1, %0|%0, %1}"
4629   [(set_attr "type" "sseicvt")
4630    (set_attr "mode" "DF")
4631    (set_attr "athlon_decode" "double,direct")
4632    (set_attr "fp_int_src" "true")])
4633
4634 (define_insn "*floatsidf2_i387"
4635   [(set (match_operand:DF 0 "register_operand" "=f,f")
4636         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4637   "TARGET_80387"
4638   "@
4639    fild%z1\t%1
4640    #"
4641   [(set_attr "type" "fmov,multi")
4642    (set_attr "mode" "DF")
4643    (set_attr "fp_int_src" "true")])
4644
4645 (define_expand "floatdidf2"
4646   [(set (match_operand:DF 0 "register_operand" "")
4647         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4648   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4649   "")
4650
4651 (define_insn "*floatdidf2_mixed"
4652   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4653         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4654   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4655   "@
4656    fild%z1\t%1
4657    #
4658    cvtsi2sd{q}\t{%1, %0|%0, %1}
4659    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4660   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4661    (set_attr "mode" "DF")
4662    (set_attr "athlon_decode" "*,*,double,direct")
4663    (set_attr "fp_int_src" "true")])
4664
4665 (define_insn "*floatdidf2_sse"
4666   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4667         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4668   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4669   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4670   [(set_attr "type" "sseicvt")
4671    (set_attr "mode" "DF")
4672    (set_attr "athlon_decode" "double,direct")
4673    (set_attr "fp_int_src" "true")])
4674
4675 (define_insn "*floatdidf2_i387"
4676   [(set (match_operand:DF 0 "register_operand" "=f,f")
4677         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4678   "TARGET_80387"
4679   "@
4680    fild%z1\t%1
4681    #"
4682   [(set_attr "type" "fmov,multi")
4683    (set_attr "mode" "DF")
4684    (set_attr "fp_int_src" "true")])
4685
4686 (define_insn "floathixf2"
4687   [(set (match_operand:XF 0 "register_operand" "=f,f")
4688         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4689   "TARGET_80387"
4690   "@
4691    fild%z1\t%1
4692    #"
4693   [(set_attr "type" "fmov,multi")
4694    (set_attr "mode" "XF")
4695    (set_attr "fp_int_src" "true")])
4696
4697 (define_insn "floatsixf2"
4698   [(set (match_operand:XF 0 "register_operand" "=f,f")
4699         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4700   "TARGET_80387"
4701   "@
4702    fild%z1\t%1
4703    #"
4704   [(set_attr "type" "fmov,multi")
4705    (set_attr "mode" "XF")
4706    (set_attr "fp_int_src" "true")])
4707
4708 (define_insn "floatdixf2"
4709   [(set (match_operand:XF 0 "register_operand" "=f,f")
4710         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4711   "TARGET_80387"
4712   "@
4713    fild%z1\t%1
4714    #"
4715   [(set_attr "type" "fmov,multi")
4716    (set_attr "mode" "XF")
4717    (set_attr "fp_int_src" "true")])
4718
4719 ;; %%% Kill these when reload knows how to do it.
4720 (define_split
4721   [(set (match_operand 0 "fp_register_operand" "")
4722         (float (match_operand 1 "register_operand" "")))]
4723   "reload_completed
4724    && TARGET_80387
4725    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4726   [(const_int 0)]
4727 {
4728   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4729   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4730   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4731   ix86_free_from_memory (GET_MODE (operands[1]));
4732   DONE;
4733 })
4734
4735 (define_expand "floatunssisf2"
4736   [(use (match_operand:SF 0 "register_operand" ""))
4737    (use (match_operand:SI 1 "register_operand" ""))]
4738   "!TARGET_64BIT && TARGET_SSE_MATH"
4739   "x86_emit_floatuns (operands); DONE;")
4740
4741 (define_expand "floatunsdisf2"
4742   [(use (match_operand:SF 0 "register_operand" ""))
4743    (use (match_operand:DI 1 "register_operand" ""))]
4744   "TARGET_64BIT && TARGET_SSE_MATH"
4745   "x86_emit_floatuns (operands); DONE;")
4746
4747 (define_expand "floatunsdidf2"
4748   [(use (match_operand:DF 0 "register_operand" ""))
4749    (use (match_operand:DI 1 "register_operand" ""))]
4750   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4751   "x86_emit_floatuns (operands); DONE;")
4752 \f
4753 ;; SSE extract/set expanders
4754
4755 (define_expand "vec_setv2df"
4756   [(match_operand:V2DF 0 "register_operand" "")
4757    (match_operand:DF 1 "register_operand" "")
4758    (match_operand 2 "const_int_operand" "")]
4759   "TARGET_SSE2"
4760 {
4761   switch (INTVAL (operands[2]))
4762     {
4763     case 0:
4764       emit_insn (gen_sse2_movsd (operands[0], operands[0],
4765                                  simplify_gen_subreg (V2DFmode, operands[1],
4766                                                       DFmode, 0)));
4767       break;
4768     case 1:
4769       {
4770         rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4771
4772         emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4773       }
4774       break;
4775     default:
4776       abort ();
4777     }
4778   DONE;
4779 })
4780
4781 (define_expand "vec_extractv2df"
4782   [(match_operand:DF 0 "register_operand" "")
4783    (match_operand:V2DF 1 "register_operand" "")
4784    (match_operand 2 "const_int_operand" "")]
4785   "TARGET_SSE2"
4786 {
4787   switch (INTVAL (operands[2]))
4788     {
4789     case 0:
4790       emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4791       break;
4792     case 1:
4793       {
4794         rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4795
4796         emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4797       }
4798       break;
4799     default:
4800       abort ();
4801     }
4802   DONE;
4803 })
4804
4805 (define_expand "vec_initv2df"
4806   [(match_operand:V2DF 0 "register_operand" "")
4807    (match_operand 1 "" "")]
4808   "TARGET_SSE2"
4809 {
4810   ix86_expand_vector_init (operands[0], operands[1]);
4811   DONE;
4812 })
4813
4814 (define_expand "vec_setv4sf"
4815   [(match_operand:V4SF 0 "register_operand" "")
4816    (match_operand:SF 1 "register_operand" "")
4817    (match_operand 2 "const_int_operand" "")]
4818   "TARGET_SSE"
4819 {
4820   switch (INTVAL (operands[2]))
4821     {
4822     case 0:
4823       emit_insn (gen_sse_movss (operands[0], operands[0],
4824                                 simplify_gen_subreg (V4SFmode, operands[1],
4825                                                      SFmode, 0)));
4826       break;
4827     case 1:
4828       {
4829         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4830         rtx tmp = gen_reg_rtx (V4SFmode);
4831  
4832         emit_move_insn (tmp, operands[0]);
4833         emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4834         emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4835         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4836                                    GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4837       }
4838       break;
4839     case 2:
4840       {
4841         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4842         rtx tmp = gen_reg_rtx (V4SFmode);
4843
4844         emit_move_insn (tmp, operands[0]);
4845         emit_insn (gen_sse_movss (tmp, tmp, op1));
4846         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4847                                    GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4848       }
4849       break;
4850     case 3:
4851       {
4852         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4853         rtx tmp = gen_reg_rtx (V4SFmode);
4854
4855         emit_move_insn (tmp, operands[0]);
4856         emit_insn (gen_sse_movss (tmp, tmp, op1));
4857         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4858                                    GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4859       }
4860       break;
4861     default:
4862       abort ();
4863     }
4864   DONE;
4865 })
4866
4867 (define_expand "vec_extractv4sf"
4868   [(match_operand:SF 0 "register_operand" "")
4869    (match_operand:V4SF 1 "register_operand" "")
4870    (match_operand 2 "const_int_operand" "")]
4871   "TARGET_SSE"
4872 {
4873   switch (INTVAL (operands[2]))
4874     {
4875     case 0:
4876       emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4877       break;
4878     case 1:
4879       {
4880         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4881         rtx tmp = gen_reg_rtx (V4SFmode);
4882  
4883         emit_move_insn (tmp, operands[1]);
4884         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4885                                    const1_rtx));
4886       }
4887       break;
4888     case 2:
4889       {
4890         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4891         rtx tmp = gen_reg_rtx (V4SFmode);
4892  
4893         emit_move_insn (tmp, operands[1]);
4894         emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4895       }
4896       break;
4897     case 3:
4898       {
4899         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4900         rtx tmp = gen_reg_rtx (V4SFmode);
4901  
4902         emit_move_insn (tmp, operands[1]);
4903         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4904                                    GEN_INT (3)));
4905       }
4906       break;
4907     default:
4908       abort ();
4909     }
4910   DONE;
4911 })
4912
4913 (define_expand "vec_initv4sf"
4914   [(match_operand:V4SF 0 "register_operand" "")
4915    (match_operand 1 "" "")]
4916   "TARGET_SSE"
4917 {
4918   ix86_expand_vector_init (operands[0], operands[1]);
4919   DONE;
4920 })
4921 \f
4922 ;; Add instructions
4923
4924 ;; %%% splits for addsidi3
4925 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4926 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4927 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4928
4929 (define_expand "adddi3"
4930   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4931         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4932                  (match_operand:DI 2 "x86_64_general_operand" "")))
4933    (clobber (reg:CC FLAGS_REG))]
4934   ""
4935   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4936
4937 (define_insn "*adddi3_1"
4938   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4939         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4940                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4941    (clobber (reg:CC FLAGS_REG))]
4942   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4943   "#")
4944
4945 (define_split
4946   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4947         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4948                  (match_operand:DI 2 "general_operand" "")))
4949    (clobber (reg:CC FLAGS_REG))]
4950   "!TARGET_64BIT && reload_completed"
4951   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4952                                           UNSPEC_ADD_CARRY))
4953               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4954    (parallel [(set (match_dup 3)
4955                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4956                                      (match_dup 4))
4957                             (match_dup 5)))
4958               (clobber (reg:CC FLAGS_REG))])]
4959   "split_di (operands+0, 1, operands+0, operands+3);
4960    split_di (operands+1, 1, operands+1, operands+4);
4961    split_di (operands+2, 1, operands+2, operands+5);")
4962
4963 (define_insn "adddi3_carry_rex64"
4964   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4965           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4966                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4967                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4968    (clobber (reg:CC FLAGS_REG))]
4969   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4970   "adc{q}\t{%2, %0|%0, %2}"
4971   [(set_attr "type" "alu")
4972    (set_attr "pent_pair" "pu")
4973    (set_attr "mode" "DI")])
4974
4975 (define_insn "*adddi3_cc_rex64"
4976   [(set (reg:CC FLAGS_REG)
4977         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4978                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4979                    UNSPEC_ADD_CARRY))
4980    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4981         (plus:DI (match_dup 1) (match_dup 2)))]
4982   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4983   "add{q}\t{%2, %0|%0, %2}"
4984   [(set_attr "type" "alu")
4985    (set_attr "mode" "DI")])
4986
4987 (define_insn "addqi3_carry"
4988   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4989           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4990                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4991                    (match_operand:QI 2 "general_operand" "qi,qm")))
4992    (clobber (reg:CC FLAGS_REG))]
4993   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4994   "adc{b}\t{%2, %0|%0, %2}"
4995   [(set_attr "type" "alu")
4996    (set_attr "pent_pair" "pu")
4997    (set_attr "mode" "QI")])
4998
4999 (define_insn "addhi3_carry"
5000   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5001           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5002                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5003                    (match_operand:HI 2 "general_operand" "ri,rm")))
5004    (clobber (reg:CC FLAGS_REG))]
5005   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5006   "adc{w}\t{%2, %0|%0, %2}"
5007   [(set_attr "type" "alu")
5008    (set_attr "pent_pair" "pu")
5009    (set_attr "mode" "HI")])
5010
5011 (define_insn "addsi3_carry"
5012   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5013           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5014                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5015                    (match_operand:SI 2 "general_operand" "ri,rm")))
5016    (clobber (reg:CC FLAGS_REG))]
5017   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5018   "adc{l}\t{%2, %0|%0, %2}"
5019   [(set_attr "type" "alu")
5020    (set_attr "pent_pair" "pu")
5021    (set_attr "mode" "SI")])
5022
5023 (define_insn "*addsi3_carry_zext"
5024   [(set (match_operand:DI 0 "register_operand" "=r")
5025           (zero_extend:DI 
5026             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5027                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5028                      (match_operand:SI 2 "general_operand" "rim"))))
5029    (clobber (reg:CC FLAGS_REG))]
5030   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5031   "adc{l}\t{%2, %k0|%k0, %2}"
5032   [(set_attr "type" "alu")
5033    (set_attr "pent_pair" "pu")
5034    (set_attr "mode" "SI")])
5035
5036 (define_insn "*addsi3_cc"
5037   [(set (reg:CC FLAGS_REG)
5038         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5039                     (match_operand:SI 2 "general_operand" "ri,rm")]
5040                    UNSPEC_ADD_CARRY))
5041    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5042         (plus:SI (match_dup 1) (match_dup 2)))]
5043   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5044   "add{l}\t{%2, %0|%0, %2}"
5045   [(set_attr "type" "alu")
5046    (set_attr "mode" "SI")])
5047
5048 (define_insn "addqi3_cc"
5049   [(set (reg:CC FLAGS_REG)
5050         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5051                     (match_operand:QI 2 "general_operand" "qi,qm")]
5052                    UNSPEC_ADD_CARRY))
5053    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5054         (plus:QI (match_dup 1) (match_dup 2)))]
5055   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5056   "add{b}\t{%2, %0|%0, %2}"
5057   [(set_attr "type" "alu")
5058    (set_attr "mode" "QI")])
5059
5060 (define_expand "addsi3"
5061   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5062                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5063                             (match_operand:SI 2 "general_operand" "")))
5064               (clobber (reg:CC FLAGS_REG))])]
5065   ""
5066   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5067
5068 (define_insn "*lea_1"
5069   [(set (match_operand:SI 0 "register_operand" "=r")
5070         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5071   "!TARGET_64BIT"
5072   "lea{l}\t{%a1, %0|%0, %a1}"
5073   [(set_attr "type" "lea")
5074    (set_attr "mode" "SI")])
5075
5076 (define_insn "*lea_1_rex64"
5077   [(set (match_operand:SI 0 "register_operand" "=r")
5078         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5079   "TARGET_64BIT"
5080   "lea{l}\t{%a1, %0|%0, %a1}"
5081   [(set_attr "type" "lea")
5082    (set_attr "mode" "SI")])
5083
5084 (define_insn "*lea_1_zext"
5085   [(set (match_operand:DI 0 "register_operand" "=r")
5086         (zero_extend:DI
5087          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5088   "TARGET_64BIT"
5089   "lea{l}\t{%a1, %k0|%k0, %a1}"
5090   [(set_attr "type" "lea")
5091    (set_attr "mode" "SI")])
5092
5093 (define_insn "*lea_2_rex64"
5094   [(set (match_operand:DI 0 "register_operand" "=r")
5095         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5096   "TARGET_64BIT"
5097   "lea{q}\t{%a1, %0|%0, %a1}"
5098   [(set_attr "type" "lea")
5099    (set_attr "mode" "DI")])
5100
5101 ;; The lea patterns for non-Pmodes needs to be matched by several
5102 ;; insns converted to real lea by splitters.
5103
5104 (define_insn_and_split "*lea_general_1"
5105   [(set (match_operand 0 "register_operand" "=r")
5106         (plus (plus (match_operand 1 "index_register_operand" "l")
5107                     (match_operand 2 "register_operand" "r"))
5108               (match_operand 3 "immediate_operand" "i")))]
5109   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5110     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5111    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5112    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5113    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5114    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5115        || GET_MODE (operands[3]) == VOIDmode)"
5116   "#"
5117   "&& reload_completed"
5118   [(const_int 0)]
5119 {
5120   rtx pat;
5121   operands[0] = gen_lowpart (SImode, operands[0]);
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   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5126                       operands[3]);
5127   if (Pmode != SImode)
5128     pat = gen_rtx_SUBREG (SImode, pat, 0);
5129   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5130   DONE;
5131 }
5132   [(set_attr "type" "lea")
5133    (set_attr "mode" "SI")])
5134
5135 (define_insn_and_split "*lea_general_1_zext"
5136   [(set (match_operand:DI 0 "register_operand" "=r")
5137         (zero_extend:DI
5138           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5139                             (match_operand:SI 2 "register_operand" "r"))
5140                    (match_operand:SI 3 "immediate_operand" "i"))))]
5141   "TARGET_64BIT"
5142   "#"
5143   "&& reload_completed"
5144   [(set (match_dup 0)
5145         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5146                                                      (match_dup 2))
5147                                             (match_dup 3)) 0)))]
5148 {
5149   operands[1] = gen_lowpart (Pmode, operands[1]);
5150   operands[2] = gen_lowpart (Pmode, operands[2]);
5151   operands[3] = gen_lowpart (Pmode, operands[3]);
5152 }
5153   [(set_attr "type" "lea")
5154    (set_attr "mode" "SI")])
5155
5156 (define_insn_and_split "*lea_general_2"
5157   [(set (match_operand 0 "register_operand" "=r")
5158         (plus (mult (match_operand 1 "index_register_operand" "l")
5159                     (match_operand 2 "const248_operand" "i"))
5160               (match_operand 3 "nonmemory_operand" "ri")))]
5161   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5162     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5163    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5164    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5165    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5166        || GET_MODE (operands[3]) == VOIDmode)"
5167   "#"
5168   "&& reload_completed"
5169   [(const_int 0)]
5170 {
5171   rtx pat;
5172   operands[0] = gen_lowpart (SImode, operands[0]);
5173   operands[1] = gen_lowpart (Pmode, operands[1]);
5174   operands[3] = gen_lowpart (Pmode, operands[3]);
5175   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5176                       operands[3]);
5177   if (Pmode != SImode)
5178     pat = gen_rtx_SUBREG (SImode, pat, 0);
5179   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5180   DONE;
5181 }
5182   [(set_attr "type" "lea")
5183    (set_attr "mode" "SI")])
5184
5185 (define_insn_and_split "*lea_general_2_zext"
5186   [(set (match_operand:DI 0 "register_operand" "=r")
5187         (zero_extend:DI
5188           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5189                             (match_operand:SI 2 "const248_operand" "n"))
5190                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5191   "TARGET_64BIT"
5192   "#"
5193   "&& reload_completed"
5194   [(set (match_dup 0)
5195         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5196                                                      (match_dup 2))
5197                                             (match_dup 3)) 0)))]
5198 {
5199   operands[1] = gen_lowpart (Pmode, operands[1]);
5200   operands[3] = gen_lowpart (Pmode, operands[3]);
5201 }
5202   [(set_attr "type" "lea")
5203    (set_attr "mode" "SI")])
5204
5205 (define_insn_and_split "*lea_general_3"
5206   [(set (match_operand 0 "register_operand" "=r")
5207         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5208                           (match_operand 2 "const248_operand" "i"))
5209                     (match_operand 3 "register_operand" "r"))
5210               (match_operand 4 "immediate_operand" "i")))]
5211   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5212     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5213    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5214    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5215    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5216   "#"
5217   "&& reload_completed"
5218   [(const_int 0)]
5219 {
5220   rtx pat;
5221   operands[0] = gen_lowpart (SImode, operands[0]);
5222   operands[1] = gen_lowpart (Pmode, operands[1]);
5223   operands[3] = gen_lowpart (Pmode, operands[3]);
5224   operands[4] = gen_lowpart (Pmode, operands[4]);
5225   pat = gen_rtx_PLUS (Pmode,
5226                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5227                                                          operands[2]),
5228                                     operands[3]),
5229                       operands[4]);
5230   if (Pmode != SImode)
5231     pat = gen_rtx_SUBREG (SImode, pat, 0);
5232   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5233   DONE;
5234 }
5235   [(set_attr "type" "lea")
5236    (set_attr "mode" "SI")])
5237
5238 (define_insn_and_split "*lea_general_3_zext"
5239   [(set (match_operand:DI 0 "register_operand" "=r")
5240         (zero_extend:DI
5241           (plus:SI (plus:SI (mult:SI
5242                               (match_operand:SI 1 "index_register_operand" "l")
5243                               (match_operand:SI 2 "const248_operand" "n"))
5244                             (match_operand:SI 3 "register_operand" "r"))
5245                    (match_operand:SI 4 "immediate_operand" "i"))))]
5246   "TARGET_64BIT"
5247   "#"
5248   "&& reload_completed"
5249   [(set (match_dup 0)
5250         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5251                                                               (match_dup 2))
5252                                                      (match_dup 3))
5253                                             (match_dup 4)) 0)))]
5254 {
5255   operands[1] = gen_lowpart (Pmode, operands[1]);
5256   operands[3] = gen_lowpart (Pmode, operands[3]);
5257   operands[4] = gen_lowpart (Pmode, operands[4]);
5258 }
5259   [(set_attr "type" "lea")
5260    (set_attr "mode" "SI")])
5261
5262 (define_insn "*adddi_1_rex64"
5263   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5264         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5265                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5266    (clobber (reg:CC FLAGS_REG))]
5267   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5268 {
5269   switch (get_attr_type (insn))
5270     {
5271     case TYPE_LEA:
5272       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5273       return "lea{q}\t{%a2, %0|%0, %a2}";
5274
5275     case TYPE_INCDEC:
5276       if (! rtx_equal_p (operands[0], operands[1]))
5277         abort ();
5278       if (operands[2] == const1_rtx)
5279         return "inc{q}\t%0";
5280       else if (operands[2] == constm1_rtx)
5281         return "dec{q}\t%0";
5282       else
5283         abort ();
5284
5285     default:
5286       if (! rtx_equal_p (operands[0], operands[1]))
5287         abort ();
5288
5289       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5290          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5291       if (GET_CODE (operands[2]) == CONST_INT
5292           /* Avoid overflows.  */
5293           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5294           && (INTVAL (operands[2]) == 128
5295               || (INTVAL (operands[2]) < 0
5296                   && INTVAL (operands[2]) != -128)))
5297         {
5298           operands[2] = GEN_INT (-INTVAL (operands[2]));
5299           return "sub{q}\t{%2, %0|%0, %2}";
5300         }
5301       return "add{q}\t{%2, %0|%0, %2}";
5302     }
5303 }
5304   [(set (attr "type")
5305      (cond [(eq_attr "alternative" "2")
5306               (const_string "lea")
5307             ; Current assemblers are broken and do not allow @GOTOFF in
5308             ; ought but a memory context.
5309             (match_operand:DI 2 "pic_symbolic_operand" "")
5310               (const_string "lea")
5311             (match_operand:DI 2 "incdec_operand" "")
5312               (const_string "incdec")
5313            ]
5314            (const_string "alu")))
5315    (set_attr "mode" "DI")])
5316
5317 ;; Convert lea to the lea pattern to avoid flags dependency.
5318 (define_split
5319   [(set (match_operand:DI 0 "register_operand" "")
5320         (plus:DI (match_operand:DI 1 "register_operand" "")
5321                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5322    (clobber (reg:CC FLAGS_REG))]
5323   "TARGET_64BIT && reload_completed
5324    && true_regnum (operands[0]) != true_regnum (operands[1])"
5325   [(set (match_dup 0)
5326         (plus:DI (match_dup 1)
5327                  (match_dup 2)))]
5328   "")
5329
5330 (define_insn "*adddi_2_rex64"
5331   [(set (reg FLAGS_REG)
5332         (compare
5333           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5334                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5335           (const_int 0)))                       
5336    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5337         (plus:DI (match_dup 1) (match_dup 2)))]
5338   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5339    && ix86_binary_operator_ok (PLUS, DImode, operands)
5340    /* Current assemblers are broken and do not allow @GOTOFF in
5341       ought but a memory context.  */
5342    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5343 {
5344   switch (get_attr_type (insn))
5345     {
5346     case TYPE_INCDEC:
5347       if (! rtx_equal_p (operands[0], operands[1]))
5348         abort ();
5349       if (operands[2] == const1_rtx)
5350         return "inc{q}\t%0";
5351       else if (operands[2] == constm1_rtx)
5352         return "dec{q}\t%0";
5353       else
5354         abort ();
5355
5356     default:
5357       if (! rtx_equal_p (operands[0], operands[1]))
5358         abort ();
5359       /* ???? We ought to handle there the 32bit case too
5360          - do we need new constraint?  */
5361       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5362          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5363       if (GET_CODE (operands[2]) == CONST_INT
5364           /* Avoid overflows.  */
5365           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5366           && (INTVAL (operands[2]) == 128
5367               || (INTVAL (operands[2]) < 0
5368                   && INTVAL (operands[2]) != -128)))
5369         {
5370           operands[2] = GEN_INT (-INTVAL (operands[2]));
5371           return "sub{q}\t{%2, %0|%0, %2}";
5372         }
5373       return "add{q}\t{%2, %0|%0, %2}";
5374     }
5375 }
5376   [(set (attr "type")
5377      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5378         (const_string "incdec")
5379         (const_string "alu")))
5380    (set_attr "mode" "DI")])
5381
5382 (define_insn "*adddi_3_rex64"
5383   [(set (reg FLAGS_REG)
5384         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5385                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5386    (clobber (match_scratch:DI 0 "=r"))]
5387   "TARGET_64BIT
5388    && ix86_match_ccmode (insn, CCZmode)
5389    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5390    /* Current assemblers are broken and do not allow @GOTOFF in
5391       ought but a memory context.  */
5392    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5393 {
5394   switch (get_attr_type (insn))
5395     {
5396     case TYPE_INCDEC:
5397       if (! rtx_equal_p (operands[0], operands[1]))
5398         abort ();
5399       if (operands[2] == const1_rtx)
5400         return "inc{q}\t%0";
5401       else if (operands[2] == constm1_rtx)
5402         return "dec{q}\t%0";
5403       else
5404         abort ();
5405
5406     default:
5407       if (! rtx_equal_p (operands[0], operands[1]))
5408         abort ();
5409       /* ???? We ought to handle there the 32bit case too
5410          - do we need new constraint?  */
5411       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5412          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5413       if (GET_CODE (operands[2]) == CONST_INT
5414           /* Avoid overflows.  */
5415           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5416           && (INTVAL (operands[2]) == 128
5417               || (INTVAL (operands[2]) < 0
5418                   && INTVAL (operands[2]) != -128)))
5419         {
5420           operands[2] = GEN_INT (-INTVAL (operands[2]));
5421           return "sub{q}\t{%2, %0|%0, %2}";
5422         }
5423       return "add{q}\t{%2, %0|%0, %2}";
5424     }
5425 }
5426   [(set (attr "type")
5427      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5428         (const_string "incdec")
5429         (const_string "alu")))
5430    (set_attr "mode" "DI")])
5431
5432 ; For comparisons against 1, -1 and 128, we may generate better code
5433 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5434 ; is matched then.  We can't accept general immediate, because for
5435 ; case of overflows,  the result is messed up.
5436 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5437 ; when negated.
5438 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5439 ; only for comparisons not depending on it.
5440 (define_insn "*adddi_4_rex64"
5441   [(set (reg FLAGS_REG)
5442         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5443                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5444    (clobber (match_scratch:DI 0 "=rm"))]
5445   "TARGET_64BIT
5446    &&  ix86_match_ccmode (insn, CCGCmode)"
5447 {
5448   switch (get_attr_type (insn))
5449     {
5450     case TYPE_INCDEC:
5451       if (operands[2] == constm1_rtx)
5452         return "inc{q}\t%0";
5453       else if (operands[2] == const1_rtx)
5454         return "dec{q}\t%0";
5455       else
5456         abort();
5457
5458     default:
5459       if (! rtx_equal_p (operands[0], operands[1]))
5460         abort ();
5461       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5462          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5463       if ((INTVAL (operands[2]) == -128
5464            || (INTVAL (operands[2]) > 0
5465                && INTVAL (operands[2]) != 128))
5466           /* Avoid overflows.  */
5467           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5468         return "sub{q}\t{%2, %0|%0, %2}";
5469       operands[2] = GEN_INT (-INTVAL (operands[2]));
5470       return "add{q}\t{%2, %0|%0, %2}";
5471     }
5472 }
5473   [(set (attr "type")
5474      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5475         (const_string "incdec")
5476         (const_string "alu")))
5477    (set_attr "mode" "DI")])
5478
5479 (define_insn "*adddi_5_rex64"
5480   [(set (reg FLAGS_REG)
5481         (compare
5482           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5483                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5484           (const_int 0)))                       
5485    (clobber (match_scratch:DI 0 "=r"))]
5486   "TARGET_64BIT
5487    && ix86_match_ccmode (insn, CCGOCmode)
5488    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5489    /* Current assemblers are broken and do not allow @GOTOFF in
5490       ought but a memory context.  */
5491    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5492 {
5493   switch (get_attr_type (insn))
5494     {
5495     case TYPE_INCDEC:
5496       if (! rtx_equal_p (operands[0], operands[1]))
5497         abort ();
5498       if (operands[2] == const1_rtx)
5499         return "inc{q}\t%0";
5500       else if (operands[2] == constm1_rtx)
5501         return "dec{q}\t%0";
5502       else
5503         abort();
5504
5505     default:
5506       if (! rtx_equal_p (operands[0], operands[1]))
5507         abort ();
5508       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5509          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5510       if (GET_CODE (operands[2]) == CONST_INT
5511           /* Avoid overflows.  */
5512           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5513           && (INTVAL (operands[2]) == 128
5514               || (INTVAL (operands[2]) < 0
5515                   && INTVAL (operands[2]) != -128)))
5516         {
5517           operands[2] = GEN_INT (-INTVAL (operands[2]));
5518           return "sub{q}\t{%2, %0|%0, %2}";
5519         }
5520       return "add{q}\t{%2, %0|%0, %2}";
5521     }
5522 }
5523   [(set (attr "type")
5524      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5525         (const_string "incdec")
5526         (const_string "alu")))
5527    (set_attr "mode" "DI")])
5528
5529
5530 (define_insn "*addsi_1"
5531   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5532         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5533                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5534    (clobber (reg:CC FLAGS_REG))]
5535   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5536 {
5537   switch (get_attr_type (insn))
5538     {
5539     case TYPE_LEA:
5540       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5541       return "lea{l}\t{%a2, %0|%0, %a2}";
5542
5543     case TYPE_INCDEC:
5544       if (! rtx_equal_p (operands[0], operands[1]))
5545         abort ();
5546       if (operands[2] == const1_rtx)
5547         return "inc{l}\t%0";
5548       else if (operands[2] == constm1_rtx)
5549         return "dec{l}\t%0";
5550       else
5551         abort();
5552
5553     default:
5554       if (! rtx_equal_p (operands[0], operands[1]))
5555         abort ();
5556
5557       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5558          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5559       if (GET_CODE (operands[2]) == CONST_INT
5560           && (INTVAL (operands[2]) == 128
5561               || (INTVAL (operands[2]) < 0
5562                   && INTVAL (operands[2]) != -128)))
5563         {
5564           operands[2] = GEN_INT (-INTVAL (operands[2]));
5565           return "sub{l}\t{%2, %0|%0, %2}";
5566         }
5567       return "add{l}\t{%2, %0|%0, %2}";
5568     }
5569 }
5570   [(set (attr "type")
5571      (cond [(eq_attr "alternative" "2")
5572               (const_string "lea")
5573             ; Current assemblers are broken and do not allow @GOTOFF in
5574             ; ought but a memory context.
5575             (match_operand:SI 2 "pic_symbolic_operand" "")
5576               (const_string "lea")
5577             (match_operand:SI 2 "incdec_operand" "")
5578               (const_string "incdec")
5579            ]
5580            (const_string "alu")))
5581    (set_attr "mode" "SI")])
5582
5583 ;; Convert lea to the lea pattern to avoid flags dependency.
5584 (define_split
5585   [(set (match_operand 0 "register_operand" "")
5586         (plus (match_operand 1 "register_operand" "")
5587               (match_operand 2 "nonmemory_operand" "")))
5588    (clobber (reg:CC FLAGS_REG))]
5589   "reload_completed
5590    && true_regnum (operands[0]) != true_regnum (operands[1])"
5591   [(const_int 0)]
5592 {
5593   rtx pat;
5594   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5595      may confuse gen_lowpart.  */
5596   if (GET_MODE (operands[0]) != Pmode)
5597     {
5598       operands[1] = gen_lowpart (Pmode, operands[1]);
5599       operands[2] = gen_lowpart (Pmode, operands[2]);
5600     }
5601   operands[0] = gen_lowpart (SImode, operands[0]);
5602   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5603   if (Pmode != SImode)
5604     pat = gen_rtx_SUBREG (SImode, pat, 0);
5605   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5606   DONE;
5607 })
5608
5609 ;; It may seem that nonimmediate operand is proper one for operand 1.
5610 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5611 ;; we take care in ix86_binary_operator_ok to not allow two memory
5612 ;; operands so proper swapping will be done in reload.  This allow
5613 ;; patterns constructed from addsi_1 to match.
5614 (define_insn "addsi_1_zext"
5615   [(set (match_operand:DI 0 "register_operand" "=r,r")
5616         (zero_extend:DI
5617           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5618                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5619    (clobber (reg:CC FLAGS_REG))]
5620   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5621 {
5622   switch (get_attr_type (insn))
5623     {
5624     case TYPE_LEA:
5625       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5626       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5627
5628     case TYPE_INCDEC:
5629       if (operands[2] == const1_rtx)
5630         return "inc{l}\t%k0";
5631       else if (operands[2] == constm1_rtx)
5632         return "dec{l}\t%k0";
5633       else
5634         abort();
5635
5636     default:
5637       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5638          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5639       if (GET_CODE (operands[2]) == CONST_INT
5640           && (INTVAL (operands[2]) == 128
5641               || (INTVAL (operands[2]) < 0
5642                   && INTVAL (operands[2]) != -128)))
5643         {
5644           operands[2] = GEN_INT (-INTVAL (operands[2]));
5645           return "sub{l}\t{%2, %k0|%k0, %2}";
5646         }
5647       return "add{l}\t{%2, %k0|%k0, %2}";
5648     }
5649 }
5650   [(set (attr "type")
5651      (cond [(eq_attr "alternative" "1")
5652               (const_string "lea")
5653             ; Current assemblers are broken and do not allow @GOTOFF in
5654             ; ought but a memory context.
5655             (match_operand:SI 2 "pic_symbolic_operand" "")
5656               (const_string "lea")
5657             (match_operand:SI 2 "incdec_operand" "")
5658               (const_string "incdec")
5659            ]
5660            (const_string "alu")))
5661    (set_attr "mode" "SI")])
5662
5663 ;; Convert lea to the lea pattern to avoid flags dependency.
5664 (define_split
5665   [(set (match_operand:DI 0 "register_operand" "")
5666         (zero_extend:DI
5667           (plus:SI (match_operand:SI 1 "register_operand" "")
5668                    (match_operand:SI 2 "nonmemory_operand" ""))))
5669    (clobber (reg:CC FLAGS_REG))]
5670   "TARGET_64BIT && reload_completed
5671    && true_regnum (operands[0]) != true_regnum (operands[1])"
5672   [(set (match_dup 0)
5673         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5674 {
5675   operands[1] = gen_lowpart (Pmode, operands[1]);
5676   operands[2] = gen_lowpart (Pmode, operands[2]);
5677 })
5678
5679 (define_insn "*addsi_2"
5680   [(set (reg FLAGS_REG)
5681         (compare
5682           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5683                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5684           (const_int 0)))                       
5685    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5686         (plus:SI (match_dup 1) (match_dup 2)))]
5687   "ix86_match_ccmode (insn, CCGOCmode)
5688    && ix86_binary_operator_ok (PLUS, SImode, operands)
5689    /* Current assemblers are broken and do not allow @GOTOFF in
5690       ought but a memory context.  */
5691    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5692 {
5693   switch (get_attr_type (insn))
5694     {
5695     case TYPE_INCDEC:
5696       if (! rtx_equal_p (operands[0], operands[1]))
5697         abort ();
5698       if (operands[2] == const1_rtx)
5699         return "inc{l}\t%0";
5700       else if (operands[2] == constm1_rtx)
5701         return "dec{l}\t%0";
5702       else
5703         abort();
5704
5705     default:
5706       if (! rtx_equal_p (operands[0], operands[1]))
5707         abort ();
5708       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5709          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5710       if (GET_CODE (operands[2]) == CONST_INT
5711           && (INTVAL (operands[2]) == 128
5712               || (INTVAL (operands[2]) < 0
5713                   && INTVAL (operands[2]) != -128)))
5714         {
5715           operands[2] = GEN_INT (-INTVAL (operands[2]));
5716           return "sub{l}\t{%2, %0|%0, %2}";
5717         }
5718       return "add{l}\t{%2, %0|%0, %2}";
5719     }
5720 }
5721   [(set (attr "type")
5722      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5723         (const_string "incdec")
5724         (const_string "alu")))
5725    (set_attr "mode" "SI")])
5726
5727 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5728 (define_insn "*addsi_2_zext"
5729   [(set (reg FLAGS_REG)
5730         (compare
5731           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5732                    (match_operand:SI 2 "general_operand" "rmni"))
5733           (const_int 0)))                       
5734    (set (match_operand:DI 0 "register_operand" "=r")
5735         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5736   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5737    && ix86_binary_operator_ok (PLUS, SImode, operands)
5738    /* Current assemblers are broken and do not allow @GOTOFF in
5739       ought but a memory context.  */
5740    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5741 {
5742   switch (get_attr_type (insn))
5743     {
5744     case TYPE_INCDEC:
5745       if (operands[2] == const1_rtx)
5746         return "inc{l}\t%k0";
5747       else if (operands[2] == constm1_rtx)
5748         return "dec{l}\t%k0";
5749       else
5750         abort();
5751
5752     default:
5753       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5754          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5755       if (GET_CODE (operands[2]) == CONST_INT
5756           && (INTVAL (operands[2]) == 128
5757               || (INTVAL (operands[2]) < 0
5758                   && INTVAL (operands[2]) != -128)))
5759         {
5760           operands[2] = GEN_INT (-INTVAL (operands[2]));
5761           return "sub{l}\t{%2, %k0|%k0, %2}";
5762         }
5763       return "add{l}\t{%2, %k0|%k0, %2}";
5764     }
5765 }
5766   [(set (attr "type")
5767      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5768         (const_string "incdec")
5769         (const_string "alu")))
5770    (set_attr "mode" "SI")])
5771
5772 (define_insn "*addsi_3"
5773   [(set (reg FLAGS_REG)
5774         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5775                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5776    (clobber (match_scratch:SI 0 "=r"))]
5777   "ix86_match_ccmode (insn, CCZmode)
5778    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5779    /* Current assemblers are broken and do not allow @GOTOFF in
5780       ought but a memory context.  */
5781    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5782 {
5783   switch (get_attr_type (insn))
5784     {
5785     case TYPE_INCDEC:
5786       if (! rtx_equal_p (operands[0], operands[1]))
5787         abort ();
5788       if (operands[2] == const1_rtx)
5789         return "inc{l}\t%0";
5790       else if (operands[2] == constm1_rtx)
5791         return "dec{l}\t%0";
5792       else
5793         abort();
5794
5795     default:
5796       if (! rtx_equal_p (operands[0], operands[1]))
5797         abort ();
5798       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5799          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5800       if (GET_CODE (operands[2]) == CONST_INT
5801           && (INTVAL (operands[2]) == 128
5802               || (INTVAL (operands[2]) < 0
5803                   && INTVAL (operands[2]) != -128)))
5804         {
5805           operands[2] = GEN_INT (-INTVAL (operands[2]));
5806           return "sub{l}\t{%2, %0|%0, %2}";
5807         }
5808       return "add{l}\t{%2, %0|%0, %2}";
5809     }
5810 }
5811   [(set (attr "type")
5812      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5813         (const_string "incdec")
5814         (const_string "alu")))
5815    (set_attr "mode" "SI")])
5816
5817 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5818 (define_insn "*addsi_3_zext"
5819   [(set (reg FLAGS_REG)
5820         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5821                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5822    (set (match_operand:DI 0 "register_operand" "=r")
5823         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5824   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5825    && ix86_binary_operator_ok (PLUS, SImode, operands)
5826    /* Current assemblers are broken and do not allow @GOTOFF in
5827       ought but a memory context.  */
5828    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5829 {
5830   switch (get_attr_type (insn))
5831     {
5832     case TYPE_INCDEC:
5833       if (operands[2] == const1_rtx)
5834         return "inc{l}\t%k0";
5835       else if (operands[2] == constm1_rtx)
5836         return "dec{l}\t%k0";
5837       else
5838         abort();
5839
5840     default:
5841       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5842          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5843       if (GET_CODE (operands[2]) == CONST_INT
5844           && (INTVAL (operands[2]) == 128
5845               || (INTVAL (operands[2]) < 0
5846                   && INTVAL (operands[2]) != -128)))
5847         {
5848           operands[2] = GEN_INT (-INTVAL (operands[2]));
5849           return "sub{l}\t{%2, %k0|%k0, %2}";
5850         }
5851       return "add{l}\t{%2, %k0|%k0, %2}";
5852     }
5853 }
5854   [(set (attr "type")
5855      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5856         (const_string "incdec")
5857         (const_string "alu")))
5858    (set_attr "mode" "SI")])
5859
5860 ; For comparisons against 1, -1 and 128, we may generate better code
5861 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5862 ; is matched then.  We can't accept general immediate, because for
5863 ; case of overflows,  the result is messed up.
5864 ; This pattern also don't hold of 0x80000000, since the value overflows
5865 ; when negated.
5866 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5867 ; only for comparisons not depending on it.
5868 (define_insn "*addsi_4"
5869   [(set (reg FLAGS_REG)
5870         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5871                  (match_operand:SI 2 "const_int_operand" "n")))
5872    (clobber (match_scratch:SI 0 "=rm"))]
5873   "ix86_match_ccmode (insn, CCGCmode)
5874    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5875 {
5876   switch (get_attr_type (insn))
5877     {
5878     case TYPE_INCDEC:
5879       if (operands[2] == constm1_rtx)
5880         return "inc{l}\t%0";
5881       else if (operands[2] == const1_rtx)
5882         return "dec{l}\t%0";
5883       else
5884         abort();
5885
5886     default:
5887       if (! rtx_equal_p (operands[0], operands[1]))
5888         abort ();
5889       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5890          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5891       if ((INTVAL (operands[2]) == -128
5892            || (INTVAL (operands[2]) > 0
5893                && INTVAL (operands[2]) != 128)))
5894         return "sub{l}\t{%2, %0|%0, %2}";
5895       operands[2] = GEN_INT (-INTVAL (operands[2]));
5896       return "add{l}\t{%2, %0|%0, %2}";
5897     }
5898 }
5899   [(set (attr "type")
5900      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5901         (const_string "incdec")
5902         (const_string "alu")))
5903    (set_attr "mode" "SI")])
5904
5905 (define_insn "*addsi_5"
5906   [(set (reg FLAGS_REG)
5907         (compare
5908           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5909                    (match_operand:SI 2 "general_operand" "rmni"))
5910           (const_int 0)))                       
5911    (clobber (match_scratch:SI 0 "=r"))]
5912   "ix86_match_ccmode (insn, CCGOCmode)
5913    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5914    /* Current assemblers are broken and do not allow @GOTOFF in
5915       ought but a memory context.  */
5916    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5917 {
5918   switch (get_attr_type (insn))
5919     {
5920     case TYPE_INCDEC:
5921       if (! rtx_equal_p (operands[0], operands[1]))
5922         abort ();
5923       if (operands[2] == const1_rtx)
5924         return "inc{l}\t%0";
5925       else if (operands[2] == constm1_rtx)
5926         return "dec{l}\t%0";
5927       else
5928         abort();
5929
5930     default:
5931       if (! rtx_equal_p (operands[0], operands[1]))
5932         abort ();
5933       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5934          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5935       if (GET_CODE (operands[2]) == CONST_INT
5936           && (INTVAL (operands[2]) == 128
5937               || (INTVAL (operands[2]) < 0
5938                   && INTVAL (operands[2]) != -128)))
5939         {
5940           operands[2] = GEN_INT (-INTVAL (operands[2]));
5941           return "sub{l}\t{%2, %0|%0, %2}";
5942         }
5943       return "add{l}\t{%2, %0|%0, %2}";
5944     }
5945 }
5946   [(set (attr "type")
5947      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5948         (const_string "incdec")
5949         (const_string "alu")))
5950    (set_attr "mode" "SI")])
5951
5952 (define_expand "addhi3"
5953   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5954                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5955                             (match_operand:HI 2 "general_operand" "")))
5956               (clobber (reg:CC FLAGS_REG))])]
5957   "TARGET_HIMODE_MATH"
5958   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5959
5960 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5961 ;; type optimizations enabled by define-splits.  This is not important
5962 ;; for PII, and in fact harmful because of partial register stalls.
5963
5964 (define_insn "*addhi_1_lea"
5965   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5966         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5967                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5968    (clobber (reg:CC FLAGS_REG))]
5969   "!TARGET_PARTIAL_REG_STALL
5970    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5971 {
5972   switch (get_attr_type (insn))
5973     {
5974     case TYPE_LEA:
5975       return "#";
5976     case TYPE_INCDEC:
5977       if (operands[2] == const1_rtx)
5978         return "inc{w}\t%0";
5979       else if (operands[2] == constm1_rtx)
5980         return "dec{w}\t%0";
5981       abort();
5982
5983     default:
5984       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5985          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5986       if (GET_CODE (operands[2]) == CONST_INT
5987           && (INTVAL (operands[2]) == 128
5988               || (INTVAL (operands[2]) < 0
5989                   && INTVAL (operands[2]) != -128)))
5990         {
5991           operands[2] = GEN_INT (-INTVAL (operands[2]));
5992           return "sub{w}\t{%2, %0|%0, %2}";
5993         }
5994       return "add{w}\t{%2, %0|%0, %2}";
5995     }
5996 }
5997   [(set (attr "type")
5998      (if_then_else (eq_attr "alternative" "2")
5999         (const_string "lea")
6000         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6001            (const_string "incdec")
6002            (const_string "alu"))))
6003    (set_attr "mode" "HI,HI,SI")])
6004
6005 (define_insn "*addhi_1"
6006   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6007         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6008                  (match_operand:HI 2 "general_operand" "ri,rm")))
6009    (clobber (reg:CC FLAGS_REG))]
6010   "TARGET_PARTIAL_REG_STALL
6011    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6012 {
6013   switch (get_attr_type (insn))
6014     {
6015     case TYPE_INCDEC:
6016       if (operands[2] == const1_rtx)
6017         return "inc{w}\t%0";
6018       else if (operands[2] == constm1_rtx)
6019         return "dec{w}\t%0";
6020       abort();
6021
6022     default:
6023       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6024          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6025       if (GET_CODE (operands[2]) == CONST_INT
6026           && (INTVAL (operands[2]) == 128
6027               || (INTVAL (operands[2]) < 0
6028                   && INTVAL (operands[2]) != -128)))
6029         {
6030           operands[2] = GEN_INT (-INTVAL (operands[2]));
6031           return "sub{w}\t{%2, %0|%0, %2}";
6032         }
6033       return "add{w}\t{%2, %0|%0, %2}";
6034     }
6035 }
6036   [(set (attr "type")
6037      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6038         (const_string "incdec")
6039         (const_string "alu")))
6040    (set_attr "mode" "HI")])
6041
6042 (define_insn "*addhi_2"
6043   [(set (reg FLAGS_REG)
6044         (compare
6045           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6046                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6047           (const_int 0)))                       
6048    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6049         (plus:HI (match_dup 1) (match_dup 2)))]
6050   "ix86_match_ccmode (insn, CCGOCmode)
6051    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6052 {
6053   switch (get_attr_type (insn))
6054     {
6055     case TYPE_INCDEC:
6056       if (operands[2] == const1_rtx)
6057         return "inc{w}\t%0";
6058       else if (operands[2] == constm1_rtx)
6059         return "dec{w}\t%0";
6060       abort();
6061
6062     default:
6063       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6064          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6065       if (GET_CODE (operands[2]) == CONST_INT
6066           && (INTVAL (operands[2]) == 128
6067               || (INTVAL (operands[2]) < 0
6068                   && INTVAL (operands[2]) != -128)))
6069         {
6070           operands[2] = GEN_INT (-INTVAL (operands[2]));
6071           return "sub{w}\t{%2, %0|%0, %2}";
6072         }
6073       return "add{w}\t{%2, %0|%0, %2}";
6074     }
6075 }
6076   [(set (attr "type")
6077      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6078         (const_string "incdec")
6079         (const_string "alu")))
6080    (set_attr "mode" "HI")])
6081
6082 (define_insn "*addhi_3"
6083   [(set (reg FLAGS_REG)
6084         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6085                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6086    (clobber (match_scratch:HI 0 "=r"))]
6087   "ix86_match_ccmode (insn, CCZmode)
6088    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6089 {
6090   switch (get_attr_type (insn))
6091     {
6092     case TYPE_INCDEC:
6093       if (operands[2] == const1_rtx)
6094         return "inc{w}\t%0";
6095       else if (operands[2] == constm1_rtx)
6096         return "dec{w}\t%0";
6097       abort();
6098
6099     default:
6100       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6101          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6102       if (GET_CODE (operands[2]) == CONST_INT
6103           && (INTVAL (operands[2]) == 128
6104               || (INTVAL (operands[2]) < 0
6105                   && INTVAL (operands[2]) != -128)))
6106         {
6107           operands[2] = GEN_INT (-INTVAL (operands[2]));
6108           return "sub{w}\t{%2, %0|%0, %2}";
6109         }
6110       return "add{w}\t{%2, %0|%0, %2}";
6111     }
6112 }
6113   [(set (attr "type")
6114      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6115         (const_string "incdec")
6116         (const_string "alu")))
6117    (set_attr "mode" "HI")])
6118
6119 ; See comments above addsi_3_imm for details.
6120 (define_insn "*addhi_4"
6121   [(set (reg FLAGS_REG)
6122         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6123                  (match_operand:HI 2 "const_int_operand" "n")))
6124    (clobber (match_scratch:HI 0 "=rm"))]
6125   "ix86_match_ccmode (insn, CCGCmode)
6126    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6127 {
6128   switch (get_attr_type (insn))
6129     {
6130     case TYPE_INCDEC:
6131       if (operands[2] == constm1_rtx)
6132         return "inc{w}\t%0";
6133       else if (operands[2] == const1_rtx)
6134         return "dec{w}\t%0";
6135       else
6136         abort();
6137
6138     default:
6139       if (! rtx_equal_p (operands[0], operands[1]))
6140         abort ();
6141       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6142          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6143       if ((INTVAL (operands[2]) == -128
6144            || (INTVAL (operands[2]) > 0
6145                && INTVAL (operands[2]) != 128)))
6146         return "sub{w}\t{%2, %0|%0, %2}";
6147       operands[2] = GEN_INT (-INTVAL (operands[2]));
6148       return "add{w}\t{%2, %0|%0, %2}";
6149     }
6150 }
6151   [(set (attr "type")
6152      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6153         (const_string "incdec")
6154         (const_string "alu")))
6155    (set_attr "mode" "SI")])
6156
6157
6158 (define_insn "*addhi_5"
6159   [(set (reg FLAGS_REG)
6160         (compare
6161           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6162                    (match_operand:HI 2 "general_operand" "rmni"))
6163           (const_int 0)))                       
6164    (clobber (match_scratch:HI 0 "=r"))]
6165   "ix86_match_ccmode (insn, CCGOCmode)
6166    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6167 {
6168   switch (get_attr_type (insn))
6169     {
6170     case TYPE_INCDEC:
6171       if (operands[2] == const1_rtx)
6172         return "inc{w}\t%0";
6173       else if (operands[2] == constm1_rtx)
6174         return "dec{w}\t%0";
6175       abort();
6176
6177     default:
6178       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6179          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6180       if (GET_CODE (operands[2]) == CONST_INT
6181           && (INTVAL (operands[2]) == 128
6182               || (INTVAL (operands[2]) < 0
6183                   && INTVAL (operands[2]) != -128)))
6184         {
6185           operands[2] = GEN_INT (-INTVAL (operands[2]));
6186           return "sub{w}\t{%2, %0|%0, %2}";
6187         }
6188       return "add{w}\t{%2, %0|%0, %2}";
6189     }
6190 }
6191   [(set (attr "type")
6192      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6193         (const_string "incdec")
6194         (const_string "alu")))
6195    (set_attr "mode" "HI")])
6196
6197 (define_expand "addqi3"
6198   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6199                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6200                             (match_operand:QI 2 "general_operand" "")))
6201               (clobber (reg:CC FLAGS_REG))])]
6202   "TARGET_QIMODE_MATH"
6203   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6204
6205 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6206 (define_insn "*addqi_1_lea"
6207   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6208         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6209                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6210    (clobber (reg:CC FLAGS_REG))]
6211   "!TARGET_PARTIAL_REG_STALL
6212    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6213 {
6214   int widen = (which_alternative == 2);
6215   switch (get_attr_type (insn))
6216     {
6217     case TYPE_LEA:
6218       return "#";
6219     case TYPE_INCDEC:
6220       if (operands[2] == const1_rtx)
6221         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6222       else if (operands[2] == constm1_rtx)
6223         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6224       abort();
6225
6226     default:
6227       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6228          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6229       if (GET_CODE (operands[2]) == CONST_INT
6230           && (INTVAL (operands[2]) == 128
6231               || (INTVAL (operands[2]) < 0
6232                   && INTVAL (operands[2]) != -128)))
6233         {
6234           operands[2] = GEN_INT (-INTVAL (operands[2]));
6235           if (widen)
6236             return "sub{l}\t{%2, %k0|%k0, %2}";
6237           else
6238             return "sub{b}\t{%2, %0|%0, %2}";
6239         }
6240       if (widen)
6241         return "add{l}\t{%k2, %k0|%k0, %k2}";
6242       else
6243         return "add{b}\t{%2, %0|%0, %2}";
6244     }
6245 }
6246   [(set (attr "type")
6247      (if_then_else (eq_attr "alternative" "3")
6248         (const_string "lea")
6249         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6250            (const_string "incdec")
6251            (const_string "alu"))))
6252    (set_attr "mode" "QI,QI,SI,SI")])
6253
6254 (define_insn "*addqi_1"
6255   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6256         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6257                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6258    (clobber (reg:CC FLAGS_REG))]
6259   "TARGET_PARTIAL_REG_STALL
6260    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6261 {
6262   int widen = (which_alternative == 2);
6263   switch (get_attr_type (insn))
6264     {
6265     case TYPE_INCDEC:
6266       if (operands[2] == const1_rtx)
6267         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6268       else if (operands[2] == constm1_rtx)
6269         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6270       abort();
6271
6272     default:
6273       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6274          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6275       if (GET_CODE (operands[2]) == CONST_INT
6276           && (INTVAL (operands[2]) == 128
6277               || (INTVAL (operands[2]) < 0
6278                   && INTVAL (operands[2]) != -128)))
6279         {
6280           operands[2] = GEN_INT (-INTVAL (operands[2]));
6281           if (widen)
6282             return "sub{l}\t{%2, %k0|%k0, %2}";
6283           else
6284             return "sub{b}\t{%2, %0|%0, %2}";
6285         }
6286       if (widen)
6287         return "add{l}\t{%k2, %k0|%k0, %k2}";
6288       else
6289         return "add{b}\t{%2, %0|%0, %2}";
6290     }
6291 }
6292   [(set (attr "type")
6293      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6294         (const_string "incdec")
6295         (const_string "alu")))
6296    (set_attr "mode" "QI,QI,SI")])
6297
6298 (define_insn "*addqi_1_slp"
6299   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6300         (plus:QI (match_dup 0)
6301                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6302    (clobber (reg:CC FLAGS_REG))]
6303   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6304    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6305 {
6306   switch (get_attr_type (insn))
6307     {
6308     case TYPE_INCDEC:
6309       if (operands[1] == const1_rtx)
6310         return "inc{b}\t%0";
6311       else if (operands[1] == constm1_rtx)
6312         return "dec{b}\t%0";
6313       abort();
6314
6315     default:
6316       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6317       if (GET_CODE (operands[1]) == CONST_INT
6318           && INTVAL (operands[1]) < 0)
6319         {
6320           operands[1] = GEN_INT (-INTVAL (operands[1]));
6321           return "sub{b}\t{%1, %0|%0, %1}";
6322         }
6323       return "add{b}\t{%1, %0|%0, %1}";
6324     }
6325 }
6326   [(set (attr "type")
6327      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6328         (const_string "incdec")
6329         (const_string "alu1")))
6330    (set_attr "mode" "QI")])
6331
6332 (define_insn "*addqi_2"
6333   [(set (reg FLAGS_REG)
6334         (compare
6335           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6336                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6337           (const_int 0)))
6338    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6339         (plus:QI (match_dup 1) (match_dup 2)))]
6340   "ix86_match_ccmode (insn, CCGOCmode)
6341    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6342 {
6343   switch (get_attr_type (insn))
6344     {
6345     case TYPE_INCDEC:
6346       if (operands[2] == const1_rtx)
6347         return "inc{b}\t%0";
6348       else if (operands[2] == constm1_rtx
6349                || (GET_CODE (operands[2]) == CONST_INT
6350                    && INTVAL (operands[2]) == 255))
6351         return "dec{b}\t%0";
6352       abort();
6353
6354     default:
6355       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6356       if (GET_CODE (operands[2]) == CONST_INT
6357           && INTVAL (operands[2]) < 0)
6358         {
6359           operands[2] = GEN_INT (-INTVAL (operands[2]));
6360           return "sub{b}\t{%2, %0|%0, %2}";
6361         }
6362       return "add{b}\t{%2, %0|%0, %2}";
6363     }
6364 }
6365   [(set (attr "type")
6366      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6367         (const_string "incdec")
6368         (const_string "alu")))
6369    (set_attr "mode" "QI")])
6370
6371 (define_insn "*addqi_3"
6372   [(set (reg FLAGS_REG)
6373         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6374                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6375    (clobber (match_scratch:QI 0 "=q"))]
6376   "ix86_match_ccmode (insn, CCZmode)
6377    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6378 {
6379   switch (get_attr_type (insn))
6380     {
6381     case TYPE_INCDEC:
6382       if (operands[2] == const1_rtx)
6383         return "inc{b}\t%0";
6384       else if (operands[2] == constm1_rtx
6385                || (GET_CODE (operands[2]) == CONST_INT
6386                    && INTVAL (operands[2]) == 255))
6387         return "dec{b}\t%0";
6388       abort();
6389
6390     default:
6391       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6392       if (GET_CODE (operands[2]) == CONST_INT
6393           && INTVAL (operands[2]) < 0)
6394         {
6395           operands[2] = GEN_INT (-INTVAL (operands[2]));
6396           return "sub{b}\t{%2, %0|%0, %2}";
6397         }
6398       return "add{b}\t{%2, %0|%0, %2}";
6399     }
6400 }
6401   [(set (attr "type")
6402      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6403         (const_string "incdec")
6404         (const_string "alu")))
6405    (set_attr "mode" "QI")])
6406
6407 ; See comments above addsi_3_imm for details.
6408 (define_insn "*addqi_4"
6409   [(set (reg FLAGS_REG)
6410         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6411                  (match_operand:QI 2 "const_int_operand" "n")))
6412    (clobber (match_scratch:QI 0 "=qm"))]
6413   "ix86_match_ccmode (insn, CCGCmode)
6414    && (INTVAL (operands[2]) & 0xff) != 0x80"
6415 {
6416   switch (get_attr_type (insn))
6417     {
6418     case TYPE_INCDEC:
6419       if (operands[2] == constm1_rtx
6420           || (GET_CODE (operands[2]) == CONST_INT
6421               && INTVAL (operands[2]) == 255))
6422         return "inc{b}\t%0";
6423       else if (operands[2] == const1_rtx)
6424         return "dec{b}\t%0";
6425       else
6426         abort();
6427
6428     default:
6429       if (! rtx_equal_p (operands[0], operands[1]))
6430         abort ();
6431       if (INTVAL (operands[2]) < 0)
6432         {
6433           operands[2] = GEN_INT (-INTVAL (operands[2]));
6434           return "add{b}\t{%2, %0|%0, %2}";
6435         }
6436       return "sub{b}\t{%2, %0|%0, %2}";
6437     }
6438 }
6439   [(set (attr "type")
6440      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6441         (const_string "incdec")
6442         (const_string "alu")))
6443    (set_attr "mode" "QI")])
6444
6445
6446 (define_insn "*addqi_5"
6447   [(set (reg FLAGS_REG)
6448         (compare
6449           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6450                    (match_operand:QI 2 "general_operand" "qmni"))
6451           (const_int 0)))
6452    (clobber (match_scratch:QI 0 "=q"))]
6453   "ix86_match_ccmode (insn, CCGOCmode)
6454    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6455 {
6456   switch (get_attr_type (insn))
6457     {
6458     case TYPE_INCDEC:
6459       if (operands[2] == const1_rtx)
6460         return "inc{b}\t%0";
6461       else if (operands[2] == constm1_rtx
6462                || (GET_CODE (operands[2]) == CONST_INT
6463                    && INTVAL (operands[2]) == 255))
6464         return "dec{b}\t%0";
6465       abort();
6466
6467     default:
6468       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6469       if (GET_CODE (operands[2]) == CONST_INT
6470           && INTVAL (operands[2]) < 0)
6471         {
6472           operands[2] = GEN_INT (-INTVAL (operands[2]));
6473           return "sub{b}\t{%2, %0|%0, %2}";
6474         }
6475       return "add{b}\t{%2, %0|%0, %2}";
6476     }
6477 }
6478   [(set (attr "type")
6479      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6480         (const_string "incdec")
6481         (const_string "alu")))
6482    (set_attr "mode" "QI")])
6483
6484
6485 (define_insn "addqi_ext_1"
6486   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6487                          (const_int 8)
6488                          (const_int 8))
6489         (plus:SI
6490           (zero_extract:SI
6491             (match_operand 1 "ext_register_operand" "0")
6492             (const_int 8)
6493             (const_int 8))
6494           (match_operand:QI 2 "general_operand" "Qmn")))
6495    (clobber (reg:CC FLAGS_REG))]
6496   "!TARGET_64BIT"
6497 {
6498   switch (get_attr_type (insn))
6499     {
6500     case TYPE_INCDEC:
6501       if (operands[2] == const1_rtx)
6502         return "inc{b}\t%h0";
6503       else if (operands[2] == constm1_rtx
6504                || (GET_CODE (operands[2]) == CONST_INT
6505                    && INTVAL (operands[2]) == 255))
6506         return "dec{b}\t%h0";
6507       abort();
6508
6509     default:
6510       return "add{b}\t{%2, %h0|%h0, %2}";
6511     }
6512 }
6513   [(set (attr "type")
6514      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6515         (const_string "incdec")
6516         (const_string "alu")))
6517    (set_attr "mode" "QI")])
6518
6519 (define_insn "*addqi_ext_1_rex64"
6520   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6521                          (const_int 8)
6522                          (const_int 8))
6523         (plus:SI
6524           (zero_extract:SI
6525             (match_operand 1 "ext_register_operand" "0")
6526             (const_int 8)
6527             (const_int 8))
6528           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6529    (clobber (reg:CC FLAGS_REG))]
6530   "TARGET_64BIT"
6531 {
6532   switch (get_attr_type (insn))
6533     {
6534     case TYPE_INCDEC:
6535       if (operands[2] == const1_rtx)
6536         return "inc{b}\t%h0";
6537       else if (operands[2] == constm1_rtx
6538                || (GET_CODE (operands[2]) == CONST_INT
6539                    && INTVAL (operands[2]) == 255))
6540         return "dec{b}\t%h0";
6541       abort();
6542
6543     default:
6544       return "add{b}\t{%2, %h0|%h0, %2}";
6545     }
6546 }
6547   [(set (attr "type")
6548      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6549         (const_string "incdec")
6550         (const_string "alu")))
6551    (set_attr "mode" "QI")])
6552
6553 (define_insn "*addqi_ext_2"
6554   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6555                          (const_int 8)
6556                          (const_int 8))
6557         (plus:SI
6558           (zero_extract:SI
6559             (match_operand 1 "ext_register_operand" "%0")
6560             (const_int 8)
6561             (const_int 8))
6562           (zero_extract:SI
6563             (match_operand 2 "ext_register_operand" "Q")
6564             (const_int 8)
6565             (const_int 8))))
6566    (clobber (reg:CC FLAGS_REG))]
6567   ""
6568   "add{b}\t{%h2, %h0|%h0, %h2}"
6569   [(set_attr "type" "alu")
6570    (set_attr "mode" "QI")])
6571
6572 ;; The patterns that match these are at the end of this file.
6573
6574 (define_expand "addxf3"
6575   [(set (match_operand:XF 0 "register_operand" "")
6576         (plus:XF (match_operand:XF 1 "register_operand" "")
6577                  (match_operand:XF 2 "register_operand" "")))]
6578   "TARGET_80387"
6579   "")
6580
6581 (define_expand "adddf3"
6582   [(set (match_operand:DF 0 "register_operand" "")
6583         (plus:DF (match_operand:DF 1 "register_operand" "")
6584                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6585   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6586   "")
6587
6588 (define_expand "addsf3"
6589   [(set (match_operand:SF 0 "register_operand" "")
6590         (plus:SF (match_operand:SF 1 "register_operand" "")
6591                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6592   "TARGET_80387 || TARGET_SSE_MATH"
6593   "")
6594 \f
6595 ;; Subtract instructions
6596
6597 ;; %%% splits for subsidi3
6598
6599 (define_expand "subdi3"
6600   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6601                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6602                              (match_operand:DI 2 "x86_64_general_operand" "")))
6603               (clobber (reg:CC FLAGS_REG))])]
6604   ""
6605   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6606
6607 (define_insn "*subdi3_1"
6608   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6609         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6610                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6611    (clobber (reg:CC FLAGS_REG))]
6612   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6613   "#")
6614
6615 (define_split
6616   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6617         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6618                   (match_operand:DI 2 "general_operand" "")))
6619    (clobber (reg:CC FLAGS_REG))]
6620   "!TARGET_64BIT && reload_completed"
6621   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6622               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6623    (parallel [(set (match_dup 3)
6624                    (minus:SI (match_dup 4)
6625                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6626                                       (match_dup 5))))
6627               (clobber (reg:CC FLAGS_REG))])]
6628   "split_di (operands+0, 1, operands+0, operands+3);
6629    split_di (operands+1, 1, operands+1, operands+4);
6630    split_di (operands+2, 1, operands+2, operands+5);")
6631
6632 (define_insn "subdi3_carry_rex64"
6633   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6634           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6635             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6636                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6637    (clobber (reg:CC FLAGS_REG))]
6638   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6639   "sbb{q}\t{%2, %0|%0, %2}"
6640   [(set_attr "type" "alu")
6641    (set_attr "pent_pair" "pu")
6642    (set_attr "mode" "DI")])
6643
6644 (define_insn "*subdi_1_rex64"
6645   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6646         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6647                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6648    (clobber (reg:CC FLAGS_REG))]
6649   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6650   "sub{q}\t{%2, %0|%0, %2}"
6651   [(set_attr "type" "alu")
6652    (set_attr "mode" "DI")])
6653
6654 (define_insn "*subdi_2_rex64"
6655   [(set (reg FLAGS_REG)
6656         (compare
6657           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6658                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6659           (const_int 0)))
6660    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6661         (minus:DI (match_dup 1) (match_dup 2)))]
6662   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6663    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6664   "sub{q}\t{%2, %0|%0, %2}"
6665   [(set_attr "type" "alu")
6666    (set_attr "mode" "DI")])
6667
6668 (define_insn "*subdi_3_rex63"
6669   [(set (reg FLAGS_REG)
6670         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6671                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6672    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6673         (minus:DI (match_dup 1) (match_dup 2)))]
6674   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6675    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6676   "sub{q}\t{%2, %0|%0, %2}"
6677   [(set_attr "type" "alu")
6678    (set_attr "mode" "DI")])
6679
6680 (define_insn "subqi3_carry"
6681   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6682           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6683             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6684                (match_operand:QI 2 "general_operand" "qi,qm"))))
6685    (clobber (reg:CC FLAGS_REG))]
6686   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6687   "sbb{b}\t{%2, %0|%0, %2}"
6688   [(set_attr "type" "alu")
6689    (set_attr "pent_pair" "pu")
6690    (set_attr "mode" "QI")])
6691
6692 (define_insn "subhi3_carry"
6693   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6694           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6695             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6696                (match_operand:HI 2 "general_operand" "ri,rm"))))
6697    (clobber (reg:CC FLAGS_REG))]
6698   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6699   "sbb{w}\t{%2, %0|%0, %2}"
6700   [(set_attr "type" "alu")
6701    (set_attr "pent_pair" "pu")
6702    (set_attr "mode" "HI")])
6703
6704 (define_insn "subsi3_carry"
6705   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6706           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6707             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6708                (match_operand:SI 2 "general_operand" "ri,rm"))))
6709    (clobber (reg:CC FLAGS_REG))]
6710   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6711   "sbb{l}\t{%2, %0|%0, %2}"
6712   [(set_attr "type" "alu")
6713    (set_attr "pent_pair" "pu")
6714    (set_attr "mode" "SI")])
6715
6716 (define_insn "subsi3_carry_zext"
6717   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6718           (zero_extend:DI
6719             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6720               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6721                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6722    (clobber (reg:CC FLAGS_REG))]
6723   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6724   "sbb{l}\t{%2, %k0|%k0, %2}"
6725   [(set_attr "type" "alu")
6726    (set_attr "pent_pair" "pu")
6727    (set_attr "mode" "SI")])
6728
6729 (define_expand "subsi3"
6730   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6731                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6732                              (match_operand:SI 2 "general_operand" "")))
6733               (clobber (reg:CC FLAGS_REG))])]
6734   ""
6735   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6736
6737 (define_insn "*subsi_1"
6738   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6739         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6740                   (match_operand:SI 2 "general_operand" "ri,rm")))
6741    (clobber (reg:CC FLAGS_REG))]
6742   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6743   "sub{l}\t{%2, %0|%0, %2}"
6744   [(set_attr "type" "alu")
6745    (set_attr "mode" "SI")])
6746
6747 (define_insn "*subsi_1_zext"
6748   [(set (match_operand:DI 0 "register_operand" "=r")
6749         (zero_extend:DI
6750           (minus:SI (match_operand:SI 1 "register_operand" "0")
6751                     (match_operand:SI 2 "general_operand" "rim"))))
6752    (clobber (reg:CC FLAGS_REG))]
6753   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6754   "sub{l}\t{%2, %k0|%k0, %2}"
6755   [(set_attr "type" "alu")
6756    (set_attr "mode" "SI")])
6757
6758 (define_insn "*subsi_2"
6759   [(set (reg FLAGS_REG)
6760         (compare
6761           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6762                     (match_operand:SI 2 "general_operand" "ri,rm"))
6763           (const_int 0)))
6764    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6765         (minus:SI (match_dup 1) (match_dup 2)))]
6766   "ix86_match_ccmode (insn, CCGOCmode)
6767    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6768   "sub{l}\t{%2, %0|%0, %2}"
6769   [(set_attr "type" "alu")
6770    (set_attr "mode" "SI")])
6771
6772 (define_insn "*subsi_2_zext"
6773   [(set (reg FLAGS_REG)
6774         (compare
6775           (minus:SI (match_operand:SI 1 "register_operand" "0")
6776                     (match_operand:SI 2 "general_operand" "rim"))
6777           (const_int 0)))
6778    (set (match_operand:DI 0 "register_operand" "=r")
6779         (zero_extend:DI
6780           (minus:SI (match_dup 1)
6781                     (match_dup 2))))]
6782   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6783    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6784   "sub{l}\t{%2, %k0|%k0, %2}"
6785   [(set_attr "type" "alu")
6786    (set_attr "mode" "SI")])
6787
6788 (define_insn "*subsi_3"
6789   [(set (reg FLAGS_REG)
6790         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6791                  (match_operand:SI 2 "general_operand" "ri,rm")))
6792    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6793         (minus:SI (match_dup 1) (match_dup 2)))]
6794   "ix86_match_ccmode (insn, CCmode)
6795    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6796   "sub{l}\t{%2, %0|%0, %2}"
6797   [(set_attr "type" "alu")
6798    (set_attr "mode" "SI")])
6799
6800 (define_insn "*subsi_3_zext"
6801   [(set (reg FLAGS_REG)
6802         (compare (match_operand:SI 1 "register_operand" "0")
6803                  (match_operand:SI 2 "general_operand" "rim")))
6804    (set (match_operand:DI 0 "register_operand" "=r")
6805         (zero_extend:DI
6806           (minus:SI (match_dup 1)
6807                     (match_dup 2))))]
6808   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6809    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6810   "sub{q}\t{%2, %0|%0, %2}"
6811   [(set_attr "type" "alu")
6812    (set_attr "mode" "DI")])
6813
6814 (define_expand "subhi3"
6815   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6816                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6817                              (match_operand:HI 2 "general_operand" "")))
6818               (clobber (reg:CC FLAGS_REG))])]
6819   "TARGET_HIMODE_MATH"
6820   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6821
6822 (define_insn "*subhi_1"
6823   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6824         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6825                   (match_operand:HI 2 "general_operand" "ri,rm")))
6826    (clobber (reg:CC FLAGS_REG))]
6827   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6828   "sub{w}\t{%2, %0|%0, %2}"
6829   [(set_attr "type" "alu")
6830    (set_attr "mode" "HI")])
6831
6832 (define_insn "*subhi_2"
6833   [(set (reg FLAGS_REG)
6834         (compare
6835           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6836                     (match_operand:HI 2 "general_operand" "ri,rm"))
6837           (const_int 0)))
6838    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6839         (minus:HI (match_dup 1) (match_dup 2)))]
6840   "ix86_match_ccmode (insn, CCGOCmode)
6841    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6842   "sub{w}\t{%2, %0|%0, %2}"
6843   [(set_attr "type" "alu")
6844    (set_attr "mode" "HI")])
6845
6846 (define_insn "*subhi_3"
6847   [(set (reg FLAGS_REG)
6848         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6849                  (match_operand:HI 2 "general_operand" "ri,rm")))
6850    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6851         (minus:HI (match_dup 1) (match_dup 2)))]
6852   "ix86_match_ccmode (insn, CCmode)
6853    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6854   "sub{w}\t{%2, %0|%0, %2}"
6855   [(set_attr "type" "alu")
6856    (set_attr "mode" "HI")])
6857
6858 (define_expand "subqi3"
6859   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6860                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6861                              (match_operand:QI 2 "general_operand" "")))
6862               (clobber (reg:CC FLAGS_REG))])]
6863   "TARGET_QIMODE_MATH"
6864   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6865
6866 (define_insn "*subqi_1"
6867   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6868         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6869                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6870    (clobber (reg:CC FLAGS_REG))]
6871   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6872   "sub{b}\t{%2, %0|%0, %2}"
6873   [(set_attr "type" "alu")
6874    (set_attr "mode" "QI")])
6875
6876 (define_insn "*subqi_1_slp"
6877   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6878         (minus:QI (match_dup 0)
6879                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6880    (clobber (reg:CC FLAGS_REG))]
6881   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6882    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6883   "sub{b}\t{%1, %0|%0, %1}"
6884   [(set_attr "type" "alu1")
6885    (set_attr "mode" "QI")])
6886
6887 (define_insn "*subqi_2"
6888   [(set (reg FLAGS_REG)
6889         (compare
6890           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6891                     (match_operand:QI 2 "general_operand" "qi,qm"))
6892           (const_int 0)))
6893    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6894         (minus:HI (match_dup 1) (match_dup 2)))]
6895   "ix86_match_ccmode (insn, CCGOCmode)
6896    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6897   "sub{b}\t{%2, %0|%0, %2}"
6898   [(set_attr "type" "alu")
6899    (set_attr "mode" "QI")])
6900
6901 (define_insn "*subqi_3"
6902   [(set (reg FLAGS_REG)
6903         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6904                  (match_operand:QI 2 "general_operand" "qi,qm")))
6905    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6906         (minus:HI (match_dup 1) (match_dup 2)))]
6907   "ix86_match_ccmode (insn, CCmode)
6908    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6909   "sub{b}\t{%2, %0|%0, %2}"
6910   [(set_attr "type" "alu")
6911    (set_attr "mode" "QI")])
6912
6913 ;; The patterns that match these are at the end of this file.
6914
6915 (define_expand "subxf3"
6916   [(set (match_operand:XF 0 "register_operand" "")
6917         (minus:XF (match_operand:XF 1 "register_operand" "")
6918                   (match_operand:XF 2 "register_operand" "")))]
6919   "TARGET_80387"
6920   "")
6921
6922 (define_expand "subdf3"
6923   [(set (match_operand:DF 0 "register_operand" "")
6924         (minus:DF (match_operand:DF 1 "register_operand" "")
6925                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6926   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6927   "")
6928
6929 (define_expand "subsf3"
6930   [(set (match_operand:SF 0 "register_operand" "")
6931         (minus:SF (match_operand:SF 1 "register_operand" "")
6932                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6933   "TARGET_80387 || TARGET_SSE_MATH"
6934   "")
6935 \f
6936 ;; Multiply instructions
6937
6938 (define_expand "muldi3"
6939   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6940                    (mult:DI (match_operand:DI 1 "register_operand" "")
6941                             (match_operand:DI 2 "x86_64_general_operand" "")))
6942               (clobber (reg:CC FLAGS_REG))])]
6943   "TARGET_64BIT"
6944   "")
6945
6946 (define_insn "*muldi3_1_rex64"
6947   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6948         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6949                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6950    (clobber (reg:CC FLAGS_REG))]
6951   "TARGET_64BIT
6952    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6953   "@
6954    imul{q}\t{%2, %1, %0|%0, %1, %2}
6955    imul{q}\t{%2, %1, %0|%0, %1, %2}
6956    imul{q}\t{%2, %0|%0, %2}"
6957   [(set_attr "type" "imul")
6958    (set_attr "prefix_0f" "0,0,1")
6959    (set (attr "athlon_decode")
6960         (cond [(eq_attr "cpu" "athlon")
6961                   (const_string "vector")
6962                (eq_attr "alternative" "1")
6963                   (const_string "vector")
6964                (and (eq_attr "alternative" "2")
6965                     (match_operand 1 "memory_operand" ""))
6966                   (const_string "vector")]
6967               (const_string "direct")))
6968    (set_attr "mode" "DI")])
6969
6970 (define_expand "mulsi3"
6971   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6972                    (mult:SI (match_operand:SI 1 "register_operand" "")
6973                             (match_operand:SI 2 "general_operand" "")))
6974               (clobber (reg:CC FLAGS_REG))])]
6975   ""
6976   "")
6977
6978 (define_insn "*mulsi3_1"
6979   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6980         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6981                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6982    (clobber (reg:CC FLAGS_REG))]
6983   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6984   "@
6985    imul{l}\t{%2, %1, %0|%0, %1, %2}
6986    imul{l}\t{%2, %1, %0|%0, %1, %2}
6987    imul{l}\t{%2, %0|%0, %2}"
6988   [(set_attr "type" "imul")
6989    (set_attr "prefix_0f" "0,0,1")
6990    (set (attr "athlon_decode")
6991         (cond [(eq_attr "cpu" "athlon")
6992                   (const_string "vector")
6993                (eq_attr "alternative" "1")
6994                   (const_string "vector")
6995                (and (eq_attr "alternative" "2")
6996                     (match_operand 1 "memory_operand" ""))
6997                   (const_string "vector")]
6998               (const_string "direct")))
6999    (set_attr "mode" "SI")])
7000
7001 (define_insn "*mulsi3_1_zext"
7002   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7003         (zero_extend:DI
7004           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7005                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7006    (clobber (reg:CC FLAGS_REG))]
7007   "TARGET_64BIT
7008    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7009   "@
7010    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7011    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7012    imul{l}\t{%2, %k0|%k0, %2}"
7013   [(set_attr "type" "imul")
7014    (set_attr "prefix_0f" "0,0,1")
7015    (set (attr "athlon_decode")
7016         (cond [(eq_attr "cpu" "athlon")
7017                   (const_string "vector")
7018                (eq_attr "alternative" "1")
7019                   (const_string "vector")
7020                (and (eq_attr "alternative" "2")
7021                     (match_operand 1 "memory_operand" ""))
7022                   (const_string "vector")]
7023               (const_string "direct")))
7024    (set_attr "mode" "SI")])
7025
7026 (define_expand "mulhi3"
7027   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7028                    (mult:HI (match_operand:HI 1 "register_operand" "")
7029                             (match_operand:HI 2 "general_operand" "")))
7030               (clobber (reg:CC FLAGS_REG))])]
7031   "TARGET_HIMODE_MATH"
7032   "")
7033
7034 (define_insn "*mulhi3_1"
7035   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7036         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7037                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7038    (clobber (reg:CC FLAGS_REG))]
7039   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7040   "@
7041    imul{w}\t{%2, %1, %0|%0, %1, %2}
7042    imul{w}\t{%2, %1, %0|%0, %1, %2}
7043    imul{w}\t{%2, %0|%0, %2}"
7044   [(set_attr "type" "imul")
7045    (set_attr "prefix_0f" "0,0,1")
7046    (set (attr "athlon_decode")
7047         (cond [(eq_attr "cpu" "athlon")
7048                   (const_string "vector")
7049                (eq_attr "alternative" "1,2")
7050                   (const_string "vector")]
7051               (const_string "direct")))
7052    (set_attr "mode" "HI")])
7053
7054 (define_expand "mulqi3"
7055   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7056                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7057                             (match_operand:QI 2 "register_operand" "")))
7058               (clobber (reg:CC FLAGS_REG))])]
7059   "TARGET_QIMODE_MATH"
7060   "")
7061
7062 (define_insn "*mulqi3_1"
7063   [(set (match_operand:QI 0 "register_operand" "=a")
7064         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7065                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7066    (clobber (reg:CC FLAGS_REG))]
7067   "TARGET_QIMODE_MATH
7068    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7069   "mul{b}\t%2"
7070   [(set_attr "type" "imul")
7071    (set_attr "length_immediate" "0")
7072    (set (attr "athlon_decode")
7073      (if_then_else (eq_attr "cpu" "athlon")
7074         (const_string "vector")
7075         (const_string "direct")))
7076    (set_attr "mode" "QI")])
7077
7078 (define_expand "umulqihi3"
7079   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7080                    (mult:HI (zero_extend:HI
7081                               (match_operand:QI 1 "nonimmediate_operand" ""))
7082                             (zero_extend:HI
7083                               (match_operand:QI 2 "register_operand" ""))))
7084               (clobber (reg:CC FLAGS_REG))])]
7085   "TARGET_QIMODE_MATH"
7086   "")
7087
7088 (define_insn "*umulqihi3_1"
7089   [(set (match_operand:HI 0 "register_operand" "=a")
7090         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7091                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7092    (clobber (reg:CC FLAGS_REG))]
7093   "TARGET_QIMODE_MATH
7094    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7095   "mul{b}\t%2"
7096   [(set_attr "type" "imul")
7097    (set_attr "length_immediate" "0")
7098    (set (attr "athlon_decode")
7099      (if_then_else (eq_attr "cpu" "athlon")
7100         (const_string "vector")
7101         (const_string "direct")))
7102    (set_attr "mode" "QI")])
7103
7104 (define_expand "mulqihi3"
7105   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7106                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7107                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7108               (clobber (reg:CC FLAGS_REG))])]
7109   "TARGET_QIMODE_MATH"
7110   "")
7111
7112 (define_insn "*mulqihi3_insn"
7113   [(set (match_operand:HI 0 "register_operand" "=a")
7114         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7115                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7116    (clobber (reg:CC FLAGS_REG))]
7117   "TARGET_QIMODE_MATH
7118    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7119   "imul{b}\t%2"
7120   [(set_attr "type" "imul")
7121    (set_attr "length_immediate" "0")
7122    (set (attr "athlon_decode")
7123      (if_then_else (eq_attr "cpu" "athlon")
7124         (const_string "vector")
7125         (const_string "direct")))
7126    (set_attr "mode" "QI")])
7127
7128 (define_expand "umulditi3"
7129   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7130                    (mult:TI (zero_extend:TI
7131                               (match_operand:DI 1 "nonimmediate_operand" ""))
7132                             (zero_extend:TI
7133                               (match_operand:DI 2 "register_operand" ""))))
7134               (clobber (reg:CC FLAGS_REG))])]
7135   "TARGET_64BIT"
7136   "")
7137
7138 (define_insn "*umulditi3_insn"
7139   [(set (match_operand:TI 0 "register_operand" "=A")
7140         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7141                  (zero_extend:TI (match_operand:DI 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{q}\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" "DI")])
7153
7154 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7155 (define_expand "umulsidi3"
7156   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7157                    (mult:DI (zero_extend:DI
7158                               (match_operand:SI 1 "nonimmediate_operand" ""))
7159                             (zero_extend:DI
7160                               (match_operand:SI 2 "register_operand" ""))))
7161               (clobber (reg:CC FLAGS_REG))])]
7162   "!TARGET_64BIT"
7163   "")
7164
7165 (define_insn "*umulsidi3_insn"
7166   [(set (match_operand:DI 0 "register_operand" "=A")
7167         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7168                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7169    (clobber (reg:CC FLAGS_REG))]
7170   "!TARGET_64BIT
7171    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7172   "mul{l}\t%2"
7173   [(set_attr "type" "imul")
7174    (set_attr "length_immediate" "0")
7175    (set (attr "athlon_decode")
7176      (if_then_else (eq_attr "cpu" "athlon")
7177         (const_string "vector")
7178         (const_string "double")))
7179    (set_attr "mode" "SI")])
7180
7181 (define_expand "mulditi3"
7182   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7183                    (mult:TI (sign_extend:TI
7184                               (match_operand:DI 1 "nonimmediate_operand" ""))
7185                             (sign_extend:TI
7186                               (match_operand:DI 2 "register_operand" ""))))
7187               (clobber (reg:CC FLAGS_REG))])]
7188   "TARGET_64BIT"
7189   "")
7190
7191 (define_insn "*mulditi3_insn"
7192   [(set (match_operand:TI 0 "register_operand" "=A")
7193         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7194                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7195    (clobber (reg:CC FLAGS_REG))]
7196   "TARGET_64BIT
7197    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7198   "imul{q}\t%2"
7199   [(set_attr "type" "imul")
7200    (set_attr "length_immediate" "0")
7201    (set (attr "athlon_decode")
7202      (if_then_else (eq_attr "cpu" "athlon")
7203         (const_string "vector")
7204         (const_string "double")))
7205    (set_attr "mode" "DI")])
7206
7207 (define_expand "mulsidi3"
7208   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7209                    (mult:DI (sign_extend:DI
7210                               (match_operand:SI 1 "nonimmediate_operand" ""))
7211                             (sign_extend:DI
7212                               (match_operand:SI 2 "register_operand" ""))))
7213               (clobber (reg:CC FLAGS_REG))])]
7214   "!TARGET_64BIT"
7215   "")
7216
7217 (define_insn "*mulsidi3_insn"
7218   [(set (match_operand:DI 0 "register_operand" "=A")
7219         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7220                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7221    (clobber (reg:CC FLAGS_REG))]
7222   "!TARGET_64BIT
7223    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7224   "imul{l}\t%2"
7225   [(set_attr "type" "imul")
7226    (set_attr "length_immediate" "0")
7227    (set (attr "athlon_decode")
7228      (if_then_else (eq_attr "cpu" "athlon")
7229         (const_string "vector")
7230         (const_string "double")))
7231    (set_attr "mode" "SI")])
7232
7233 (define_expand "umuldi3_highpart"
7234   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7235                    (truncate:DI
7236                      (lshiftrt:TI
7237                        (mult:TI (zero_extend:TI
7238                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7239                                 (zero_extend:TI
7240                                   (match_operand:DI 2 "register_operand" "")))
7241                        (const_int 64))))
7242               (clobber (match_scratch:DI 3 ""))
7243               (clobber (reg:CC FLAGS_REG))])]
7244   "TARGET_64BIT"
7245   "")
7246
7247 (define_insn "*umuldi3_highpart_rex64"
7248   [(set (match_operand:DI 0 "register_operand" "=d")
7249         (truncate:DI
7250           (lshiftrt:TI
7251             (mult:TI (zero_extend:TI
7252                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7253                      (zero_extend:TI
7254                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7255             (const_int 64))))
7256    (clobber (match_scratch:DI 3 "=1"))
7257    (clobber (reg:CC FLAGS_REG))]
7258   "TARGET_64BIT
7259    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7260   "mul{q}\t%2"
7261   [(set_attr "type" "imul")
7262    (set_attr "length_immediate" "0")
7263    (set (attr "athlon_decode")
7264      (if_then_else (eq_attr "cpu" "athlon")
7265         (const_string "vector")
7266         (const_string "double")))
7267    (set_attr "mode" "DI")])
7268
7269 (define_expand "umulsi3_highpart"
7270   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7271                    (truncate:SI
7272                      (lshiftrt:DI
7273                        (mult:DI (zero_extend:DI
7274                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7275                                 (zero_extend:DI
7276                                   (match_operand:SI 2 "register_operand" "")))
7277                        (const_int 32))))
7278               (clobber (match_scratch:SI 3 ""))
7279               (clobber (reg:CC FLAGS_REG))])]
7280   ""
7281   "")
7282
7283 (define_insn "*umulsi3_highpart_insn"
7284   [(set (match_operand:SI 0 "register_operand" "=d")
7285         (truncate:SI
7286           (lshiftrt:DI
7287             (mult:DI (zero_extend:DI
7288                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7289                      (zero_extend:DI
7290                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7291             (const_int 32))))
7292    (clobber (match_scratch:SI 3 "=1"))
7293    (clobber (reg:CC FLAGS_REG))]
7294   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7295   "mul{l}\t%2"
7296   [(set_attr "type" "imul")
7297    (set_attr "length_immediate" "0")
7298    (set (attr "athlon_decode")
7299      (if_then_else (eq_attr "cpu" "athlon")
7300         (const_string "vector")
7301         (const_string "double")))
7302    (set_attr "mode" "SI")])
7303
7304 (define_insn "*umulsi3_highpart_zext"
7305   [(set (match_operand:DI 0 "register_operand" "=d")
7306         (zero_extend:DI (truncate:SI
7307           (lshiftrt:DI
7308             (mult:DI (zero_extend:DI
7309                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7310                      (zero_extend:DI
7311                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7312             (const_int 32)))))
7313    (clobber (match_scratch:SI 3 "=1"))
7314    (clobber (reg:CC FLAGS_REG))]
7315   "TARGET_64BIT
7316    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7317   "mul{l}\t%2"
7318   [(set_attr "type" "imul")
7319    (set_attr "length_immediate" "0")
7320    (set (attr "athlon_decode")
7321      (if_then_else (eq_attr "cpu" "athlon")
7322         (const_string "vector")
7323         (const_string "double")))
7324    (set_attr "mode" "SI")])
7325
7326 (define_expand "smuldi3_highpart"
7327   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7328                    (truncate:DI
7329                      (lshiftrt:TI
7330                        (mult:TI (sign_extend:TI
7331                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7332                                 (sign_extend:TI
7333                                   (match_operand:DI 2 "register_operand" "")))
7334                        (const_int 64))))
7335               (clobber (match_scratch:DI 3 ""))
7336               (clobber (reg:CC FLAGS_REG))])]
7337   "TARGET_64BIT"
7338   "")
7339
7340 (define_insn "*smuldi3_highpart_rex64"
7341   [(set (match_operand:DI 0 "register_operand" "=d")
7342         (truncate:DI
7343           (lshiftrt:TI
7344             (mult:TI (sign_extend:TI
7345                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7346                      (sign_extend:TI
7347                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7348             (const_int 64))))
7349    (clobber (match_scratch:DI 3 "=1"))
7350    (clobber (reg:CC FLAGS_REG))]
7351   "TARGET_64BIT
7352    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7353   "imul{q}\t%2"
7354   [(set_attr "type" "imul")
7355    (set (attr "athlon_decode")
7356      (if_then_else (eq_attr "cpu" "athlon")
7357         (const_string "vector")
7358         (const_string "double")))
7359    (set_attr "mode" "DI")])
7360
7361 (define_expand "smulsi3_highpart"
7362   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7363                    (truncate:SI
7364                      (lshiftrt:DI
7365                        (mult:DI (sign_extend:DI
7366                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7367                                 (sign_extend:DI
7368                                   (match_operand:SI 2 "register_operand" "")))
7369                        (const_int 32))))
7370               (clobber (match_scratch:SI 3 ""))
7371               (clobber (reg:CC FLAGS_REG))])]
7372   ""
7373   "")
7374
7375 (define_insn "*smulsi3_highpart_insn"
7376   [(set (match_operand:SI 0 "register_operand" "=d")
7377         (truncate:SI
7378           (lshiftrt:DI
7379             (mult:DI (sign_extend:DI
7380                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7381                      (sign_extend:DI
7382                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7383             (const_int 32))))
7384    (clobber (match_scratch:SI 3 "=1"))
7385    (clobber (reg:CC FLAGS_REG))]
7386   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7387   "imul{l}\t%2"
7388   [(set_attr "type" "imul")
7389    (set (attr "athlon_decode")
7390      (if_then_else (eq_attr "cpu" "athlon")
7391         (const_string "vector")
7392         (const_string "double")))
7393    (set_attr "mode" "SI")])
7394
7395 (define_insn "*smulsi3_highpart_zext"
7396   [(set (match_operand:DI 0 "register_operand" "=d")
7397         (zero_extend:DI (truncate:SI
7398           (lshiftrt:DI
7399             (mult:DI (sign_extend:DI
7400                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7401                      (sign_extend:DI
7402                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7403             (const_int 32)))))
7404    (clobber (match_scratch:SI 3 "=1"))
7405    (clobber (reg:CC FLAGS_REG))]
7406   "TARGET_64BIT
7407    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7408   "imul{l}\t%2"
7409   [(set_attr "type" "imul")
7410    (set (attr "athlon_decode")
7411      (if_then_else (eq_attr "cpu" "athlon")
7412         (const_string "vector")
7413         (const_string "double")))
7414    (set_attr "mode" "SI")])
7415
7416 ;; The patterns that match these are at the end of this file.
7417
7418 (define_expand "mulxf3"
7419   [(set (match_operand:XF 0 "register_operand" "")
7420         (mult:XF (match_operand:XF 1 "register_operand" "")
7421                  (match_operand:XF 2 "register_operand" "")))]
7422   "TARGET_80387"
7423   "")
7424
7425 (define_expand "muldf3"
7426   [(set (match_operand:DF 0 "register_operand" "")
7427         (mult:DF (match_operand:DF 1 "register_operand" "")
7428                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7429   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7430   "")
7431
7432 (define_expand "mulsf3"
7433   [(set (match_operand:SF 0 "register_operand" "")
7434         (mult:SF (match_operand:SF 1 "register_operand" "")
7435                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7436   "TARGET_80387 || TARGET_SSE_MATH"
7437   "")
7438 \f
7439 ;; Divide instructions
7440
7441 (define_insn "divqi3"
7442   [(set (match_operand:QI 0 "register_operand" "=a")
7443         (div:QI (match_operand:HI 1 "register_operand" "0")
7444                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7445    (clobber (reg:CC FLAGS_REG))]
7446   "TARGET_QIMODE_MATH"
7447   "idiv{b}\t%2"
7448   [(set_attr "type" "idiv")
7449    (set_attr "mode" "QI")])
7450
7451 (define_insn "udivqi3"
7452   [(set (match_operand:QI 0 "register_operand" "=a")
7453         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7454                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7455    (clobber (reg:CC FLAGS_REG))]
7456   "TARGET_QIMODE_MATH"
7457   "div{b}\t%2"
7458   [(set_attr "type" "idiv")
7459    (set_attr "mode" "QI")])
7460
7461 ;; The patterns that match these are at the end of this file.
7462
7463 (define_expand "divxf3"
7464   [(set (match_operand:XF 0 "register_operand" "")
7465         (div:XF (match_operand:XF 1 "register_operand" "")
7466                 (match_operand:XF 2 "register_operand" "")))]
7467   "TARGET_80387"
7468   "")
7469
7470 (define_expand "divdf3"
7471   [(set (match_operand:DF 0 "register_operand" "")
7472         (div:DF (match_operand:DF 1 "register_operand" "")
7473                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7474    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7475    "")
7476  
7477 (define_expand "divsf3"
7478   [(set (match_operand:SF 0 "register_operand" "")
7479         (div:SF (match_operand:SF 1 "register_operand" "")
7480                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7481   "TARGET_80387 || TARGET_SSE_MATH"
7482   "")
7483 \f
7484 ;; Remainder instructions.
7485
7486 (define_expand "divmoddi4"
7487   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7488                    (div:DI (match_operand:DI 1 "register_operand" "")
7489                            (match_operand:DI 2 "nonimmediate_operand" "")))
7490               (set (match_operand:DI 3 "register_operand" "")
7491                    (mod:DI (match_dup 1) (match_dup 2)))
7492               (clobber (reg:CC FLAGS_REG))])]
7493   "TARGET_64BIT"
7494   "")
7495
7496 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7497 ;; Penalize eax case slightly because it results in worse scheduling
7498 ;; of code.
7499 (define_insn "*divmoddi4_nocltd_rex64"
7500   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7501         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7502                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7503    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7504         (mod:DI (match_dup 2) (match_dup 3)))
7505    (clobber (reg:CC FLAGS_REG))]
7506   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7507   "#"
7508   [(set_attr "type" "multi")])
7509
7510 (define_insn "*divmoddi4_cltd_rex64"
7511   [(set (match_operand:DI 0 "register_operand" "=a")
7512         (div:DI (match_operand:DI 2 "register_operand" "a")
7513                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7514    (set (match_operand:DI 1 "register_operand" "=&d")
7515         (mod:DI (match_dup 2) (match_dup 3)))
7516    (clobber (reg:CC FLAGS_REG))]
7517   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7518   "#"
7519   [(set_attr "type" "multi")])
7520
7521 (define_insn "*divmoddi_noext_rex64"
7522   [(set (match_operand:DI 0 "register_operand" "=a")
7523         (div:DI (match_operand:DI 1 "register_operand" "0")
7524                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7525    (set (match_operand:DI 3 "register_operand" "=d")
7526         (mod:DI (match_dup 1) (match_dup 2)))
7527    (use (match_operand:DI 4 "register_operand" "3"))
7528    (clobber (reg:CC FLAGS_REG))]
7529   "TARGET_64BIT"
7530   "idiv{q}\t%2"
7531   [(set_attr "type" "idiv")
7532    (set_attr "mode" "DI")])
7533
7534 (define_split
7535   [(set (match_operand:DI 0 "register_operand" "")
7536         (div:DI (match_operand:DI 1 "register_operand" "")
7537                 (match_operand:DI 2 "nonimmediate_operand" "")))
7538    (set (match_operand:DI 3 "register_operand" "")
7539         (mod:DI (match_dup 1) (match_dup 2)))
7540    (clobber (reg:CC FLAGS_REG))]
7541   "TARGET_64BIT && reload_completed"
7542   [(parallel [(set (match_dup 3)
7543                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7544               (clobber (reg:CC FLAGS_REG))])
7545    (parallel [(set (match_dup 0)
7546                    (div:DI (reg:DI 0) (match_dup 2)))
7547               (set (match_dup 3)
7548                    (mod:DI (reg:DI 0) (match_dup 2)))
7549               (use (match_dup 3))
7550               (clobber (reg:CC FLAGS_REG))])]
7551 {
7552   /* Avoid use of cltd in favor of a mov+shift.  */
7553   if (!TARGET_USE_CLTD && !optimize_size)
7554     {
7555       if (true_regnum (operands[1]))
7556         emit_move_insn (operands[0], operands[1]);
7557       else
7558         emit_move_insn (operands[3], operands[1]);
7559       operands[4] = operands[3];
7560     }
7561   else
7562     {
7563       if (true_regnum (operands[1]))
7564         abort();
7565       operands[4] = operands[1];
7566     }
7567 })
7568
7569
7570 (define_expand "divmodsi4"
7571   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7572                    (div:SI (match_operand:SI 1 "register_operand" "")
7573                            (match_operand:SI 2 "nonimmediate_operand" "")))
7574               (set (match_operand:SI 3 "register_operand" "")
7575                    (mod:SI (match_dup 1) (match_dup 2)))
7576               (clobber (reg:CC FLAGS_REG))])]
7577   ""
7578   "")
7579
7580 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7581 ;; Penalize eax case slightly because it results in worse scheduling
7582 ;; of code.
7583 (define_insn "*divmodsi4_nocltd"
7584   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7585         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7586                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7587    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7588         (mod:SI (match_dup 2) (match_dup 3)))
7589    (clobber (reg:CC FLAGS_REG))]
7590   "!optimize_size && !TARGET_USE_CLTD"
7591   "#"
7592   [(set_attr "type" "multi")])
7593
7594 (define_insn "*divmodsi4_cltd"
7595   [(set (match_operand:SI 0 "register_operand" "=a")
7596         (div:SI (match_operand:SI 2 "register_operand" "a")
7597                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7598    (set (match_operand:SI 1 "register_operand" "=&d")
7599         (mod:SI (match_dup 2) (match_dup 3)))
7600    (clobber (reg:CC FLAGS_REG))]
7601   "optimize_size || TARGET_USE_CLTD"
7602   "#"
7603   [(set_attr "type" "multi")])
7604
7605 (define_insn "*divmodsi_noext"
7606   [(set (match_operand:SI 0 "register_operand" "=a")
7607         (div:SI (match_operand:SI 1 "register_operand" "0")
7608                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7609    (set (match_operand:SI 3 "register_operand" "=d")
7610         (mod:SI (match_dup 1) (match_dup 2)))
7611    (use (match_operand:SI 4 "register_operand" "3"))
7612    (clobber (reg:CC FLAGS_REG))]
7613   ""
7614   "idiv{l}\t%2"
7615   [(set_attr "type" "idiv")
7616    (set_attr "mode" "SI")])
7617
7618 (define_split
7619   [(set (match_operand:SI 0 "register_operand" "")
7620         (div:SI (match_operand:SI 1 "register_operand" "")
7621                 (match_operand:SI 2 "nonimmediate_operand" "")))
7622    (set (match_operand:SI 3 "register_operand" "")
7623         (mod:SI (match_dup 1) (match_dup 2)))
7624    (clobber (reg:CC FLAGS_REG))]
7625   "reload_completed"
7626   [(parallel [(set (match_dup 3)
7627                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7628               (clobber (reg:CC FLAGS_REG))])
7629    (parallel [(set (match_dup 0)
7630                    (div:SI (reg:SI 0) (match_dup 2)))
7631               (set (match_dup 3)
7632                    (mod:SI (reg:SI 0) (match_dup 2)))
7633               (use (match_dup 3))
7634               (clobber (reg:CC FLAGS_REG))])]
7635 {
7636   /* Avoid use of cltd in favor of a mov+shift.  */
7637   if (!TARGET_USE_CLTD && !optimize_size)
7638     {
7639       if (true_regnum (operands[1]))
7640         emit_move_insn (operands[0], operands[1]);
7641       else
7642         emit_move_insn (operands[3], operands[1]);
7643       operands[4] = operands[3];
7644     }
7645   else
7646     {
7647       if (true_regnum (operands[1]))
7648         abort();
7649       operands[4] = operands[1];
7650     }
7651 })
7652 ;; %%% Split me.
7653 (define_insn "divmodhi4"
7654   [(set (match_operand:HI 0 "register_operand" "=a")
7655         (div:HI (match_operand:HI 1 "register_operand" "0")
7656                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7657    (set (match_operand:HI 3 "register_operand" "=&d")
7658         (mod:HI (match_dup 1) (match_dup 2)))
7659    (clobber (reg:CC FLAGS_REG))]
7660   "TARGET_HIMODE_MATH"
7661   "cwtd\;idiv{w}\t%2"
7662   [(set_attr "type" "multi")
7663    (set_attr "length_immediate" "0")
7664    (set_attr "mode" "SI")])
7665
7666 (define_insn "udivmoddi4"
7667   [(set (match_operand:DI 0 "register_operand" "=a")
7668         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7669                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7670    (set (match_operand:DI 3 "register_operand" "=&d")
7671         (umod:DI (match_dup 1) (match_dup 2)))
7672    (clobber (reg:CC FLAGS_REG))]
7673   "TARGET_64BIT"
7674   "xor{q}\t%3, %3\;div{q}\t%2"
7675   [(set_attr "type" "multi")
7676    (set_attr "length_immediate" "0")
7677    (set_attr "mode" "DI")])
7678
7679 (define_insn "*udivmoddi4_noext"
7680   [(set (match_operand:DI 0 "register_operand" "=a")
7681         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7682                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7683    (set (match_operand:DI 3 "register_operand" "=d")
7684         (umod:DI (match_dup 1) (match_dup 2)))
7685    (use (match_dup 3))
7686    (clobber (reg:CC FLAGS_REG))]
7687   "TARGET_64BIT"
7688   "div{q}\t%2"
7689   [(set_attr "type" "idiv")
7690    (set_attr "mode" "DI")])
7691
7692 (define_split
7693   [(set (match_operand:DI 0 "register_operand" "")
7694         (udiv:DI (match_operand:DI 1 "register_operand" "")
7695                  (match_operand:DI 2 "nonimmediate_operand" "")))
7696    (set (match_operand:DI 3 "register_operand" "")
7697         (umod:DI (match_dup 1) (match_dup 2)))
7698    (clobber (reg:CC FLAGS_REG))]
7699   "TARGET_64BIT && reload_completed"
7700   [(set (match_dup 3) (const_int 0))
7701    (parallel [(set (match_dup 0)
7702                    (udiv:DI (match_dup 1) (match_dup 2)))
7703               (set (match_dup 3)
7704                    (umod:DI (match_dup 1) (match_dup 2)))
7705               (use (match_dup 3))
7706               (clobber (reg:CC FLAGS_REG))])]
7707   "")
7708
7709 (define_insn "udivmodsi4"
7710   [(set (match_operand:SI 0 "register_operand" "=a")
7711         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7712                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7713    (set (match_operand:SI 3 "register_operand" "=&d")
7714         (umod:SI (match_dup 1) (match_dup 2)))
7715    (clobber (reg:CC FLAGS_REG))]
7716   ""
7717   "xor{l}\t%3, %3\;div{l}\t%2"
7718   [(set_attr "type" "multi")
7719    (set_attr "length_immediate" "0")
7720    (set_attr "mode" "SI")])
7721
7722 (define_insn "*udivmodsi4_noext"
7723   [(set (match_operand:SI 0 "register_operand" "=a")
7724         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7725                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7726    (set (match_operand:SI 3 "register_operand" "=d")
7727         (umod:SI (match_dup 1) (match_dup 2)))
7728    (use (match_dup 3))
7729    (clobber (reg:CC FLAGS_REG))]
7730   ""
7731   "div{l}\t%2"
7732   [(set_attr "type" "idiv")
7733    (set_attr "mode" "SI")])
7734
7735 (define_split
7736   [(set (match_operand:SI 0 "register_operand" "")
7737         (udiv:SI (match_operand:SI 1 "register_operand" "")
7738                  (match_operand:SI 2 "nonimmediate_operand" "")))
7739    (set (match_operand:SI 3 "register_operand" "")
7740         (umod:SI (match_dup 1) (match_dup 2)))
7741    (clobber (reg:CC FLAGS_REG))]
7742   "reload_completed"
7743   [(set (match_dup 3) (const_int 0))
7744    (parallel [(set (match_dup 0)
7745                    (udiv:SI (match_dup 1) (match_dup 2)))
7746               (set (match_dup 3)
7747                    (umod:SI (match_dup 1) (match_dup 2)))
7748               (use (match_dup 3))
7749               (clobber (reg:CC FLAGS_REG))])]
7750   "")
7751
7752 (define_expand "udivmodhi4"
7753   [(set (match_dup 4) (const_int 0))
7754    (parallel [(set (match_operand:HI 0 "register_operand" "")
7755                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7756                             (match_operand:HI 2 "nonimmediate_operand" "")))
7757               (set (match_operand:HI 3 "register_operand" "")
7758                    (umod:HI (match_dup 1) (match_dup 2)))
7759               (use (match_dup 4))
7760               (clobber (reg:CC FLAGS_REG))])]
7761   "TARGET_HIMODE_MATH"
7762   "operands[4] = gen_reg_rtx (HImode);")
7763
7764 (define_insn "*udivmodhi_noext"
7765   [(set (match_operand:HI 0 "register_operand" "=a")
7766         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7767                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7768    (set (match_operand:HI 3 "register_operand" "=d")
7769         (umod:HI (match_dup 1) (match_dup 2)))
7770    (use (match_operand:HI 4 "register_operand" "3"))
7771    (clobber (reg:CC FLAGS_REG))]
7772   ""
7773   "div{w}\t%2"
7774   [(set_attr "type" "idiv")
7775    (set_attr "mode" "HI")])
7776
7777 ;; We cannot use div/idiv for double division, because it causes
7778 ;; "division by zero" on the overflow and that's not what we expect
7779 ;; from truncate.  Because true (non truncating) double division is
7780 ;; never generated, we can't create this insn anyway.
7781 ;
7782 ;(define_insn ""
7783 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7784 ;       (truncate:SI
7785 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7786 ;                  (zero_extend:DI
7787 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7788 ;   (set (match_operand:SI 3 "register_operand" "=d")
7789 ;       (truncate:SI
7790 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7791 ;   (clobber (reg:CC FLAGS_REG))]
7792 ;  ""
7793 ;  "div{l}\t{%2, %0|%0, %2}"
7794 ;  [(set_attr "type" "idiv")])
7795 \f
7796 ;;- Logical AND instructions
7797
7798 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7799 ;; Note that this excludes ah.
7800
7801 (define_insn "*testdi_1_rex64"
7802   [(set (reg FLAGS_REG)
7803         (compare
7804           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7805                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7806           (const_int 0)))]
7807   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7808    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7809   "@
7810    test{l}\t{%k1, %k0|%k0, %k1}
7811    test{l}\t{%k1, %k0|%k0, %k1}
7812    test{q}\t{%1, %0|%0, %1}
7813    test{q}\t{%1, %0|%0, %1}
7814    test{q}\t{%1, %0|%0, %1}"
7815   [(set_attr "type" "test")
7816    (set_attr "modrm" "0,1,0,1,1")
7817    (set_attr "mode" "SI,SI,DI,DI,DI")
7818    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7819
7820 (define_insn "testsi_1"
7821   [(set (reg FLAGS_REG)
7822         (compare
7823           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7824                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7825           (const_int 0)))]
7826   "ix86_match_ccmode (insn, CCNOmode)
7827    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7828   "test{l}\t{%1, %0|%0, %1}"
7829   [(set_attr "type" "test")
7830    (set_attr "modrm" "0,1,1")
7831    (set_attr "mode" "SI")
7832    (set_attr "pent_pair" "uv,np,uv")])
7833
7834 (define_expand "testsi_ccno_1"
7835   [(set (reg:CCNO FLAGS_REG)
7836         (compare:CCNO
7837           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7838                   (match_operand:SI 1 "nonmemory_operand" ""))
7839           (const_int 0)))]
7840   ""
7841   "")
7842
7843 (define_insn "*testhi_1"
7844   [(set (reg FLAGS_REG)
7845         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7846                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7847                  (const_int 0)))]
7848   "ix86_match_ccmode (insn, CCNOmode)
7849    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7850   "test{w}\t{%1, %0|%0, %1}"
7851   [(set_attr "type" "test")
7852    (set_attr "modrm" "0,1,1")
7853    (set_attr "mode" "HI")
7854    (set_attr "pent_pair" "uv,np,uv")])
7855
7856 (define_expand "testqi_ccz_1"
7857   [(set (reg:CCZ FLAGS_REG)
7858         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7859                              (match_operand:QI 1 "nonmemory_operand" ""))
7860                  (const_int 0)))]
7861   ""
7862   "")
7863
7864 (define_insn "*testqi_1_maybe_si"
7865   [(set (reg FLAGS_REG)
7866         (compare
7867           (and:QI
7868             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7869             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7870           (const_int 0)))]
7871    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7872     && ix86_match_ccmode (insn,
7873                          GET_CODE (operands[1]) == CONST_INT
7874                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7875 {
7876   if (which_alternative == 3)
7877     {
7878       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7879         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7880       return "test{l}\t{%1, %k0|%k0, %1}";
7881     }
7882   return "test{b}\t{%1, %0|%0, %1}";
7883 }
7884   [(set_attr "type" "test")
7885    (set_attr "modrm" "0,1,1,1")
7886    (set_attr "mode" "QI,QI,QI,SI")
7887    (set_attr "pent_pair" "uv,np,uv,np")])
7888
7889 (define_insn "*testqi_1"
7890   [(set (reg FLAGS_REG)
7891         (compare
7892           (and:QI
7893             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7894             (match_operand:QI 1 "general_operand" "n,n,qn"))
7895           (const_int 0)))]
7896   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7897    && ix86_match_ccmode (insn, CCNOmode)"
7898   "test{b}\t{%1, %0|%0, %1}"
7899   [(set_attr "type" "test")
7900    (set_attr "modrm" "0,1,1")
7901    (set_attr "mode" "QI")
7902    (set_attr "pent_pair" "uv,np,uv")])
7903
7904 (define_expand "testqi_ext_ccno_0"
7905   [(set (reg:CCNO FLAGS_REG)
7906         (compare:CCNO
7907           (and:SI
7908             (zero_extract:SI
7909               (match_operand 0 "ext_register_operand" "")
7910               (const_int 8)
7911               (const_int 8))
7912             (match_operand 1 "const_int_operand" ""))
7913           (const_int 0)))]
7914   ""
7915   "")
7916
7917 (define_insn "*testqi_ext_0"
7918   [(set (reg FLAGS_REG)
7919         (compare
7920           (and:SI
7921             (zero_extract:SI
7922               (match_operand 0 "ext_register_operand" "Q")
7923               (const_int 8)
7924               (const_int 8))
7925             (match_operand 1 "const_int_operand" "n"))
7926           (const_int 0)))]
7927   "ix86_match_ccmode (insn, CCNOmode)"
7928   "test{b}\t{%1, %h0|%h0, %1}"
7929   [(set_attr "type" "test")
7930    (set_attr "mode" "QI")
7931    (set_attr "length_immediate" "1")
7932    (set_attr "pent_pair" "np")])
7933
7934 (define_insn "*testqi_ext_1"
7935   [(set (reg FLAGS_REG)
7936         (compare
7937           (and:SI
7938             (zero_extract:SI
7939               (match_operand 0 "ext_register_operand" "Q")
7940               (const_int 8)
7941               (const_int 8))
7942             (zero_extend:SI
7943               (match_operand:QI 1 "general_operand" "Qm")))
7944           (const_int 0)))]
7945   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7946    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7947   "test{b}\t{%1, %h0|%h0, %1}"
7948   [(set_attr "type" "test")
7949    (set_attr "mode" "QI")])
7950
7951 (define_insn "*testqi_ext_1_rex64"
7952   [(set (reg FLAGS_REG)
7953         (compare
7954           (and:SI
7955             (zero_extract:SI
7956               (match_operand 0 "ext_register_operand" "Q")
7957               (const_int 8)
7958               (const_int 8))
7959             (zero_extend:SI
7960               (match_operand:QI 1 "register_operand" "Q")))
7961           (const_int 0)))]
7962   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7963   "test{b}\t{%1, %h0|%h0, %1}"
7964   [(set_attr "type" "test")
7965    (set_attr "mode" "QI")])
7966
7967 (define_insn "*testqi_ext_2"
7968   [(set (reg FLAGS_REG)
7969         (compare
7970           (and:SI
7971             (zero_extract:SI
7972               (match_operand 0 "ext_register_operand" "Q")
7973               (const_int 8)
7974               (const_int 8))
7975             (zero_extract:SI
7976               (match_operand 1 "ext_register_operand" "Q")
7977               (const_int 8)
7978               (const_int 8)))
7979           (const_int 0)))]
7980   "ix86_match_ccmode (insn, CCNOmode)"
7981   "test{b}\t{%h1, %h0|%h0, %h1}"
7982   [(set_attr "type" "test")
7983    (set_attr "mode" "QI")])
7984
7985 ;; Combine likes to form bit extractions for some tests.  Humor it.
7986 (define_insn "*testqi_ext_3"
7987   [(set (reg FLAGS_REG)
7988         (compare (zero_extract:SI
7989                    (match_operand 0 "nonimmediate_operand" "rm")
7990                    (match_operand:SI 1 "const_int_operand" "")
7991                    (match_operand:SI 2 "const_int_operand" ""))
7992                  (const_int 0)))]
7993   "ix86_match_ccmode (insn, CCNOmode)
7994    && (GET_MODE (operands[0]) == SImode
7995        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7996        || GET_MODE (operands[0]) == HImode
7997        || GET_MODE (operands[0]) == QImode)"
7998   "#")
7999
8000 (define_insn "*testqi_ext_3_rex64"
8001   [(set (reg FLAGS_REG)
8002         (compare (zero_extract:DI
8003                    (match_operand 0 "nonimmediate_operand" "rm")
8004                    (match_operand:DI 1 "const_int_operand" "")
8005                    (match_operand:DI 2 "const_int_operand" ""))
8006                  (const_int 0)))]
8007   "TARGET_64BIT
8008    && ix86_match_ccmode (insn, CCNOmode)
8009    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
8010    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8011    /* Ensure that resulting mask is zero or sign extended operand.  */
8012    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8013        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8014            && INTVAL (operands[1]) > 32))
8015    && (GET_MODE (operands[0]) == SImode
8016        || GET_MODE (operands[0]) == DImode
8017        || GET_MODE (operands[0]) == HImode
8018        || GET_MODE (operands[0]) == QImode)"
8019   "#")
8020
8021 (define_split
8022   [(set (match_operand 0 "flags_reg_operand" "")
8023         (match_operator 1 "compare_operator"
8024           [(zero_extract
8025              (match_operand 2 "nonimmediate_operand" "")
8026              (match_operand 3 "const_int_operand" "")
8027              (match_operand 4 "const_int_operand" ""))
8028            (const_int 0)]))]
8029   "ix86_match_ccmode (insn, CCNOmode)"
8030   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8031 {
8032   rtx val = operands[2];
8033   HOST_WIDE_INT len = INTVAL (operands[3]);
8034   HOST_WIDE_INT pos = INTVAL (operands[4]);
8035   HOST_WIDE_INT mask;
8036   enum machine_mode mode, submode;
8037
8038   mode = GET_MODE (val);
8039   if (GET_CODE (val) == MEM)
8040     {
8041       /* ??? Combine likes to put non-volatile mem extractions in QImode
8042          no matter the size of the test.  So find a mode that works.  */
8043       if (! MEM_VOLATILE_P (val))
8044         {
8045           mode = smallest_mode_for_size (pos + len, MODE_INT);
8046           val = adjust_address (val, mode, 0);
8047         }
8048     }
8049   else if (GET_CODE (val) == SUBREG
8050            && (submode = GET_MODE (SUBREG_REG (val)),
8051                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8052            && pos + len <= GET_MODE_BITSIZE (submode))
8053     {
8054       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8055       mode = submode;
8056       val = SUBREG_REG (val);
8057     }
8058   else if (mode == HImode && pos + len <= 8)
8059     {
8060       /* Small HImode tests can be converted to QImode.  */
8061       mode = QImode;
8062       val = gen_lowpart (QImode, val);
8063     }
8064
8065   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8066   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8067
8068   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8069 })
8070
8071 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8072 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8073 ;; this is relatively important trick.
8074 ;; Do the conversion only post-reload to avoid limiting of the register class
8075 ;; to QI regs.
8076 (define_split
8077   [(set (match_operand 0 "flags_reg_operand" "")
8078         (match_operator 1 "compare_operator"
8079           [(and (match_operand 2 "register_operand" "")
8080                 (match_operand 3 "const_int_operand" ""))
8081            (const_int 0)]))]
8082    "reload_completed
8083     && QI_REG_P (operands[2])
8084     && GET_MODE (operands[2]) != QImode
8085     && ((ix86_match_ccmode (insn, CCZmode)
8086          && !(INTVAL (operands[3]) & ~(255 << 8)))
8087         || (ix86_match_ccmode (insn, CCNOmode)
8088             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8089   [(set (match_dup 0)
8090         (match_op_dup 1
8091           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8092                    (match_dup 3))
8093            (const_int 0)]))]
8094   "operands[2] = gen_lowpart (SImode, operands[2]);
8095    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8096
8097 (define_split
8098   [(set (match_operand 0 "flags_reg_operand" "")
8099         (match_operator 1 "compare_operator"
8100           [(and (match_operand 2 "nonimmediate_operand" "")
8101                 (match_operand 3 "const_int_operand" ""))
8102            (const_int 0)]))]
8103    "reload_completed
8104     && GET_MODE (operands[2]) != QImode
8105     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8106     && ((ix86_match_ccmode (insn, CCZmode)
8107          && !(INTVAL (operands[3]) & ~255))
8108         || (ix86_match_ccmode (insn, CCNOmode)
8109             && !(INTVAL (operands[3]) & ~127)))"
8110   [(set (match_dup 0)
8111         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8112                          (const_int 0)]))]
8113   "operands[2] = gen_lowpart (QImode, operands[2]);
8114    operands[3] = gen_lowpart (QImode, operands[3]);")
8115
8116
8117 ;; %%% This used to optimize known byte-wide and operations to memory,
8118 ;; and sometimes to QImode registers.  If this is considered useful,
8119 ;; it should be done with splitters.
8120
8121 (define_expand "anddi3"
8122   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8123         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8124                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8125    (clobber (reg:CC FLAGS_REG))]
8126   "TARGET_64BIT"
8127   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8128
8129 (define_insn "*anddi_1_rex64"
8130   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8131         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8132                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8133    (clobber (reg:CC FLAGS_REG))]
8134   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8135 {
8136   switch (get_attr_type (insn))
8137     {
8138     case TYPE_IMOVX:
8139       {
8140         enum machine_mode mode;
8141
8142         if (GET_CODE (operands[2]) != CONST_INT)
8143           abort ();
8144         if (INTVAL (operands[2]) == 0xff)
8145           mode = QImode;
8146         else if (INTVAL (operands[2]) == 0xffff)
8147           mode = HImode;
8148         else
8149           abort ();
8150         
8151         operands[1] = gen_lowpart (mode, operands[1]);
8152         if (mode == QImode)
8153           return "movz{bq|x}\t{%1,%0|%0, %1}";
8154         else
8155           return "movz{wq|x}\t{%1,%0|%0, %1}";
8156       }
8157
8158     default:
8159       if (! rtx_equal_p (operands[0], operands[1]))
8160         abort ();
8161       if (get_attr_mode (insn) == MODE_SI)
8162         return "and{l}\t{%k2, %k0|%k0, %k2}";
8163       else
8164         return "and{q}\t{%2, %0|%0, %2}";
8165     }
8166 }
8167   [(set_attr "type" "alu,alu,alu,imovx")
8168    (set_attr "length_immediate" "*,*,*,0")
8169    (set_attr "mode" "SI,DI,DI,DI")])
8170
8171 (define_insn "*anddi_2"
8172   [(set (reg FLAGS_REG)
8173         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8174                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8175                  (const_int 0)))
8176    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8177         (and:DI (match_dup 1) (match_dup 2)))]
8178   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8179    && ix86_binary_operator_ok (AND, DImode, operands)"
8180   "@
8181    and{l}\t{%k2, %k0|%k0, %k2}
8182    and{q}\t{%2, %0|%0, %2}
8183    and{q}\t{%2, %0|%0, %2}"
8184   [(set_attr "type" "alu")
8185    (set_attr "mode" "SI,DI,DI")])
8186
8187 (define_expand "andsi3"
8188   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8189         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8190                 (match_operand:SI 2 "general_operand" "")))
8191    (clobber (reg:CC FLAGS_REG))]
8192   ""
8193   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8194
8195 (define_insn "*andsi_1"
8196   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8197         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8198                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8199    (clobber (reg:CC FLAGS_REG))]
8200   "ix86_binary_operator_ok (AND, SImode, operands)"
8201 {
8202   switch (get_attr_type (insn))
8203     {
8204     case TYPE_IMOVX:
8205       {
8206         enum machine_mode mode;
8207
8208         if (GET_CODE (operands[2]) != CONST_INT)
8209           abort ();
8210         if (INTVAL (operands[2]) == 0xff)
8211           mode = QImode;
8212         else if (INTVAL (operands[2]) == 0xffff)
8213           mode = HImode;
8214         else
8215           abort ();
8216         
8217         operands[1] = gen_lowpart (mode, operands[1]);
8218         if (mode == QImode)
8219           return "movz{bl|x}\t{%1,%0|%0, %1}";
8220         else
8221           return "movz{wl|x}\t{%1,%0|%0, %1}";
8222       }
8223
8224     default:
8225       if (! rtx_equal_p (operands[0], operands[1]))
8226         abort ();
8227       return "and{l}\t{%2, %0|%0, %2}";
8228     }
8229 }
8230   [(set_attr "type" "alu,alu,imovx")
8231    (set_attr "length_immediate" "*,*,0")
8232    (set_attr "mode" "SI")])
8233
8234 (define_split
8235   [(set (match_operand 0 "register_operand" "")
8236         (and (match_dup 0)
8237              (const_int -65536)))
8238    (clobber (reg:CC FLAGS_REG))]
8239   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8240   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8241   "operands[1] = gen_lowpart (HImode, operands[0]);")
8242
8243 (define_split
8244   [(set (match_operand 0 "ext_register_operand" "")
8245         (and (match_dup 0)
8246              (const_int -256)))
8247    (clobber (reg:CC FLAGS_REG))]
8248   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8249   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8250   "operands[1] = gen_lowpart (QImode, operands[0]);")
8251
8252 (define_split
8253   [(set (match_operand 0 "ext_register_operand" "")
8254         (and (match_dup 0)
8255              (const_int -65281)))
8256    (clobber (reg:CC FLAGS_REG))]
8257   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8258   [(parallel [(set (zero_extract:SI (match_dup 0)
8259                                     (const_int 8)
8260                                     (const_int 8))
8261                    (xor:SI 
8262                      (zero_extract:SI (match_dup 0)
8263                                       (const_int 8)
8264                                       (const_int 8))
8265                      (zero_extract:SI (match_dup 0)
8266                                       (const_int 8)
8267                                       (const_int 8))))
8268               (clobber (reg:CC FLAGS_REG))])]
8269   "operands[0] = gen_lowpart (SImode, operands[0]);")
8270
8271 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8272 (define_insn "*andsi_1_zext"
8273   [(set (match_operand:DI 0 "register_operand" "=r")
8274         (zero_extend:DI
8275           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8276                   (match_operand:SI 2 "general_operand" "rim"))))
8277    (clobber (reg:CC FLAGS_REG))]
8278   "TARGET_64BIT && 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_insn "*andsi_2"
8284   [(set (reg FLAGS_REG)
8285         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8286                          (match_operand:SI 2 "general_operand" "rim,ri"))
8287                  (const_int 0)))
8288    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8289         (and:SI (match_dup 1) (match_dup 2)))]
8290   "ix86_match_ccmode (insn, CCNOmode)
8291    && ix86_binary_operator_ok (AND, SImode, operands)"
8292   "and{l}\t{%2, %0|%0, %2}"
8293   [(set_attr "type" "alu")
8294    (set_attr "mode" "SI")])
8295
8296 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8297 (define_insn "*andsi_2_zext"
8298   [(set (reg FLAGS_REG)
8299         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8300                          (match_operand:SI 2 "general_operand" "rim"))
8301                  (const_int 0)))
8302    (set (match_operand:DI 0 "register_operand" "=r")
8303         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8304   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8305    && ix86_binary_operator_ok (AND, SImode, operands)"
8306   "and{l}\t{%2, %k0|%k0, %2}"
8307   [(set_attr "type" "alu")
8308    (set_attr "mode" "SI")])
8309
8310 (define_expand "andhi3"
8311   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8312         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8313                 (match_operand:HI 2 "general_operand" "")))
8314    (clobber (reg:CC FLAGS_REG))]
8315   "TARGET_HIMODE_MATH"
8316   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8317
8318 (define_insn "*andhi_1"
8319   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8320         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8321                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8322    (clobber (reg:CC FLAGS_REG))]
8323   "ix86_binary_operator_ok (AND, HImode, operands)"
8324 {
8325   switch (get_attr_type (insn))
8326     {
8327     case TYPE_IMOVX:
8328       if (GET_CODE (operands[2]) != CONST_INT)
8329         abort ();
8330       if (INTVAL (operands[2]) == 0xff)
8331         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8332       abort ();
8333
8334     default:
8335       if (! rtx_equal_p (operands[0], operands[1]))
8336         abort ();
8337
8338       return "and{w}\t{%2, %0|%0, %2}";
8339     }
8340 }
8341   [(set_attr "type" "alu,alu,imovx")
8342    (set_attr "length_immediate" "*,*,0")
8343    (set_attr "mode" "HI,HI,SI")])
8344
8345 (define_insn "*andhi_2"
8346   [(set (reg FLAGS_REG)
8347         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8348                          (match_operand:HI 2 "general_operand" "rim,ri"))
8349                  (const_int 0)))
8350    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8351         (and:HI (match_dup 1) (match_dup 2)))]
8352   "ix86_match_ccmode (insn, CCNOmode)
8353    && ix86_binary_operator_ok (AND, HImode, operands)"
8354   "and{w}\t{%2, %0|%0, %2}"
8355   [(set_attr "type" "alu")
8356    (set_attr "mode" "HI")])
8357
8358 (define_expand "andqi3"
8359   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8360         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8361                 (match_operand:QI 2 "general_operand" "")))
8362    (clobber (reg:CC FLAGS_REG))]
8363   "TARGET_QIMODE_MATH"
8364   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8365
8366 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8367 (define_insn "*andqi_1"
8368   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8369         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8370                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8371    (clobber (reg:CC FLAGS_REG))]
8372   "ix86_binary_operator_ok (AND, QImode, operands)"
8373   "@
8374    and{b}\t{%2, %0|%0, %2}
8375    and{b}\t{%2, %0|%0, %2}
8376    and{l}\t{%k2, %k0|%k0, %k2}"
8377   [(set_attr "type" "alu")
8378    (set_attr "mode" "QI,QI,SI")])
8379
8380 (define_insn "*andqi_1_slp"
8381   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8382         (and:QI (match_dup 0)
8383                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8384    (clobber (reg:CC FLAGS_REG))]
8385   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8386    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8387   "and{b}\t{%1, %0|%0, %1}"
8388   [(set_attr "type" "alu1")
8389    (set_attr "mode" "QI")])
8390
8391 (define_insn "*andqi_2_maybe_si"
8392   [(set (reg FLAGS_REG)
8393         (compare (and:QI
8394                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8395                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8396                  (const_int 0)))
8397    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8398         (and:QI (match_dup 1) (match_dup 2)))]
8399   "ix86_binary_operator_ok (AND, QImode, operands)
8400    && ix86_match_ccmode (insn,
8401                          GET_CODE (operands[2]) == CONST_INT
8402                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8403 {
8404   if (which_alternative == 2)
8405     {
8406       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8407         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8408       return "and{l}\t{%2, %k0|%k0, %2}";
8409     }
8410   return "and{b}\t{%2, %0|%0, %2}";
8411 }
8412   [(set_attr "type" "alu")
8413    (set_attr "mode" "QI,QI,SI")])
8414
8415 (define_insn "*andqi_2"
8416   [(set (reg FLAGS_REG)
8417         (compare (and:QI
8418                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8419                    (match_operand:QI 2 "general_operand" "qim,qi"))
8420                  (const_int 0)))
8421    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8422         (and:QI (match_dup 1) (match_dup 2)))]
8423   "ix86_match_ccmode (insn, CCNOmode)
8424    && ix86_binary_operator_ok (AND, QImode, operands)"
8425   "and{b}\t{%2, %0|%0, %2}"
8426   [(set_attr "type" "alu")
8427    (set_attr "mode" "QI")])
8428
8429 (define_insn "*andqi_2_slp"
8430   [(set (reg FLAGS_REG)
8431         (compare (and:QI
8432                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8433                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8434                  (const_int 0)))
8435    (set (strict_low_part (match_dup 0))
8436         (and:QI (match_dup 0) (match_dup 1)))]
8437   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8438    && ix86_match_ccmode (insn, CCNOmode)
8439    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8440   "and{b}\t{%1, %0|%0, %1}"
8441   [(set_attr "type" "alu1")
8442    (set_attr "mode" "QI")])
8443
8444 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8445 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8446 ;; for a QImode operand, which of course failed.
8447
8448 (define_insn "andqi_ext_0"
8449   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8450                          (const_int 8)
8451                          (const_int 8))
8452         (and:SI 
8453           (zero_extract:SI
8454             (match_operand 1 "ext_register_operand" "0")
8455             (const_int 8)
8456             (const_int 8))
8457           (match_operand 2 "const_int_operand" "n")))
8458    (clobber (reg:CC FLAGS_REG))]
8459   ""
8460   "and{b}\t{%2, %h0|%h0, %2}"
8461   [(set_attr "type" "alu")
8462    (set_attr "length_immediate" "1")
8463    (set_attr "mode" "QI")])
8464
8465 ;; Generated by peephole translating test to and.  This shows up
8466 ;; often in fp comparisons.
8467
8468 (define_insn "*andqi_ext_0_cc"
8469   [(set (reg FLAGS_REG)
8470         (compare
8471           (and:SI
8472             (zero_extract:SI
8473               (match_operand 1 "ext_register_operand" "0")
8474               (const_int 8)
8475               (const_int 8))
8476             (match_operand 2 "const_int_operand" "n"))
8477           (const_int 0)))
8478    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8479                          (const_int 8)
8480                          (const_int 8))
8481         (and:SI 
8482           (zero_extract:SI
8483             (match_dup 1)
8484             (const_int 8)
8485             (const_int 8))
8486           (match_dup 2)))]
8487   "ix86_match_ccmode (insn, CCNOmode)"
8488   "and{b}\t{%2, %h0|%h0, %2}"
8489   [(set_attr "type" "alu")
8490    (set_attr "length_immediate" "1")
8491    (set_attr "mode" "QI")])
8492
8493 (define_insn "*andqi_ext_1"
8494   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8495                          (const_int 8)
8496                          (const_int 8))
8497         (and:SI 
8498           (zero_extract:SI
8499             (match_operand 1 "ext_register_operand" "0")
8500             (const_int 8)
8501             (const_int 8))
8502           (zero_extend:SI
8503             (match_operand:QI 2 "general_operand" "Qm"))))
8504    (clobber (reg:CC FLAGS_REG))]
8505   "!TARGET_64BIT"
8506   "and{b}\t{%2, %h0|%h0, %2}"
8507   [(set_attr "type" "alu")
8508    (set_attr "length_immediate" "0")
8509    (set_attr "mode" "QI")])
8510
8511 (define_insn "*andqi_ext_1_rex64"
8512   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8513                          (const_int 8)
8514                          (const_int 8))
8515         (and:SI 
8516           (zero_extract:SI
8517             (match_operand 1 "ext_register_operand" "0")
8518             (const_int 8)
8519             (const_int 8))
8520           (zero_extend:SI
8521             (match_operand 2 "ext_register_operand" "Q"))))
8522    (clobber (reg:CC FLAGS_REG))]
8523   "TARGET_64BIT"
8524   "and{b}\t{%2, %h0|%h0, %2}"
8525   [(set_attr "type" "alu")
8526    (set_attr "length_immediate" "0")
8527    (set_attr "mode" "QI")])
8528
8529 (define_insn "*andqi_ext_2"
8530   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8531                          (const_int 8)
8532                          (const_int 8))
8533         (and:SI
8534           (zero_extract:SI
8535             (match_operand 1 "ext_register_operand" "%0")
8536             (const_int 8)
8537             (const_int 8))
8538           (zero_extract:SI
8539             (match_operand 2 "ext_register_operand" "Q")
8540             (const_int 8)
8541             (const_int 8))))
8542    (clobber (reg:CC FLAGS_REG))]
8543   ""
8544   "and{b}\t{%h2, %h0|%h0, %h2}"
8545   [(set_attr "type" "alu")
8546    (set_attr "length_immediate" "0")
8547    (set_attr "mode" "QI")])
8548
8549 ;; Convert wide AND instructions with immediate operand to shorter QImode
8550 ;; equivalents when possible.
8551 ;; Don't do the splitting with memory operands, since it introduces risk
8552 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8553 ;; for size, but that can (should?) be handled by generic code instead.
8554 (define_split
8555   [(set (match_operand 0 "register_operand" "")
8556         (and (match_operand 1 "register_operand" "")
8557              (match_operand 2 "const_int_operand" "")))
8558    (clobber (reg:CC FLAGS_REG))]
8559    "reload_completed
8560     && QI_REG_P (operands[0])
8561     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8562     && !(~INTVAL (operands[2]) & ~(255 << 8))
8563     && GET_MODE (operands[0]) != QImode"
8564   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8565                    (and:SI (zero_extract:SI (match_dup 1)
8566                                             (const_int 8) (const_int 8))
8567                            (match_dup 2)))
8568               (clobber (reg:CC FLAGS_REG))])]
8569   "operands[0] = gen_lowpart (SImode, operands[0]);
8570    operands[1] = gen_lowpart (SImode, operands[1]);
8571    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8572
8573 ;; Since AND can be encoded with sign extended immediate, this is only
8574 ;; profitable when 7th bit is not set.
8575 (define_split
8576   [(set (match_operand 0 "register_operand" "")
8577         (and (match_operand 1 "general_operand" "")
8578              (match_operand 2 "const_int_operand" "")))
8579    (clobber (reg:CC FLAGS_REG))]
8580    "reload_completed
8581     && ANY_QI_REG_P (operands[0])
8582     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8583     && !(~INTVAL (operands[2]) & ~255)
8584     && !(INTVAL (operands[2]) & 128)
8585     && GET_MODE (operands[0]) != QImode"
8586   [(parallel [(set (strict_low_part (match_dup 0))
8587                    (and:QI (match_dup 1)
8588                            (match_dup 2)))
8589               (clobber (reg:CC FLAGS_REG))])]
8590   "operands[0] = gen_lowpart (QImode, operands[0]);
8591    operands[1] = gen_lowpart (QImode, operands[1]);
8592    operands[2] = gen_lowpart (QImode, operands[2]);")
8593 \f
8594 ;; Logical inclusive OR instructions
8595
8596 ;; %%% This used to optimize known byte-wide and operations to memory.
8597 ;; If this is considered useful, it should be done with splitters.
8598
8599 (define_expand "iordi3"
8600   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8601         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8602                 (match_operand:DI 2 "x86_64_general_operand" "")))
8603    (clobber (reg:CC FLAGS_REG))]
8604   "TARGET_64BIT"
8605   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8606
8607 (define_insn "*iordi_1_rex64"
8608   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8609         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8610                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8611    (clobber (reg:CC FLAGS_REG))]
8612   "TARGET_64BIT
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 (define_insn "*iordi_2_rex64"
8619   [(set (reg FLAGS_REG)
8620         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8621                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8622                  (const_int 0)))
8623    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8624         (ior:DI (match_dup 1) (match_dup 2)))]
8625   "TARGET_64BIT
8626    && ix86_match_ccmode (insn, CCNOmode)
8627    && ix86_binary_operator_ok (IOR, DImode, operands)"
8628   "or{q}\t{%2, %0|%0, %2}"
8629   [(set_attr "type" "alu")
8630    (set_attr "mode" "DI")])
8631
8632 (define_insn "*iordi_3_rex64"
8633   [(set (reg FLAGS_REG)
8634         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8635                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8636                  (const_int 0)))
8637    (clobber (match_scratch:DI 0 "=r"))]
8638   "TARGET_64BIT
8639    && ix86_match_ccmode (insn, CCNOmode)
8640    && ix86_binary_operator_ok (IOR, DImode, operands)"
8641   "or{q}\t{%2, %0|%0, %2}"
8642   [(set_attr "type" "alu")
8643    (set_attr "mode" "DI")])
8644
8645
8646 (define_expand "iorsi3"
8647   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8648         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8649                 (match_operand:SI 2 "general_operand" "")))
8650    (clobber (reg:CC FLAGS_REG))]
8651   ""
8652   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8653
8654 (define_insn "*iorsi_1"
8655   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8656         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8657                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8658    (clobber (reg:CC FLAGS_REG))]
8659   "ix86_binary_operator_ok (IOR, SImode, operands)"
8660   "or{l}\t{%2, %0|%0, %2}"
8661   [(set_attr "type" "alu")
8662    (set_attr "mode" "SI")])
8663
8664 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8665 (define_insn "*iorsi_1_zext"
8666   [(set (match_operand:DI 0 "register_operand" "=rm")
8667         (zero_extend:DI
8668           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8669                   (match_operand:SI 2 "general_operand" "rim"))))
8670    (clobber (reg:CC FLAGS_REG))]
8671   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8672   "or{l}\t{%2, %k0|%k0, %2}"
8673   [(set_attr "type" "alu")
8674    (set_attr "mode" "SI")])
8675
8676 (define_insn "*iorsi_1_zext_imm"
8677   [(set (match_operand:DI 0 "register_operand" "=rm")
8678         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8679                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8680    (clobber (reg:CC FLAGS_REG))]
8681   "TARGET_64BIT"
8682   "or{l}\t{%2, %k0|%k0, %2}"
8683   [(set_attr "type" "alu")
8684    (set_attr "mode" "SI")])
8685
8686 (define_insn "*iorsi_2"
8687   [(set (reg FLAGS_REG)
8688         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8689                          (match_operand:SI 2 "general_operand" "rim,ri"))
8690                  (const_int 0)))
8691    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8692         (ior:SI (match_dup 1) (match_dup 2)))]
8693   "ix86_match_ccmode (insn, CCNOmode)
8694    && ix86_binary_operator_ok (IOR, SImode, operands)"
8695   "or{l}\t{%2, %0|%0, %2}"
8696   [(set_attr "type" "alu")
8697    (set_attr "mode" "SI")])
8698
8699 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8700 ;; ??? Special case for immediate operand is missing - it is tricky.
8701 (define_insn "*iorsi_2_zext"
8702   [(set (reg FLAGS_REG)
8703         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8704                          (match_operand:SI 2 "general_operand" "rim"))
8705                  (const_int 0)))
8706    (set (match_operand:DI 0 "register_operand" "=r")
8707         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8708   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8709    && ix86_binary_operator_ok (IOR, SImode, operands)"
8710   "or{l}\t{%2, %k0|%k0, %2}"
8711   [(set_attr "type" "alu")
8712    (set_attr "mode" "SI")])
8713
8714 (define_insn "*iorsi_2_zext_imm"
8715   [(set (reg FLAGS_REG)
8716         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8717                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8718                  (const_int 0)))
8719    (set (match_operand:DI 0 "register_operand" "=r")
8720         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8721   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8722    && ix86_binary_operator_ok (IOR, SImode, operands)"
8723   "or{l}\t{%2, %k0|%k0, %2}"
8724   [(set_attr "type" "alu")
8725    (set_attr "mode" "SI")])
8726
8727 (define_insn "*iorsi_3"
8728   [(set (reg FLAGS_REG)
8729         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8730                          (match_operand:SI 2 "general_operand" "rim"))
8731                  (const_int 0)))
8732    (clobber (match_scratch:SI 0 "=r"))]
8733   "ix86_match_ccmode (insn, CCNOmode)
8734    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8735   "or{l}\t{%2, %0|%0, %2}"
8736   [(set_attr "type" "alu")
8737    (set_attr "mode" "SI")])
8738
8739 (define_expand "iorhi3"
8740   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8741         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8742                 (match_operand:HI 2 "general_operand" "")))
8743    (clobber (reg:CC FLAGS_REG))]
8744   "TARGET_HIMODE_MATH"
8745   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8746
8747 (define_insn "*iorhi_1"
8748   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8749         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8750                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8751    (clobber (reg:CC FLAGS_REG))]
8752   "ix86_binary_operator_ok (IOR, HImode, operands)"
8753   "or{w}\t{%2, %0|%0, %2}"
8754   [(set_attr "type" "alu")
8755    (set_attr "mode" "HI")])
8756
8757 (define_insn "*iorhi_2"
8758   [(set (reg FLAGS_REG)
8759         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8760                          (match_operand:HI 2 "general_operand" "rim,ri"))
8761                  (const_int 0)))
8762    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8763         (ior:HI (match_dup 1) (match_dup 2)))]
8764   "ix86_match_ccmode (insn, CCNOmode)
8765    && ix86_binary_operator_ok (IOR, HImode, operands)"
8766   "or{w}\t{%2, %0|%0, %2}"
8767   [(set_attr "type" "alu")
8768    (set_attr "mode" "HI")])
8769
8770 (define_insn "*iorhi_3"
8771   [(set (reg FLAGS_REG)
8772         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8773                          (match_operand:HI 2 "general_operand" "rim"))
8774                  (const_int 0)))
8775    (clobber (match_scratch:HI 0 "=r"))]
8776   "ix86_match_ccmode (insn, CCNOmode)
8777    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8778   "or{w}\t{%2, %0|%0, %2}"
8779   [(set_attr "type" "alu")
8780    (set_attr "mode" "HI")])
8781
8782 (define_expand "iorqi3"
8783   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8784         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8785                 (match_operand:QI 2 "general_operand" "")))
8786    (clobber (reg:CC FLAGS_REG))]
8787   "TARGET_QIMODE_MATH"
8788   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8789
8790 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8791 (define_insn "*iorqi_1"
8792   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8793         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8794                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8795    (clobber (reg:CC FLAGS_REG))]
8796   "ix86_binary_operator_ok (IOR, QImode, operands)"
8797   "@
8798    or{b}\t{%2, %0|%0, %2}
8799    or{b}\t{%2, %0|%0, %2}
8800    or{l}\t{%k2, %k0|%k0, %k2}"
8801   [(set_attr "type" "alu")
8802    (set_attr "mode" "QI,QI,SI")])
8803
8804 (define_insn "*iorqi_1_slp"
8805   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8806         (ior:QI (match_dup 0)
8807                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8808    (clobber (reg:CC FLAGS_REG))]
8809   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
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_2"
8816   [(set (reg FLAGS_REG)
8817         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8818                          (match_operand:QI 2 "general_operand" "qim,qi"))
8819                  (const_int 0)))
8820    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8821         (ior:QI (match_dup 1) (match_dup 2)))]
8822   "ix86_match_ccmode (insn, CCNOmode)
8823    && ix86_binary_operator_ok (IOR, QImode, operands)"
8824   "or{b}\t{%2, %0|%0, %2}"
8825   [(set_attr "type" "alu")
8826    (set_attr "mode" "QI")])
8827
8828 (define_insn "*iorqi_2_slp"
8829   [(set (reg FLAGS_REG)
8830         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8831                          (match_operand:QI 1 "general_operand" "qim,qi"))
8832                  (const_int 0)))
8833    (set (strict_low_part (match_dup 0))
8834         (ior:QI (match_dup 0) (match_dup 1)))]
8835   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8836    && ix86_match_ccmode (insn, CCNOmode)
8837    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8838   "or{b}\t{%1, %0|%0, %1}"
8839   [(set_attr "type" "alu1")
8840    (set_attr "mode" "QI")])
8841
8842 (define_insn "*iorqi_3"
8843   [(set (reg FLAGS_REG)
8844         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8845                          (match_operand:QI 2 "general_operand" "qim"))
8846                  (const_int 0)))
8847    (clobber (match_scratch:QI 0 "=q"))]
8848   "ix86_match_ccmode (insn, CCNOmode)
8849    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8850   "or{b}\t{%2, %0|%0, %2}"
8851   [(set_attr "type" "alu")
8852    (set_attr "mode" "QI")])
8853
8854 (define_insn "iorqi_ext_0"
8855   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8856                          (const_int 8)
8857                          (const_int 8))
8858         (ior:SI 
8859           (zero_extract:SI
8860             (match_operand 1 "ext_register_operand" "0")
8861             (const_int 8)
8862             (const_int 8))
8863           (match_operand 2 "const_int_operand" "n")))
8864    (clobber (reg:CC FLAGS_REG))]
8865   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8866   "or{b}\t{%2, %h0|%h0, %2}"
8867   [(set_attr "type" "alu")
8868    (set_attr "length_immediate" "1")
8869    (set_attr "mode" "QI")])
8870
8871 (define_insn "*iorqi_ext_1"
8872   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8873                          (const_int 8)
8874                          (const_int 8))
8875         (ior:SI 
8876           (zero_extract:SI
8877             (match_operand 1 "ext_register_operand" "0")
8878             (const_int 8)
8879             (const_int 8))
8880           (zero_extend:SI
8881             (match_operand:QI 2 "general_operand" "Qm"))))
8882    (clobber (reg:CC FLAGS_REG))]
8883   "!TARGET_64BIT
8884    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8885   "or{b}\t{%2, %h0|%h0, %2}"
8886   [(set_attr "type" "alu")
8887    (set_attr "length_immediate" "0")
8888    (set_attr "mode" "QI")])
8889
8890 (define_insn "*iorqi_ext_1_rex64"
8891   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8892                          (const_int 8)
8893                          (const_int 8))
8894         (ior:SI 
8895           (zero_extract:SI
8896             (match_operand 1 "ext_register_operand" "0")
8897             (const_int 8)
8898             (const_int 8))
8899           (zero_extend:SI
8900             (match_operand 2 "ext_register_operand" "Q"))))
8901    (clobber (reg:CC FLAGS_REG))]
8902   "TARGET_64BIT
8903    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8904   "or{b}\t{%2, %h0|%h0, %2}"
8905   [(set_attr "type" "alu")
8906    (set_attr "length_immediate" "0")
8907    (set_attr "mode" "QI")])
8908
8909 (define_insn "*iorqi_ext_2"
8910   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8911                          (const_int 8)
8912                          (const_int 8))
8913         (ior:SI 
8914           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8915                            (const_int 8)
8916                            (const_int 8))
8917           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8918                            (const_int 8)
8919                            (const_int 8))))
8920    (clobber (reg:CC FLAGS_REG))]
8921   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8922   "ior{b}\t{%h2, %h0|%h0, %h2}"
8923   [(set_attr "type" "alu")
8924    (set_attr "length_immediate" "0")
8925    (set_attr "mode" "QI")])
8926
8927 (define_split
8928   [(set (match_operand 0 "register_operand" "")
8929         (ior (match_operand 1 "register_operand" "")
8930              (match_operand 2 "const_int_operand" "")))
8931    (clobber (reg:CC FLAGS_REG))]
8932    "reload_completed
8933     && QI_REG_P (operands[0])
8934     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8935     && !(INTVAL (operands[2]) & ~(255 << 8))
8936     && GET_MODE (operands[0]) != QImode"
8937   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8938                    (ior:SI (zero_extract:SI (match_dup 1)
8939                                             (const_int 8) (const_int 8))
8940                            (match_dup 2)))
8941               (clobber (reg:CC FLAGS_REG))])]
8942   "operands[0] = gen_lowpart (SImode, operands[0]);
8943    operands[1] = gen_lowpart (SImode, operands[1]);
8944    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8945
8946 ;; Since OR can be encoded with sign extended immediate, this is only
8947 ;; profitable when 7th bit is set.
8948 (define_split
8949   [(set (match_operand 0 "register_operand" "")
8950         (ior (match_operand 1 "general_operand" "")
8951              (match_operand 2 "const_int_operand" "")))
8952    (clobber (reg:CC FLAGS_REG))]
8953    "reload_completed
8954     && ANY_QI_REG_P (operands[0])
8955     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8956     && !(INTVAL (operands[2]) & ~255)
8957     && (INTVAL (operands[2]) & 128)
8958     && GET_MODE (operands[0]) != QImode"
8959   [(parallel [(set (strict_low_part (match_dup 0))
8960                    (ior:QI (match_dup 1)
8961                            (match_dup 2)))
8962               (clobber (reg:CC FLAGS_REG))])]
8963   "operands[0] = gen_lowpart (QImode, operands[0]);
8964    operands[1] = gen_lowpart (QImode, operands[1]);
8965    operands[2] = gen_lowpart (QImode, operands[2]);")
8966 \f
8967 ;; Logical XOR instructions
8968
8969 ;; %%% This used to optimize known byte-wide and operations to memory.
8970 ;; If this is considered useful, it should be done with splitters.
8971
8972 (define_expand "xordi3"
8973   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8974         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8975                 (match_operand:DI 2 "x86_64_general_operand" "")))
8976    (clobber (reg:CC FLAGS_REG))]
8977   "TARGET_64BIT"
8978   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8979
8980 (define_insn "*xordi_1_rex64"
8981   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8982         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8983                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8984    (clobber (reg:CC FLAGS_REG))]
8985   "TARGET_64BIT
8986    && ix86_binary_operator_ok (XOR, DImode, operands)"
8987   "@
8988    xor{q}\t{%2, %0|%0, %2}
8989    xor{q}\t{%2, %0|%0, %2}"
8990   [(set_attr "type" "alu")
8991    (set_attr "mode" "DI,DI")])
8992
8993 (define_insn "*xordi_2_rex64"
8994   [(set (reg FLAGS_REG)
8995         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8996                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8997                  (const_int 0)))
8998    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8999         (xor:DI (match_dup 1) (match_dup 2)))]
9000   "TARGET_64BIT
9001    && ix86_match_ccmode (insn, CCNOmode)
9002    && ix86_binary_operator_ok (XOR, DImode, operands)"
9003   "@
9004    xor{q}\t{%2, %0|%0, %2}
9005    xor{q}\t{%2, %0|%0, %2}"
9006   [(set_attr "type" "alu")
9007    (set_attr "mode" "DI,DI")])
9008
9009 (define_insn "*xordi_3_rex64"
9010   [(set (reg FLAGS_REG)
9011         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9012                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9013                  (const_int 0)))
9014    (clobber (match_scratch:DI 0 "=r"))]
9015   "TARGET_64BIT
9016    && ix86_match_ccmode (insn, CCNOmode)
9017    && ix86_binary_operator_ok (XOR, DImode, operands)"
9018   "xor{q}\t{%2, %0|%0, %2}"
9019   [(set_attr "type" "alu")
9020    (set_attr "mode" "DI")])
9021
9022 (define_expand "xorsi3"
9023   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9024         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9025                 (match_operand:SI 2 "general_operand" "")))
9026    (clobber (reg:CC FLAGS_REG))]
9027   ""
9028   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9029
9030 (define_insn "*xorsi_1"
9031   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9032         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9033                 (match_operand:SI 2 "general_operand" "ri,rm")))
9034    (clobber (reg:CC FLAGS_REG))]
9035   "ix86_binary_operator_ok (XOR, SImode, operands)"
9036   "xor{l}\t{%2, %0|%0, %2}"
9037   [(set_attr "type" "alu")
9038    (set_attr "mode" "SI")])
9039
9040 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9041 ;; Add speccase for immediates
9042 (define_insn "*xorsi_1_zext"
9043   [(set (match_operand:DI 0 "register_operand" "=r")
9044         (zero_extend:DI
9045           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9046                   (match_operand:SI 2 "general_operand" "rim"))))
9047    (clobber (reg:CC FLAGS_REG))]
9048   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9049   "xor{l}\t{%2, %k0|%k0, %2}"
9050   [(set_attr "type" "alu")
9051    (set_attr "mode" "SI")])
9052
9053 (define_insn "*xorsi_1_zext_imm"
9054   [(set (match_operand:DI 0 "register_operand" "=r")
9055         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9056                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9057    (clobber (reg:CC FLAGS_REG))]
9058   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9059   "xor{l}\t{%2, %k0|%k0, %2}"
9060   [(set_attr "type" "alu")
9061    (set_attr "mode" "SI")])
9062
9063 (define_insn "*xorsi_2"
9064   [(set (reg FLAGS_REG)
9065         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9066                          (match_operand:SI 2 "general_operand" "rim,ri"))
9067                  (const_int 0)))
9068    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9069         (xor:SI (match_dup 1) (match_dup 2)))]
9070   "ix86_match_ccmode (insn, CCNOmode)
9071    && ix86_binary_operator_ok (XOR, SImode, operands)"
9072   "xor{l}\t{%2, %0|%0, %2}"
9073   [(set_attr "type" "alu")
9074    (set_attr "mode" "SI")])
9075
9076 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9077 ;; ??? Special case for immediate operand is missing - it is tricky.
9078 (define_insn "*xorsi_2_zext"
9079   [(set (reg FLAGS_REG)
9080         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9081                          (match_operand:SI 2 "general_operand" "rim"))
9082                  (const_int 0)))
9083    (set (match_operand:DI 0 "register_operand" "=r")
9084         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9085   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9086    && ix86_binary_operator_ok (XOR, SImode, operands)"
9087   "xor{l}\t{%2, %k0|%k0, %2}"
9088   [(set_attr "type" "alu")
9089    (set_attr "mode" "SI")])
9090
9091 (define_insn "*xorsi_2_zext_imm"
9092   [(set (reg FLAGS_REG)
9093         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9094                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9095                  (const_int 0)))
9096    (set (match_operand:DI 0 "register_operand" "=r")
9097         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9098   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9099    && ix86_binary_operator_ok (XOR, SImode, operands)"
9100   "xor{l}\t{%2, %k0|%k0, %2}"
9101   [(set_attr "type" "alu")
9102    (set_attr "mode" "SI")])
9103
9104 (define_insn "*xorsi_3"
9105   [(set (reg FLAGS_REG)
9106         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9107                          (match_operand:SI 2 "general_operand" "rim"))
9108                  (const_int 0)))
9109    (clobber (match_scratch:SI 0 "=r"))]
9110   "ix86_match_ccmode (insn, CCNOmode)
9111    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9112   "xor{l}\t{%2, %0|%0, %2}"
9113   [(set_attr "type" "alu")
9114    (set_attr "mode" "SI")])
9115
9116 (define_expand "xorhi3"
9117   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9118         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9119                 (match_operand:HI 2 "general_operand" "")))
9120    (clobber (reg:CC FLAGS_REG))]
9121   "TARGET_HIMODE_MATH"
9122   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9123
9124 (define_insn "*xorhi_1"
9125   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9126         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9127                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9128    (clobber (reg:CC FLAGS_REG))]
9129   "ix86_binary_operator_ok (XOR, HImode, operands)"
9130   "xor{w}\t{%2, %0|%0, %2}"
9131   [(set_attr "type" "alu")
9132    (set_attr "mode" "HI")])
9133
9134 (define_insn "*xorhi_2"
9135   [(set (reg FLAGS_REG)
9136         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9137                          (match_operand:HI 2 "general_operand" "rim,ri"))
9138                  (const_int 0)))
9139    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9140         (xor:HI (match_dup 1) (match_dup 2)))]
9141   "ix86_match_ccmode (insn, CCNOmode)
9142    && ix86_binary_operator_ok (XOR, HImode, operands)"
9143   "xor{w}\t{%2, %0|%0, %2}"
9144   [(set_attr "type" "alu")
9145    (set_attr "mode" "HI")])
9146
9147 (define_insn "*xorhi_3"
9148   [(set (reg FLAGS_REG)
9149         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9150                          (match_operand:HI 2 "general_operand" "rim"))
9151                  (const_int 0)))
9152    (clobber (match_scratch:HI 0 "=r"))]
9153   "ix86_match_ccmode (insn, CCNOmode)
9154    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9155   "xor{w}\t{%2, %0|%0, %2}"
9156   [(set_attr "type" "alu")
9157    (set_attr "mode" "HI")])
9158
9159 (define_expand "xorqi3"
9160   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9161         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9162                 (match_operand:QI 2 "general_operand" "")))
9163    (clobber (reg:CC FLAGS_REG))]
9164   "TARGET_QIMODE_MATH"
9165   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9166
9167 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9168 (define_insn "*xorqi_1"
9169   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9170         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9171                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9172    (clobber (reg:CC FLAGS_REG))]
9173   "ix86_binary_operator_ok (XOR, QImode, operands)"
9174   "@
9175    xor{b}\t{%2, %0|%0, %2}
9176    xor{b}\t{%2, %0|%0, %2}
9177    xor{l}\t{%k2, %k0|%k0, %k2}"
9178   [(set_attr "type" "alu")
9179    (set_attr "mode" "QI,QI,SI")])
9180
9181 (define_insn "*xorqi_1_slp"
9182   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9183         (xor:QI (match_dup 0)
9184                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9185    (clobber (reg:CC FLAGS_REG))]
9186   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9187    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9188   "xor{b}\t{%1, %0|%0, %1}"
9189   [(set_attr "type" "alu1")
9190    (set_attr "mode" "QI")])
9191
9192 (define_insn "xorqi_ext_0"
9193   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9194                          (const_int 8)
9195                          (const_int 8))
9196         (xor:SI 
9197           (zero_extract:SI
9198             (match_operand 1 "ext_register_operand" "0")
9199             (const_int 8)
9200             (const_int 8))
9201           (match_operand 2 "const_int_operand" "n")))
9202    (clobber (reg:CC FLAGS_REG))]
9203   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9204   "xor{b}\t{%2, %h0|%h0, %2}"
9205   [(set_attr "type" "alu")
9206    (set_attr "length_immediate" "1")
9207    (set_attr "mode" "QI")])
9208
9209 (define_insn "*xorqi_ext_1"
9210   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9211                          (const_int 8)
9212                          (const_int 8))
9213         (xor:SI 
9214           (zero_extract:SI
9215             (match_operand 1 "ext_register_operand" "0")
9216             (const_int 8)
9217             (const_int 8))
9218           (zero_extend:SI
9219             (match_operand:QI 2 "general_operand" "Qm"))))
9220    (clobber (reg:CC FLAGS_REG))]
9221   "!TARGET_64BIT
9222    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9223   "xor{b}\t{%2, %h0|%h0, %2}"
9224   [(set_attr "type" "alu")
9225    (set_attr "length_immediate" "0")
9226    (set_attr "mode" "QI")])
9227
9228 (define_insn "*xorqi_ext_1_rex64"
9229   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9230                          (const_int 8)
9231                          (const_int 8))
9232         (xor:SI 
9233           (zero_extract:SI
9234             (match_operand 1 "ext_register_operand" "0")
9235             (const_int 8)
9236             (const_int 8))
9237           (zero_extend:SI
9238             (match_operand 2 "ext_register_operand" "Q"))))
9239    (clobber (reg:CC FLAGS_REG))]
9240   "TARGET_64BIT
9241    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9242   "xor{b}\t{%2, %h0|%h0, %2}"
9243   [(set_attr "type" "alu")
9244    (set_attr "length_immediate" "0")
9245    (set_attr "mode" "QI")])
9246
9247 (define_insn "*xorqi_ext_2"
9248   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9249                          (const_int 8)
9250                          (const_int 8))
9251         (xor:SI 
9252           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9253                            (const_int 8)
9254                            (const_int 8))
9255           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9256                            (const_int 8)
9257                            (const_int 8))))
9258    (clobber (reg:CC FLAGS_REG))]
9259   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9260   "xor{b}\t{%h2, %h0|%h0, %h2}"
9261   [(set_attr "type" "alu")
9262    (set_attr "length_immediate" "0")
9263    (set_attr "mode" "QI")])
9264
9265 (define_insn "*xorqi_cc_1"
9266   [(set (reg FLAGS_REG)
9267         (compare
9268           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9269                   (match_operand:QI 2 "general_operand" "qim,qi"))
9270           (const_int 0)))
9271    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9272         (xor:QI (match_dup 1) (match_dup 2)))]
9273   "ix86_match_ccmode (insn, CCNOmode)
9274    && ix86_binary_operator_ok (XOR, QImode, operands)"
9275   "xor{b}\t{%2, %0|%0, %2}"
9276   [(set_attr "type" "alu")
9277    (set_attr "mode" "QI")])
9278
9279 (define_insn "*xorqi_2_slp"
9280   [(set (reg FLAGS_REG)
9281         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9282                          (match_operand:QI 1 "general_operand" "qim,qi"))
9283                  (const_int 0)))
9284    (set (strict_low_part (match_dup 0))
9285         (xor:QI (match_dup 0) (match_dup 1)))]
9286   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9287    && ix86_match_ccmode (insn, CCNOmode)
9288    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9289   "xor{b}\t{%1, %0|%0, %1}"
9290   [(set_attr "type" "alu1")
9291    (set_attr "mode" "QI")])
9292
9293 (define_insn "*xorqi_cc_2"
9294   [(set (reg FLAGS_REG)
9295         (compare
9296           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9297                   (match_operand:QI 2 "general_operand" "qim"))
9298           (const_int 0)))
9299    (clobber (match_scratch:QI 0 "=q"))]
9300   "ix86_match_ccmode (insn, CCNOmode)
9301    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9302   "xor{b}\t{%2, %0|%0, %2}"
9303   [(set_attr "type" "alu")
9304    (set_attr "mode" "QI")])
9305
9306 (define_insn "*xorqi_cc_ext_1"
9307   [(set (reg FLAGS_REG)
9308         (compare
9309           (xor:SI
9310             (zero_extract:SI
9311               (match_operand 1 "ext_register_operand" "0")
9312               (const_int 8)
9313               (const_int 8))
9314             (match_operand:QI 2 "general_operand" "qmn"))
9315           (const_int 0)))
9316    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9317                          (const_int 8)
9318                          (const_int 8))
9319         (xor:SI 
9320           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9321           (match_dup 2)))]
9322   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9323   "xor{b}\t{%2, %h0|%h0, %2}"
9324   [(set_attr "type" "alu")
9325    (set_attr "mode" "QI")])
9326
9327 (define_insn "*xorqi_cc_ext_1_rex64"
9328   [(set (reg FLAGS_REG)
9329         (compare
9330           (xor:SI
9331             (zero_extract:SI
9332               (match_operand 1 "ext_register_operand" "0")
9333               (const_int 8)
9334               (const_int 8))
9335             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9336           (const_int 0)))
9337    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9338                          (const_int 8)
9339                          (const_int 8))
9340         (xor:SI 
9341           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9342           (match_dup 2)))]
9343   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9344   "xor{b}\t{%2, %h0|%h0, %2}"
9345   [(set_attr "type" "alu")
9346    (set_attr "mode" "QI")])
9347
9348 (define_expand "xorqi_cc_ext_1"
9349   [(parallel [
9350      (set (reg:CCNO FLAGS_REG)
9351           (compare:CCNO
9352             (xor:SI
9353               (zero_extract:SI
9354                 (match_operand 1 "ext_register_operand" "")
9355                 (const_int 8)
9356                 (const_int 8))
9357               (match_operand:QI 2 "general_operand" ""))
9358             (const_int 0)))
9359      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9360                            (const_int 8)
9361                            (const_int 8))
9362           (xor:SI 
9363             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9364             (match_dup 2)))])]
9365   ""
9366   "")
9367
9368 (define_split
9369   [(set (match_operand 0 "register_operand" "")
9370         (xor (match_operand 1 "register_operand" "")
9371              (match_operand 2 "const_int_operand" "")))
9372    (clobber (reg:CC FLAGS_REG))]
9373    "reload_completed
9374     && QI_REG_P (operands[0])
9375     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9376     && !(INTVAL (operands[2]) & ~(255 << 8))
9377     && GET_MODE (operands[0]) != QImode"
9378   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9379                    (xor:SI (zero_extract:SI (match_dup 1)
9380                                             (const_int 8) (const_int 8))
9381                            (match_dup 2)))
9382               (clobber (reg:CC FLAGS_REG))])]
9383   "operands[0] = gen_lowpart (SImode, operands[0]);
9384    operands[1] = gen_lowpart (SImode, operands[1]);
9385    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9386
9387 ;; Since XOR can be encoded with sign extended immediate, this is only
9388 ;; profitable when 7th bit is set.
9389 (define_split
9390   [(set (match_operand 0 "register_operand" "")
9391         (xor (match_operand 1 "general_operand" "")
9392              (match_operand 2 "const_int_operand" "")))
9393    (clobber (reg:CC FLAGS_REG))]
9394    "reload_completed
9395     && ANY_QI_REG_P (operands[0])
9396     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9397     && !(INTVAL (operands[2]) & ~255)
9398     && (INTVAL (operands[2]) & 128)
9399     && GET_MODE (operands[0]) != QImode"
9400   [(parallel [(set (strict_low_part (match_dup 0))
9401                    (xor:QI (match_dup 1)
9402                            (match_dup 2)))
9403               (clobber (reg:CC FLAGS_REG))])]
9404   "operands[0] = gen_lowpart (QImode, operands[0]);
9405    operands[1] = gen_lowpart (QImode, operands[1]);
9406    operands[2] = gen_lowpart (QImode, operands[2]);")
9407 \f
9408 ;; Negation instructions
9409
9410 (define_expand "negdi2"
9411   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9412                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9413               (clobber (reg:CC FLAGS_REG))])]
9414   ""
9415   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9416
9417 (define_insn "*negdi2_1"
9418   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9419         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9420    (clobber (reg:CC FLAGS_REG))]
9421   "!TARGET_64BIT
9422    && ix86_unary_operator_ok (NEG, DImode, operands)"
9423   "#")
9424
9425 (define_split
9426   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9427         (neg:DI (match_operand:DI 1 "general_operand" "")))
9428    (clobber (reg:CC FLAGS_REG))]
9429   "!TARGET_64BIT && reload_completed"
9430   [(parallel
9431     [(set (reg:CCZ FLAGS_REG)
9432           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9433      (set (match_dup 0) (neg:SI (match_dup 2)))])
9434    (parallel
9435     [(set (match_dup 1)
9436           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9437                             (match_dup 3))
9438                    (const_int 0)))
9439      (clobber (reg:CC FLAGS_REG))])
9440    (parallel
9441     [(set (match_dup 1)
9442           (neg:SI (match_dup 1)))
9443      (clobber (reg:CC FLAGS_REG))])]
9444   "split_di (operands+1, 1, operands+2, operands+3);
9445    split_di (operands+0, 1, operands+0, operands+1);")
9446
9447 (define_insn "*negdi2_1_rex64"
9448   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9449         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9450    (clobber (reg:CC FLAGS_REG))]
9451   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9452   "neg{q}\t%0"
9453   [(set_attr "type" "negnot")
9454    (set_attr "mode" "DI")])
9455
9456 ;; The problem with neg is that it does not perform (compare x 0),
9457 ;; it really performs (compare 0 x), which leaves us with the zero
9458 ;; flag being the only useful item.
9459
9460 (define_insn "*negdi2_cmpz_rex64"
9461   [(set (reg:CCZ FLAGS_REG)
9462         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9463                      (const_int 0)))
9464    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9465         (neg:DI (match_dup 1)))]
9466   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9467   "neg{q}\t%0"
9468   [(set_attr "type" "negnot")
9469    (set_attr "mode" "DI")])
9470
9471
9472 (define_expand "negsi2"
9473   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9474                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9475               (clobber (reg:CC FLAGS_REG))])]
9476   ""
9477   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9478
9479 (define_insn "*negsi2_1"
9480   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9481         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9482    (clobber (reg:CC FLAGS_REG))]
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 ;; Combine is quite creative about this pattern.
9489 (define_insn "*negsi2_1_zext"
9490   [(set (match_operand:DI 0 "register_operand" "=r")
9491         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9492                                         (const_int 32)))
9493                      (const_int 32)))
9494    (clobber (reg:CC FLAGS_REG))]
9495   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9496   "neg{l}\t%k0"
9497   [(set_attr "type" "negnot")
9498    (set_attr "mode" "SI")])
9499
9500 ;; The problem with neg is that it does not perform (compare x 0),
9501 ;; it really performs (compare 0 x), which leaves us with the zero
9502 ;; flag being the only useful item.
9503
9504 (define_insn "*negsi2_cmpz"
9505   [(set (reg:CCZ FLAGS_REG)
9506         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9507                      (const_int 0)))
9508    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9509         (neg:SI (match_dup 1)))]
9510   "ix86_unary_operator_ok (NEG, SImode, operands)"
9511   "neg{l}\t%0"
9512   [(set_attr "type" "negnot")
9513    (set_attr "mode" "SI")])
9514
9515 (define_insn "*negsi2_cmpz_zext"
9516   [(set (reg:CCZ FLAGS_REG)
9517         (compare:CCZ (lshiftrt:DI
9518                        (neg:DI (ashift:DI
9519                                  (match_operand:DI 1 "register_operand" "0")
9520                                  (const_int 32)))
9521                        (const_int 32))
9522                      (const_int 0)))
9523    (set (match_operand:DI 0 "register_operand" "=r")
9524         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9525                                         (const_int 32)))
9526                      (const_int 32)))]
9527   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9528   "neg{l}\t%k0"
9529   [(set_attr "type" "negnot")
9530    (set_attr "mode" "SI")])
9531
9532 (define_expand "neghi2"
9533   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9534                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9535               (clobber (reg:CC FLAGS_REG))])]
9536   "TARGET_HIMODE_MATH"
9537   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9538
9539 (define_insn "*neghi2_1"
9540   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9541         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9542    (clobber (reg:CC FLAGS_REG))]
9543   "ix86_unary_operator_ok (NEG, HImode, operands)"
9544   "neg{w}\t%0"
9545   [(set_attr "type" "negnot")
9546    (set_attr "mode" "HI")])
9547
9548 (define_insn "*neghi2_cmpz"
9549   [(set (reg:CCZ FLAGS_REG)
9550         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9551                      (const_int 0)))
9552    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9553         (neg:HI (match_dup 1)))]
9554   "ix86_unary_operator_ok (NEG, HImode, operands)"
9555   "neg{w}\t%0"
9556   [(set_attr "type" "negnot")
9557    (set_attr "mode" "HI")])
9558
9559 (define_expand "negqi2"
9560   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9561                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9562               (clobber (reg:CC FLAGS_REG))])]
9563   "TARGET_QIMODE_MATH"
9564   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9565
9566 (define_insn "*negqi2_1"
9567   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9568         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9569    (clobber (reg:CC FLAGS_REG))]
9570   "ix86_unary_operator_ok (NEG, QImode, operands)"
9571   "neg{b}\t%0"
9572   [(set_attr "type" "negnot")
9573    (set_attr "mode" "QI")])
9574
9575 (define_insn "*negqi2_cmpz"
9576   [(set (reg:CCZ FLAGS_REG)
9577         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9578                      (const_int 0)))
9579    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9580         (neg:QI (match_dup 1)))]
9581   "ix86_unary_operator_ok (NEG, QImode, operands)"
9582   "neg{b}\t%0"
9583   [(set_attr "type" "negnot")
9584    (set_attr "mode" "QI")])
9585
9586 ;; Changing of sign for FP values is doable using integer unit too.
9587
9588 (define_expand "negsf2"
9589   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9590         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9591   "TARGET_80387 || TARGET_SSE_MATH"
9592   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9593
9594 (define_expand "abssf2"
9595   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9596         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9597   "TARGET_80387 || TARGET_SSE_MATH"
9598   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9599
9600 (define_insn "*absnegsf2_mixed"
9601   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#fr,x#fr,f#xr,rm#xf")
9602         (match_operator:SF 3 "absneg_operator"
9603           [(match_operand:SF 1 "nonimmediate_operand" "0    ,x#fr,0   ,0")]))
9604    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm   ,0   ,X   ,X"))
9605    (clobber (reg:CC FLAGS_REG))]
9606   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9607    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9608   "#")
9609
9610 (define_insn "*absnegsf2_sse"
9611   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#r,x#r,rm#x")
9612         (match_operator:SF 3 "absneg_operator"
9613           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#r,0")]))
9614    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X"))
9615    (clobber (reg:CC FLAGS_REG))]
9616   "TARGET_SSE_MATH
9617    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9618   "#")
9619
9620 (define_insn "*absnegsf2_i387"
9621   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9622         (match_operator:SF 3 "absneg_operator"
9623           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9624    (use (match_operand 2 "" ""))
9625    (clobber (reg:CC FLAGS_REG))]
9626   "TARGET_80387 && !TARGET_SSE_MATH
9627    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9628   "#")
9629
9630 (define_expand "negdf2"
9631   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9632         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9633   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9634   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9635
9636 (define_expand "absdf2"
9637   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9638         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9639   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9640   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9641
9642 (define_insn "*absnegdf2_mixed"
9643   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#fr,Y#fr,f#Yr,rm#Yf")
9644         (match_operator:DF 3 "absneg_operator"
9645           [(match_operand:DF 1 "nonimmediate_operand" "0    ,Y#fr,0   ,0")]))
9646    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym   ,0   ,X   ,X"))
9647    (clobber (reg:CC FLAGS_REG))]
9648   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9649    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9650   "#")
9651
9652 (define_insn "*absnegdf2_sse"
9653   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#r,Y#r,rm#Y")
9654         (match_operator:DF 3 "absneg_operator"
9655           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#r,0")]))
9656    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X"))
9657    (clobber (reg:CC FLAGS_REG))]
9658   "TARGET_SSE2 && TARGET_SSE_MATH
9659    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9660   "#")
9661
9662 (define_insn "*absnegdf2_i387"
9663   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9664         (match_operator:DF 3 "absneg_operator"
9665           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9666    (use (match_operand 2 "" ""))
9667    (clobber (reg:CC FLAGS_REG))]
9668   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9669    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9670   "#")
9671
9672 (define_expand "negxf2"
9673   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9674         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9675   "TARGET_80387"
9676   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9677
9678 (define_expand "absxf2"
9679   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9680         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9681   "TARGET_80387"
9682   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9683
9684 (define_insn "*absnegxf2_i387"
9685   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9686         (match_operator:XF 3 "absneg_operator"
9687           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9688    (use (match_operand 2 "" ""))
9689    (clobber (reg:CC FLAGS_REG))]
9690   "TARGET_80387
9691    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9692   "#")
9693
9694 ;; Splitters for fp abs and neg.
9695
9696 (define_split
9697   [(set (match_operand 0 "fp_register_operand" "")
9698         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9699    (use (match_operand 2 "" ""))
9700    (clobber (reg:CC FLAGS_REG))]
9701   "reload_completed"
9702   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9703
9704 (define_split
9705   [(set (match_operand 0 "register_operand" "")
9706         (match_operator 3 "absneg_operator"
9707           [(match_operand 1 "register_operand" "")]))
9708    (use (match_operand 2 "nonimmediate_operand" ""))
9709    (clobber (reg:CC FLAGS_REG))]
9710   "reload_completed && SSE_REG_P (operands[0])"
9711   [(set (match_dup 0) (match_dup 3))]
9712 {
9713   enum machine_mode mode = GET_MODE (operands[0]);
9714   enum machine_mode vmode = GET_MODE (operands[2]);
9715   rtx tmp;
9716   
9717   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9718   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9719   if (operands_match_p (operands[0], operands[2]))
9720     {
9721       tmp = operands[1];
9722       operands[1] = operands[2];
9723       operands[2] = tmp;
9724     }
9725   if (GET_CODE (operands[3]) == ABS)
9726     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9727   else
9728     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9729   operands[3] = tmp;
9730 })
9731
9732 (define_split
9733   [(set (match_operand:SF 0 "register_operand" "")
9734         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9735    (use (match_operand:V4SF 2 "" ""))
9736    (clobber (reg:CC FLAGS_REG))]
9737   "reload_completed"
9738   [(parallel [(set (match_dup 0) (match_dup 1))
9739               (clobber (reg:CC FLAGS_REG))])]
9740
9741   rtx tmp;
9742   operands[0] = gen_lowpart (SImode, operands[0]);
9743   if (GET_CODE (operands[1]) == ABS)
9744     {
9745       tmp = gen_int_mode (0x7fffffff, SImode);
9746       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9747     }
9748   else
9749     {
9750       tmp = gen_int_mode (0x80000000, SImode);
9751       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9752     }
9753   operands[1] = tmp;
9754 })
9755
9756 (define_split
9757   [(set (match_operand:DF 0 "register_operand" "")
9758         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9759    (use (match_operand 2 "" ""))
9760    (clobber (reg:CC FLAGS_REG))]
9761   "reload_completed"
9762   [(parallel [(set (match_dup 0) (match_dup 1))
9763               (clobber (reg:CC FLAGS_REG))])]
9764 {
9765   rtx tmp;
9766   if (TARGET_64BIT)
9767     {
9768       tmp = gen_lowpart (DImode, operands[0]);
9769       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9770       operands[0] = tmp;
9771
9772       if (GET_CODE (operands[1]) == ABS)
9773         tmp = const0_rtx;
9774       else
9775         tmp = gen_rtx_NOT (DImode, tmp);
9776     }
9777   else
9778     {
9779       operands[0] = gen_highpart (SImode, operands[0]);
9780       if (GET_CODE (operands[1]) == ABS)
9781         {
9782           tmp = gen_int_mode (0x7fffffff, SImode);
9783           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9784         }
9785       else
9786         {
9787           tmp = gen_int_mode (0x80000000, SImode);
9788           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9789         }
9790     }
9791   operands[1] = tmp;
9792 })
9793
9794 (define_split
9795   [(set (match_operand:XF 0 "register_operand" "")
9796         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9797    (use (match_operand 2 "" ""))
9798    (clobber (reg:CC FLAGS_REG))]
9799   "reload_completed"
9800   [(parallel [(set (match_dup 0) (match_dup 1))
9801               (clobber (reg:CC FLAGS_REG))])]
9802 {
9803   rtx tmp;
9804   operands[0] = gen_rtx_REG (SImode,
9805                              true_regnum (operands[0])
9806                              + (TARGET_64BIT ? 1 : 2));
9807   if (GET_CODE (operands[1]) == ABS)
9808     {
9809       tmp = GEN_INT (0x7fff);
9810       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9811     }
9812   else
9813     {
9814       tmp = GEN_INT (0x8000);
9815       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9816     }
9817   operands[1] = tmp;
9818 })
9819
9820 (define_split
9821   [(set (match_operand 0 "memory_operand" "")
9822         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9823    (use (match_operand 2 "" ""))
9824    (clobber (reg:CC FLAGS_REG))]
9825   "reload_completed"
9826   [(parallel [(set (match_dup 0) (match_dup 1))
9827               (clobber (reg:CC FLAGS_REG))])]
9828 {
9829   enum machine_mode mode = GET_MODE (operands[0]);
9830   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9831   rtx tmp;
9832
9833   operands[0] = adjust_address (operands[0], QImode, size - 1);
9834   if (GET_CODE (operands[1]) == ABS)
9835     {
9836       tmp = gen_int_mode (0x7f, QImode);
9837       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9838     }
9839   else
9840     {
9841       tmp = gen_int_mode (0x80, QImode);
9842       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9843     }
9844   operands[1] = tmp;
9845 })
9846
9847 ;; Conditionalize these after reload. If they match before reload, we 
9848 ;; lose the clobber and ability to use integer instructions.
9849
9850 (define_insn "*negsf2_1"
9851   [(set (match_operand:SF 0 "register_operand" "=f")
9852         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9853   "TARGET_80387 && reload_completed"
9854   "fchs"
9855   [(set_attr "type" "fsgn")
9856    (set_attr "mode" "SF")])
9857
9858 (define_insn "*negdf2_1"
9859   [(set (match_operand:DF 0 "register_operand" "=f")
9860         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9861   "TARGET_80387 && reload_completed"
9862   "fchs"
9863   [(set_attr "type" "fsgn")
9864    (set_attr "mode" "DF")])
9865
9866 (define_insn "*negxf2_1"
9867   [(set (match_operand:XF 0 "register_operand" "=f")
9868         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9869   "TARGET_80387 && reload_completed"
9870   "fchs"
9871   [(set_attr "type" "fsgn")
9872    (set_attr "mode" "XF")])
9873
9874 (define_insn "*abssf2_1"
9875   [(set (match_operand:SF 0 "register_operand" "=f")
9876         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9877   "TARGET_80387 && reload_completed"
9878   "fabs"
9879   [(set_attr "type" "fsgn")
9880    (set_attr "mode" "SF")])
9881
9882 (define_insn "*absdf2_1"
9883   [(set (match_operand:DF 0 "register_operand" "=f")
9884         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9885   "TARGET_80387 && reload_completed"
9886   "fabs"
9887   [(set_attr "type" "fsgn")
9888    (set_attr "mode" "DF")])
9889
9890 (define_insn "*absxf2_1"
9891   [(set (match_operand:XF 0 "register_operand" "=f")
9892         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9893   "TARGET_80387 && reload_completed"
9894   "fabs"
9895   [(set_attr "type" "fsgn")
9896    (set_attr "mode" "DF")])
9897
9898 (define_insn "*negextendsfdf2"
9899   [(set (match_operand:DF 0 "register_operand" "=f")
9900         (neg:DF (float_extend:DF
9901                   (match_operand:SF 1 "register_operand" "0"))))]
9902   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9903   "fchs"
9904   [(set_attr "type" "fsgn")
9905    (set_attr "mode" "DF")])
9906
9907 (define_insn "*negextenddfxf2"
9908   [(set (match_operand:XF 0 "register_operand" "=f")
9909         (neg:XF (float_extend:XF
9910                   (match_operand:DF 1 "register_operand" "0"))))]
9911   "TARGET_80387"
9912   "fchs"
9913   [(set_attr "type" "fsgn")
9914    (set_attr "mode" "XF")])
9915
9916 (define_insn "*negextendsfxf2"
9917   [(set (match_operand:XF 0 "register_operand" "=f")
9918         (neg:XF (float_extend:XF
9919                   (match_operand:SF 1 "register_operand" "0"))))]
9920   "TARGET_80387"
9921   "fchs"
9922   [(set_attr "type" "fsgn")
9923    (set_attr "mode" "XF")])
9924
9925 (define_insn "*absextendsfdf2"
9926   [(set (match_operand:DF 0 "register_operand" "=f")
9927         (abs:DF (float_extend:DF
9928                   (match_operand:SF 1 "register_operand" "0"))))]
9929   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9930   "fabs"
9931   [(set_attr "type" "fsgn")
9932    (set_attr "mode" "DF")])
9933
9934 (define_insn "*absextenddfxf2"
9935   [(set (match_operand:XF 0 "register_operand" "=f")
9936         (abs:XF (float_extend:XF
9937           (match_operand:DF 1 "register_operand" "0"))))]
9938   "TARGET_80387"
9939   "fabs"
9940   [(set_attr "type" "fsgn")
9941    (set_attr "mode" "XF")])
9942
9943 (define_insn "*absextendsfxf2"
9944   [(set (match_operand:XF 0 "register_operand" "=f")
9945         (abs:XF (float_extend:XF
9946           (match_operand:SF 1 "register_operand" "0"))))]
9947   "TARGET_80387"
9948   "fabs"
9949   [(set_attr "type" "fsgn")
9950    (set_attr "mode" "XF")])
9951 \f
9952 ;; One complement instructions
9953
9954 (define_expand "one_cmpldi2"
9955   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9956         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9957   "TARGET_64BIT"
9958   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9959
9960 (define_insn "*one_cmpldi2_1_rex64"
9961   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9962         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9963   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9964   "not{q}\t%0"
9965   [(set_attr "type" "negnot")
9966    (set_attr "mode" "DI")])
9967
9968 (define_insn "*one_cmpldi2_2_rex64"
9969   [(set (reg FLAGS_REG)
9970         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9971                  (const_int 0)))
9972    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9973         (not:DI (match_dup 1)))]
9974   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9975    && ix86_unary_operator_ok (NOT, DImode, operands)"
9976   "#"
9977   [(set_attr "type" "alu1")
9978    (set_attr "mode" "DI")])
9979
9980 (define_split
9981   [(set (match_operand 0 "flags_reg_operand" "")
9982         (match_operator 2 "compare_operator"
9983           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9984            (const_int 0)]))
9985    (set (match_operand:DI 1 "nonimmediate_operand" "")
9986         (not:DI (match_dup 3)))]
9987   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9988   [(parallel [(set (match_dup 0)
9989                    (match_op_dup 2
9990                      [(xor:DI (match_dup 3) (const_int -1))
9991                       (const_int 0)]))
9992               (set (match_dup 1)
9993                    (xor:DI (match_dup 3) (const_int -1)))])]
9994   "")
9995
9996 (define_expand "one_cmplsi2"
9997   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9998         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9999   ""
10000   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10001
10002 (define_insn "*one_cmplsi2_1"
10003   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10004         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10005   "ix86_unary_operator_ok (NOT, SImode, operands)"
10006   "not{l}\t%0"
10007   [(set_attr "type" "negnot")
10008    (set_attr "mode" "SI")])
10009
10010 ;; ??? Currently never generated - xor is used instead.
10011 (define_insn "*one_cmplsi2_1_zext"
10012   [(set (match_operand:DI 0 "register_operand" "=r")
10013         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10014   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10015   "not{l}\t%k0"
10016   [(set_attr "type" "negnot")
10017    (set_attr "mode" "SI")])
10018
10019 (define_insn "*one_cmplsi2_2"
10020   [(set (reg FLAGS_REG)
10021         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10022                  (const_int 0)))
10023    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10024         (not:SI (match_dup 1)))]
10025   "ix86_match_ccmode (insn, CCNOmode)
10026    && ix86_unary_operator_ok (NOT, SImode, operands)"
10027   "#"
10028   [(set_attr "type" "alu1")
10029    (set_attr "mode" "SI")])
10030
10031 (define_split
10032   [(set (match_operand 0 "flags_reg_operand" "")
10033         (match_operator 2 "compare_operator"
10034           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10035            (const_int 0)]))
10036    (set (match_operand:SI 1 "nonimmediate_operand" "")
10037         (not:SI (match_dup 3)))]
10038   "ix86_match_ccmode (insn, CCNOmode)"
10039   [(parallel [(set (match_dup 0)
10040                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10041                                     (const_int 0)]))
10042               (set (match_dup 1)
10043                    (xor:SI (match_dup 3) (const_int -1)))])]
10044   "")
10045
10046 ;; ??? Currently never generated - xor is used instead.
10047 (define_insn "*one_cmplsi2_2_zext"
10048   [(set (reg FLAGS_REG)
10049         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10050                  (const_int 0)))
10051    (set (match_operand:DI 0 "register_operand" "=r")
10052         (zero_extend:DI (not:SI (match_dup 1))))]
10053   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10054    && ix86_unary_operator_ok (NOT, SImode, operands)"
10055   "#"
10056   [(set_attr "type" "alu1")
10057    (set_attr "mode" "SI")])
10058
10059 (define_split
10060   [(set (match_operand 0 "flags_reg_operand" "")
10061         (match_operator 2 "compare_operator"
10062           [(not:SI (match_operand:SI 3 "register_operand" ""))
10063            (const_int 0)]))
10064    (set (match_operand:DI 1 "register_operand" "")
10065         (zero_extend:DI (not:SI (match_dup 3))))]
10066   "ix86_match_ccmode (insn, CCNOmode)"
10067   [(parallel [(set (match_dup 0)
10068                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10069                                     (const_int 0)]))
10070               (set (match_dup 1)
10071                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10072   "")
10073
10074 (define_expand "one_cmplhi2"
10075   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10076         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10077   "TARGET_HIMODE_MATH"
10078   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10079
10080 (define_insn "*one_cmplhi2_1"
10081   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10082         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10083   "ix86_unary_operator_ok (NOT, HImode, operands)"
10084   "not{w}\t%0"
10085   [(set_attr "type" "negnot")
10086    (set_attr "mode" "HI")])
10087
10088 (define_insn "*one_cmplhi2_2"
10089   [(set (reg FLAGS_REG)
10090         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10091                  (const_int 0)))
10092    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10093         (not:HI (match_dup 1)))]
10094   "ix86_match_ccmode (insn, CCNOmode)
10095    && ix86_unary_operator_ok (NEG, HImode, operands)"
10096   "#"
10097   [(set_attr "type" "alu1")
10098    (set_attr "mode" "HI")])
10099
10100 (define_split
10101   [(set (match_operand 0 "flags_reg_operand" "")
10102         (match_operator 2 "compare_operator"
10103           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10104            (const_int 0)]))
10105    (set (match_operand:HI 1 "nonimmediate_operand" "")
10106         (not:HI (match_dup 3)))]
10107   "ix86_match_ccmode (insn, CCNOmode)"
10108   [(parallel [(set (match_dup 0)
10109                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10110                                     (const_int 0)]))
10111               (set (match_dup 1)
10112                    (xor:HI (match_dup 3) (const_int -1)))])]
10113   "")
10114
10115 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10116 (define_expand "one_cmplqi2"
10117   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10118         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10119   "TARGET_QIMODE_MATH"
10120   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10121
10122 (define_insn "*one_cmplqi2_1"
10123   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10124         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10125   "ix86_unary_operator_ok (NOT, QImode, operands)"
10126   "@
10127    not{b}\t%0
10128    not{l}\t%k0"
10129   [(set_attr "type" "negnot")
10130    (set_attr "mode" "QI,SI")])
10131
10132 (define_insn "*one_cmplqi2_2"
10133   [(set (reg FLAGS_REG)
10134         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10135                  (const_int 0)))
10136    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10137         (not:QI (match_dup 1)))]
10138   "ix86_match_ccmode (insn, CCNOmode)
10139    && ix86_unary_operator_ok (NOT, QImode, operands)"
10140   "#"
10141   [(set_attr "type" "alu1")
10142    (set_attr "mode" "QI")])
10143
10144 (define_split
10145   [(set (match_operand 0 "flags_reg_operand" "")
10146         (match_operator 2 "compare_operator"
10147           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10148            (const_int 0)]))
10149    (set (match_operand:QI 1 "nonimmediate_operand" "")
10150         (not:QI (match_dup 3)))]
10151   "ix86_match_ccmode (insn, CCNOmode)"
10152   [(parallel [(set (match_dup 0)
10153                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10154                                     (const_int 0)]))
10155               (set (match_dup 1)
10156                    (xor:QI (match_dup 3) (const_int -1)))])]
10157   "")
10158 \f
10159 ;; Arithmetic shift instructions
10160
10161 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10162 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10163 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10164 ;; from the assembler input.
10165 ;;
10166 ;; This instruction shifts the target reg/mem as usual, but instead of
10167 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10168 ;; is a left shift double, bits are taken from the high order bits of
10169 ;; reg, else if the insn is a shift right double, bits are taken from the
10170 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10171 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10172 ;;
10173 ;; Since sh[lr]d does not change the `reg' operand, that is done
10174 ;; separately, making all shifts emit pairs of shift double and normal
10175 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10176 ;; support a 63 bit shift, each shift where the count is in a reg expands
10177 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10178 ;;
10179 ;; If the shift count is a constant, we need never emit more than one
10180 ;; shift pair, instead using moves and sign extension for counts greater
10181 ;; than 31.
10182
10183 (define_expand "ashldi3"
10184   [(set (match_operand:DI 0 "shiftdi_operand" "")
10185         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10186                    (match_operand:QI 2 "nonmemory_operand" "")))]
10187   ""
10188   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10189
10190 (define_insn "*ashldi3_1_rex64"
10191   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10192         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10193                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10194    (clobber (reg:CC FLAGS_REG))]
10195   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10196 {
10197   switch (get_attr_type (insn))
10198     {
10199     case TYPE_ALU:
10200       if (operands[2] != const1_rtx)
10201         abort ();
10202       if (!rtx_equal_p (operands[0], operands[1]))
10203         abort ();
10204       return "add{q}\t{%0, %0|%0, %0}";
10205
10206     case TYPE_LEA:
10207       if (GET_CODE (operands[2]) != CONST_INT
10208           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10209         abort ();
10210       operands[1] = gen_rtx_MULT (DImode, operands[1],
10211                                   GEN_INT (1 << INTVAL (operands[2])));
10212       return "lea{q}\t{%a1, %0|%0, %a1}";
10213
10214     default:
10215       if (REG_P (operands[2]))
10216         return "sal{q}\t{%b2, %0|%0, %b2}";
10217       else if (operands[2] == const1_rtx
10218                && (TARGET_SHIFT1 || optimize_size))
10219         return "sal{q}\t%0";
10220       else
10221         return "sal{q}\t{%2, %0|%0, %2}";
10222     }
10223 }
10224   [(set (attr "type")
10225      (cond [(eq_attr "alternative" "1")
10226               (const_string "lea")
10227             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10228                           (const_int 0))
10229                       (match_operand 0 "register_operand" ""))
10230                  (match_operand 2 "const1_operand" ""))
10231               (const_string "alu")
10232            ]
10233            (const_string "ishift")))
10234    (set_attr "mode" "DI")])
10235
10236 ;; Convert lea to the lea pattern to avoid flags dependency.
10237 (define_split
10238   [(set (match_operand:DI 0 "register_operand" "")
10239         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10240                    (match_operand:QI 2 "immediate_operand" "")))
10241    (clobber (reg:CC FLAGS_REG))]
10242   "TARGET_64BIT && reload_completed
10243    && true_regnum (operands[0]) != true_regnum (operands[1])"
10244   [(set (match_dup 0)
10245         (mult:DI (match_dup 1)
10246                  (match_dup 2)))]
10247   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10248
10249 ;; This pattern can't accept a variable shift count, since shifts by
10250 ;; zero don't affect the flags.  We assume that shifts by constant
10251 ;; zero are optimized away.
10252 (define_insn "*ashldi3_cmp_rex64"
10253   [(set (reg FLAGS_REG)
10254         (compare
10255           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10256                      (match_operand:QI 2 "immediate_operand" "e"))
10257           (const_int 0)))
10258    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10259         (ashift:DI (match_dup 1) (match_dup 2)))]
10260   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10261    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10262 {
10263   switch (get_attr_type (insn))
10264     {
10265     case TYPE_ALU:
10266       if (operands[2] != const1_rtx)
10267         abort ();
10268       return "add{q}\t{%0, %0|%0, %0}";
10269
10270     default:
10271       if (REG_P (operands[2]))
10272         return "sal{q}\t{%b2, %0|%0, %b2}";
10273       else if (operands[2] == const1_rtx
10274                && (TARGET_SHIFT1 || optimize_size))
10275         return "sal{q}\t%0";
10276       else
10277         return "sal{q}\t{%2, %0|%0, %2}";
10278     }
10279 }
10280   [(set (attr "type")
10281      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10282                           (const_int 0))
10283                       (match_operand 0 "register_operand" ""))
10284                  (match_operand 2 "const1_operand" ""))
10285               (const_string "alu")
10286            ]
10287            (const_string "ishift")))
10288    (set_attr "mode" "DI")])
10289
10290 (define_insn "*ashldi3_1"
10291   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10292         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10293                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10294    (clobber (reg:CC FLAGS_REG))]
10295   "!TARGET_64BIT"
10296   "#"
10297   [(set_attr "type" "multi")])
10298
10299 ;; By default we don't ask for a scratch register, because when DImode
10300 ;; values are manipulated, registers are already at a premium.  But if
10301 ;; we have one handy, we won't turn it away.
10302 (define_peephole2
10303   [(match_scratch:SI 3 "r")
10304    (parallel [(set (match_operand:DI 0 "register_operand" "")
10305                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10306                               (match_operand:QI 2 "nonmemory_operand" "")))
10307               (clobber (reg:CC FLAGS_REG))])
10308    (match_dup 3)]
10309   "!TARGET_64BIT && TARGET_CMOVE"
10310   [(const_int 0)]
10311   "ix86_split_ashldi (operands, operands[3]); DONE;")
10312
10313 (define_split
10314   [(set (match_operand:DI 0 "register_operand" "")
10315         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10316                    (match_operand:QI 2 "nonmemory_operand" "")))
10317    (clobber (reg:CC FLAGS_REG))]
10318   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10319   [(const_int 0)]
10320   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10321
10322 (define_insn "x86_shld_1"
10323   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10324         (ior:SI (ashift:SI (match_dup 0)
10325                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10326                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10327                   (minus:QI (const_int 32) (match_dup 2)))))
10328    (clobber (reg:CC FLAGS_REG))]
10329   ""
10330   "@
10331    shld{l}\t{%2, %1, %0|%0, %1, %2}
10332    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10333   [(set_attr "type" "ishift")
10334    (set_attr "prefix_0f" "1")
10335    (set_attr "mode" "SI")
10336    (set_attr "pent_pair" "np")
10337    (set_attr "athlon_decode" "vector")])
10338
10339 (define_expand "x86_shift_adj_1"
10340   [(set (reg:CCZ FLAGS_REG)
10341         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10342                              (const_int 32))
10343                      (const_int 0)))
10344    (set (match_operand:SI 0 "register_operand" "")
10345         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10346                          (match_operand:SI 1 "register_operand" "")
10347                          (match_dup 0)))
10348    (set (match_dup 1)
10349         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10350                          (match_operand:SI 3 "register_operand" "r")
10351                          (match_dup 1)))]
10352   "TARGET_CMOVE"
10353   "")
10354
10355 (define_expand "x86_shift_adj_2"
10356   [(use (match_operand:SI 0 "register_operand" ""))
10357    (use (match_operand:SI 1 "register_operand" ""))
10358    (use (match_operand:QI 2 "register_operand" ""))]
10359   ""
10360 {
10361   rtx label = gen_label_rtx ();
10362   rtx tmp;
10363
10364   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10365
10366   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10367   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10368   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10369                               gen_rtx_LABEL_REF (VOIDmode, label),
10370                               pc_rtx);
10371   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10372   JUMP_LABEL (tmp) = label;
10373
10374   emit_move_insn (operands[0], operands[1]);
10375   ix86_expand_clear (operands[1]);
10376
10377   emit_label (label);
10378   LABEL_NUSES (label) = 1;
10379
10380   DONE;
10381 })
10382
10383 (define_expand "ashlsi3"
10384   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10385         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10386                    (match_operand:QI 2 "nonmemory_operand" "")))
10387    (clobber (reg:CC FLAGS_REG))]
10388   ""
10389   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10390
10391 (define_insn "*ashlsi3_1"
10392   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10393         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10394                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10395    (clobber (reg:CC FLAGS_REG))]
10396   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10397 {
10398   switch (get_attr_type (insn))
10399     {
10400     case TYPE_ALU:
10401       if (operands[2] != const1_rtx)
10402         abort ();
10403       if (!rtx_equal_p (operands[0], operands[1]))
10404         abort ();
10405       return "add{l}\t{%0, %0|%0, %0}";
10406
10407     case TYPE_LEA:
10408       return "#";
10409
10410     default:
10411       if (REG_P (operands[2]))
10412         return "sal{l}\t{%b2, %0|%0, %b2}";
10413       else if (operands[2] == const1_rtx
10414                && (TARGET_SHIFT1 || optimize_size))
10415         return "sal{l}\t%0";
10416       else
10417         return "sal{l}\t{%2, %0|%0, %2}";
10418     }
10419 }
10420   [(set (attr "type")
10421      (cond [(eq_attr "alternative" "1")
10422               (const_string "lea")
10423             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10424                           (const_int 0))
10425                       (match_operand 0 "register_operand" ""))
10426                  (match_operand 2 "const1_operand" ""))
10427               (const_string "alu")
10428            ]
10429            (const_string "ishift")))
10430    (set_attr "mode" "SI")])
10431
10432 ;; Convert lea to the lea pattern to avoid flags dependency.
10433 (define_split
10434   [(set (match_operand 0 "register_operand" "")
10435         (ashift (match_operand 1 "index_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    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10441   [(const_int 0)]
10442 {
10443   rtx pat;
10444   enum machine_mode mode = GET_MODE (operands[0]);
10445
10446   if (GET_MODE_SIZE (mode) < 4)
10447     operands[0] = gen_lowpart (SImode, operands[0]);
10448   if (mode != Pmode)
10449     operands[1] = gen_lowpart (Pmode, operands[1]);
10450   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10451
10452   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10453   if (Pmode != SImode)
10454     pat = gen_rtx_SUBREG (SImode, pat, 0);
10455   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10456   DONE;
10457 })
10458
10459 ;; Rare case of shifting RSP is handled by generating move and shift
10460 (define_split
10461   [(set (match_operand 0 "register_operand" "")
10462         (ashift (match_operand 1 "register_operand" "")
10463                 (match_operand:QI 2 "const_int_operand" "")))
10464    (clobber (reg:CC FLAGS_REG))]
10465   "reload_completed
10466    && true_regnum (operands[0]) != true_regnum (operands[1])"
10467   [(const_int 0)]
10468 {
10469   rtx pat, clob;
10470   emit_move_insn (operands[1], operands[0]);
10471   pat = gen_rtx_SET (VOIDmode, operands[0],
10472                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10473                                      operands[0], operands[2]));
10474   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10475   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10476   DONE;
10477 })
10478
10479 (define_insn "*ashlsi3_1_zext"
10480   [(set (match_operand:DI 0 "register_operand" "=r,r")
10481         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10482                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10483    (clobber (reg:CC FLAGS_REG))]
10484   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10485 {
10486   switch (get_attr_type (insn))
10487     {
10488     case TYPE_ALU:
10489       if (operands[2] != const1_rtx)
10490         abort ();
10491       return "add{l}\t{%k0, %k0|%k0, %k0}";
10492
10493     case TYPE_LEA:
10494       return "#";
10495
10496     default:
10497       if (REG_P (operands[2]))
10498         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10499       else if (operands[2] == const1_rtx
10500                && (TARGET_SHIFT1 || optimize_size))
10501         return "sal{l}\t%k0";
10502       else
10503         return "sal{l}\t{%2, %k0|%k0, %2}";
10504     }
10505 }
10506   [(set (attr "type")
10507      (cond [(eq_attr "alternative" "1")
10508               (const_string "lea")
10509             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10510                      (const_int 0))
10511                  (match_operand 2 "const1_operand" ""))
10512               (const_string "alu")
10513            ]
10514            (const_string "ishift")))
10515    (set_attr "mode" "SI")])
10516
10517 ;; Convert lea to the lea pattern to avoid flags dependency.
10518 (define_split
10519   [(set (match_operand:DI 0 "register_operand" "")
10520         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10521                                 (match_operand:QI 2 "const_int_operand" ""))))
10522    (clobber (reg:CC FLAGS_REG))]
10523   "TARGET_64BIT && reload_completed
10524    && true_regnum (operands[0]) != true_regnum (operands[1])"
10525   [(set (match_dup 0) (zero_extend:DI
10526                         (subreg:SI (mult:SI (match_dup 1)
10527                                             (match_dup 2)) 0)))]
10528 {
10529   operands[1] = gen_lowpart (Pmode, operands[1]);
10530   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10531 })
10532
10533 ;; This pattern can't accept a variable shift count, since shifts by
10534 ;; zero don't affect the flags.  We assume that shifts by constant
10535 ;; zero are optimized away.
10536 (define_insn "*ashlsi3_cmp"
10537   [(set (reg FLAGS_REG)
10538         (compare
10539           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10540                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10541           (const_int 0)))
10542    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10543         (ashift:SI (match_dup 1) (match_dup 2)))]
10544   "ix86_match_ccmode (insn, CCGOCmode)
10545    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10546 {
10547   switch (get_attr_type (insn))
10548     {
10549     case TYPE_ALU:
10550       if (operands[2] != const1_rtx)
10551         abort ();
10552       return "add{l}\t{%0, %0|%0, %0}";
10553
10554     default:
10555       if (REG_P (operands[2]))
10556         return "sal{l}\t{%b2, %0|%0, %b2}";
10557       else if (operands[2] == const1_rtx
10558                && (TARGET_SHIFT1 || optimize_size))
10559         return "sal{l}\t%0";
10560       else
10561         return "sal{l}\t{%2, %0|%0, %2}";
10562     }
10563 }
10564   [(set (attr "type")
10565      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10566                           (const_int 0))
10567                       (match_operand 0 "register_operand" ""))
10568                  (match_operand 2 "const1_operand" ""))
10569               (const_string "alu")
10570            ]
10571            (const_string "ishift")))
10572    (set_attr "mode" "SI")])
10573
10574 (define_insn "*ashlsi3_cmp_zext"
10575   [(set (reg FLAGS_REG)
10576         (compare
10577           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10578                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10579           (const_int 0)))
10580    (set (match_operand:DI 0 "register_operand" "=r")
10581         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10582   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10583    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10584 {
10585   switch (get_attr_type (insn))
10586     {
10587     case TYPE_ALU:
10588       if (operands[2] != const1_rtx)
10589         abort ();
10590       return "add{l}\t{%k0, %k0|%k0, %k0}";
10591
10592     default:
10593       if (REG_P (operands[2]))
10594         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10595       else if (operands[2] == const1_rtx
10596                && (TARGET_SHIFT1 || optimize_size))
10597         return "sal{l}\t%k0";
10598       else
10599         return "sal{l}\t{%2, %k0|%k0, %2}";
10600     }
10601 }
10602   [(set (attr "type")
10603      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10604                      (const_int 0))
10605                  (match_operand 2 "const1_operand" ""))
10606               (const_string "alu")
10607            ]
10608            (const_string "ishift")))
10609    (set_attr "mode" "SI")])
10610
10611 (define_expand "ashlhi3"
10612   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10613         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10614                    (match_operand:QI 2 "nonmemory_operand" "")))
10615    (clobber (reg:CC FLAGS_REG))]
10616   "TARGET_HIMODE_MATH"
10617   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10618
10619 (define_insn "*ashlhi3_1_lea"
10620   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10621         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10622                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10623    (clobber (reg:CC FLAGS_REG))]
10624   "!TARGET_PARTIAL_REG_STALL
10625    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10626 {
10627   switch (get_attr_type (insn))
10628     {
10629     case TYPE_LEA:
10630       return "#";
10631     case TYPE_ALU:
10632       if (operands[2] != const1_rtx)
10633         abort ();
10634       return "add{w}\t{%0, %0|%0, %0}";
10635
10636     default:
10637       if (REG_P (operands[2]))
10638         return "sal{w}\t{%b2, %0|%0, %b2}";
10639       else if (operands[2] == const1_rtx
10640                && (TARGET_SHIFT1 || optimize_size))
10641         return "sal{w}\t%0";
10642       else
10643         return "sal{w}\t{%2, %0|%0, %2}";
10644     }
10645 }
10646   [(set (attr "type")
10647      (cond [(eq_attr "alternative" "1")
10648               (const_string "lea")
10649             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10650                           (const_int 0))
10651                       (match_operand 0 "register_operand" ""))
10652                  (match_operand 2 "const1_operand" ""))
10653               (const_string "alu")
10654            ]
10655            (const_string "ishift")))
10656    (set_attr "mode" "HI,SI")])
10657
10658 (define_insn "*ashlhi3_1"
10659   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10660         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10661                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10662    (clobber (reg:CC FLAGS_REG))]
10663   "TARGET_PARTIAL_REG_STALL
10664    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10665 {
10666   switch (get_attr_type (insn))
10667     {
10668     case TYPE_ALU:
10669       if (operands[2] != const1_rtx)
10670         abort ();
10671       return "add{w}\t{%0, %0|%0, %0}";
10672
10673     default:
10674       if (REG_P (operands[2]))
10675         return "sal{w}\t{%b2, %0|%0, %b2}";
10676       else if (operands[2] == const1_rtx
10677                && (TARGET_SHIFT1 || optimize_size))
10678         return "sal{w}\t%0";
10679       else
10680         return "sal{w}\t{%2, %0|%0, %2}";
10681     }
10682 }
10683   [(set (attr "type")
10684      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10685                           (const_int 0))
10686                       (match_operand 0 "register_operand" ""))
10687                  (match_operand 2 "const1_operand" ""))
10688               (const_string "alu")
10689            ]
10690            (const_string "ishift")))
10691    (set_attr "mode" "HI")])
10692
10693 ;; This pattern can't accept a variable shift count, since shifts by
10694 ;; zero don't affect the flags.  We assume that shifts by constant
10695 ;; zero are optimized away.
10696 (define_insn "*ashlhi3_cmp"
10697   [(set (reg FLAGS_REG)
10698         (compare
10699           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10700                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10701           (const_int 0)))
10702    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10703         (ashift:HI (match_dup 1) (match_dup 2)))]
10704   "ix86_match_ccmode (insn, CCGOCmode)
10705    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10706 {
10707   switch (get_attr_type (insn))
10708     {
10709     case TYPE_ALU:
10710       if (operands[2] != const1_rtx)
10711         abort ();
10712       return "add{w}\t{%0, %0|%0, %0}";
10713
10714     default:
10715       if (REG_P (operands[2]))
10716         return "sal{w}\t{%b2, %0|%0, %b2}";
10717       else if (operands[2] == const1_rtx
10718                && (TARGET_SHIFT1 || optimize_size))
10719         return "sal{w}\t%0";
10720       else
10721         return "sal{w}\t{%2, %0|%0, %2}";
10722     }
10723 }
10724   [(set (attr "type")
10725      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10726                           (const_int 0))
10727                       (match_operand 0 "register_operand" ""))
10728                  (match_operand 2 "const1_operand" ""))
10729               (const_string "alu")
10730            ]
10731            (const_string "ishift")))
10732    (set_attr "mode" "HI")])
10733
10734 (define_expand "ashlqi3"
10735   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10736         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10737                    (match_operand:QI 2 "nonmemory_operand" "")))
10738    (clobber (reg:CC FLAGS_REG))]
10739   "TARGET_QIMODE_MATH"
10740   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10741
10742 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10743
10744 (define_insn "*ashlqi3_1_lea"
10745   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10746         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10747                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10748    (clobber (reg:CC FLAGS_REG))]
10749   "!TARGET_PARTIAL_REG_STALL
10750    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10751 {
10752   switch (get_attr_type (insn))
10753     {
10754     case TYPE_LEA:
10755       return "#";
10756     case TYPE_ALU:
10757       if (operands[2] != const1_rtx)
10758         abort ();
10759       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10760         return "add{l}\t{%k0, %k0|%k0, %k0}";
10761       else
10762         return "add{b}\t{%0, %0|%0, %0}";
10763
10764     default:
10765       if (REG_P (operands[2]))
10766         {
10767           if (get_attr_mode (insn) == MODE_SI)
10768             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10769           else
10770             return "sal{b}\t{%b2, %0|%0, %b2}";
10771         }
10772       else if (operands[2] == const1_rtx
10773                && (TARGET_SHIFT1 || optimize_size))
10774         {
10775           if (get_attr_mode (insn) == MODE_SI)
10776             return "sal{l}\t%0";
10777           else
10778             return "sal{b}\t%0";
10779         }
10780       else
10781         {
10782           if (get_attr_mode (insn) == MODE_SI)
10783             return "sal{l}\t{%2, %k0|%k0, %2}";
10784           else
10785             return "sal{b}\t{%2, %0|%0, %2}";
10786         }
10787     }
10788 }
10789   [(set (attr "type")
10790      (cond [(eq_attr "alternative" "2")
10791               (const_string "lea")
10792             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10793                           (const_int 0))
10794                       (match_operand 0 "register_operand" ""))
10795                  (match_operand 2 "const1_operand" ""))
10796               (const_string "alu")
10797            ]
10798            (const_string "ishift")))
10799    (set_attr "mode" "QI,SI,SI")])
10800
10801 (define_insn "*ashlqi3_1"
10802   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10803         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10804                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10805    (clobber (reg:CC FLAGS_REG))]
10806   "TARGET_PARTIAL_REG_STALL
10807    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10808 {
10809   switch (get_attr_type (insn))
10810     {
10811     case TYPE_ALU:
10812       if (operands[2] != const1_rtx)
10813         abort ();
10814       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10815         return "add{l}\t{%k0, %k0|%k0, %k0}";
10816       else
10817         return "add{b}\t{%0, %0|%0, %0}";
10818
10819     default:
10820       if (REG_P (operands[2]))
10821         {
10822           if (get_attr_mode (insn) == MODE_SI)
10823             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10824           else
10825             return "sal{b}\t{%b2, %0|%0, %b2}";
10826         }
10827       else if (operands[2] == const1_rtx
10828                && (TARGET_SHIFT1 || optimize_size))
10829         {
10830           if (get_attr_mode (insn) == MODE_SI)
10831             return "sal{l}\t%0";
10832           else
10833             return "sal{b}\t%0";
10834         }
10835       else
10836         {
10837           if (get_attr_mode (insn) == MODE_SI)
10838             return "sal{l}\t{%2, %k0|%k0, %2}";
10839           else
10840             return "sal{b}\t{%2, %0|%0, %2}";
10841         }
10842     }
10843 }
10844   [(set (attr "type")
10845      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10846                           (const_int 0))
10847                       (match_operand 0 "register_operand" ""))
10848                  (match_operand 2 "const1_operand" ""))
10849               (const_string "alu")
10850            ]
10851            (const_string "ishift")))
10852    (set_attr "mode" "QI,SI")])
10853
10854 ;; This pattern can't accept a variable shift count, since shifts by
10855 ;; zero don't affect the flags.  We assume that shifts by constant
10856 ;; zero are optimized away.
10857 (define_insn "*ashlqi3_cmp"
10858   [(set (reg FLAGS_REG)
10859         (compare
10860           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10861                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10862           (const_int 0)))
10863    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10864         (ashift:QI (match_dup 1) (match_dup 2)))]
10865   "ix86_match_ccmode (insn, CCGOCmode)
10866    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10867 {
10868   switch (get_attr_type (insn))
10869     {
10870     case TYPE_ALU:
10871       if (operands[2] != const1_rtx)
10872         abort ();
10873       return "add{b}\t{%0, %0|%0, %0}";
10874
10875     default:
10876       if (REG_P (operands[2]))
10877         return "sal{b}\t{%b2, %0|%0, %b2}";
10878       else if (operands[2] == const1_rtx
10879                && (TARGET_SHIFT1 || optimize_size))
10880         return "sal{b}\t%0";
10881       else
10882         return "sal{b}\t{%2, %0|%0, %2}";
10883     }
10884 }
10885   [(set (attr "type")
10886      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10887                           (const_int 0))
10888                       (match_operand 0 "register_operand" ""))
10889                  (match_operand 2 "const1_operand" ""))
10890               (const_string "alu")
10891            ]
10892            (const_string "ishift")))
10893    (set_attr "mode" "QI")])
10894
10895 ;; See comment above `ashldi3' about how this works.
10896
10897 (define_expand "ashrdi3"
10898   [(set (match_operand:DI 0 "shiftdi_operand" "")
10899         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10900                      (match_operand:QI 2 "nonmemory_operand" "")))]
10901   ""
10902   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10903
10904 (define_insn "*ashrdi3_63_rex64"
10905   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10906         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10907                      (match_operand:DI 2 "const_int_operand" "i,i")))
10908    (clobber (reg:CC FLAGS_REG))]
10909   "TARGET_64BIT && INTVAL (operands[2]) == 63
10910    && (TARGET_USE_CLTD || optimize_size)
10911    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10912   "@
10913    {cqto|cqo}
10914    sar{q}\t{%2, %0|%0, %2}"
10915   [(set_attr "type" "imovx,ishift")
10916    (set_attr "prefix_0f" "0,*")
10917    (set_attr "length_immediate" "0,*")
10918    (set_attr "modrm" "0,1")
10919    (set_attr "mode" "DI")])
10920
10921 (define_insn "*ashrdi3_1_one_bit_rex64"
10922   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10923         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10924                      (match_operand:QI 2 "const1_operand" "")))
10925    (clobber (reg:CC FLAGS_REG))]
10926   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10927    && (TARGET_SHIFT1 || optimize_size)"
10928   "sar{q}\t%0"
10929   [(set_attr "type" "ishift")
10930    (set (attr "length") 
10931      (if_then_else (match_operand:DI 0 "register_operand" "") 
10932         (const_string "2")
10933         (const_string "*")))])
10934
10935 (define_insn "*ashrdi3_1_rex64"
10936   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10937         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10938                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10939    (clobber (reg:CC FLAGS_REG))]
10940   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10941   "@
10942    sar{q}\t{%2, %0|%0, %2}
10943    sar{q}\t{%b2, %0|%0, %b2}"
10944   [(set_attr "type" "ishift")
10945    (set_attr "mode" "DI")])
10946
10947 ;; This pattern can't accept a variable shift count, since shifts by
10948 ;; zero don't affect the flags.  We assume that shifts by constant
10949 ;; zero are optimized away.
10950 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10951   [(set (reg FLAGS_REG)
10952         (compare
10953           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10954                        (match_operand:QI 2 "const1_operand" ""))
10955           (const_int 0)))
10956    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10957         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10958   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10959    && (TARGET_SHIFT1 || optimize_size)
10960    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10961   "sar{q}\t%0"
10962   [(set_attr "type" "ishift")
10963    (set (attr "length") 
10964      (if_then_else (match_operand:DI 0 "register_operand" "") 
10965         (const_string "2")
10966         (const_string "*")))])
10967
10968 ;; This pattern can't accept a variable shift count, since shifts by
10969 ;; zero don't affect the flags.  We assume that shifts by constant
10970 ;; zero are optimized away.
10971 (define_insn "*ashrdi3_cmp_rex64"
10972   [(set (reg FLAGS_REG)
10973         (compare
10974           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10975                        (match_operand:QI 2 "const_int_operand" "n"))
10976           (const_int 0)))
10977    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10978         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10979   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10980    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10981   "sar{q}\t{%2, %0|%0, %2}"
10982   [(set_attr "type" "ishift")
10983    (set_attr "mode" "DI")])
10984
10985 (define_insn "*ashrdi3_1"
10986   [(set (match_operand:DI 0 "register_operand" "=r")
10987         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10988                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10989    (clobber (reg:CC FLAGS_REG))]
10990   "!TARGET_64BIT"
10991   "#"
10992   [(set_attr "type" "multi")])
10993
10994 ;; By default we don't ask for a scratch register, because when DImode
10995 ;; values are manipulated, registers are already at a premium.  But if
10996 ;; we have one handy, we won't turn it away.
10997 (define_peephole2
10998   [(match_scratch:SI 3 "r")
10999    (parallel [(set (match_operand:DI 0 "register_operand" "")
11000                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11001                                 (match_operand:QI 2 "nonmemory_operand" "")))
11002               (clobber (reg:CC FLAGS_REG))])
11003    (match_dup 3)]
11004   "!TARGET_64BIT && TARGET_CMOVE"
11005   [(const_int 0)]
11006   "ix86_split_ashrdi (operands, operands[3]); DONE;")
11007
11008 (define_split
11009   [(set (match_operand:DI 0 "register_operand" "")
11010         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11011                      (match_operand:QI 2 "nonmemory_operand" "")))
11012    (clobber (reg:CC FLAGS_REG))]
11013   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11014   [(const_int 0)]
11015   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11016
11017 (define_insn "x86_shrd_1"
11018   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11019         (ior:SI (ashiftrt:SI (match_dup 0)
11020                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11021                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11022                   (minus:QI (const_int 32) (match_dup 2)))))
11023    (clobber (reg:CC FLAGS_REG))]
11024   ""
11025   "@
11026    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11027    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11028   [(set_attr "type" "ishift")
11029    (set_attr "prefix_0f" "1")
11030    (set_attr "pent_pair" "np")
11031    (set_attr "mode" "SI")])
11032
11033 (define_expand "x86_shift_adj_3"
11034   [(use (match_operand:SI 0 "register_operand" ""))
11035    (use (match_operand:SI 1 "register_operand" ""))
11036    (use (match_operand:QI 2 "register_operand" ""))]
11037   ""
11038 {
11039   rtx label = gen_label_rtx ();
11040   rtx tmp;
11041
11042   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11043
11044   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11045   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11046   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11047                               gen_rtx_LABEL_REF (VOIDmode, label),
11048                               pc_rtx);
11049   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11050   JUMP_LABEL (tmp) = label;
11051
11052   emit_move_insn (operands[0], operands[1]);
11053   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11054
11055   emit_label (label);
11056   LABEL_NUSES (label) = 1;
11057
11058   DONE;
11059 })
11060
11061 (define_insn "ashrsi3_31"
11062   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11063         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11064                      (match_operand:SI 2 "const_int_operand" "i,i")))
11065    (clobber (reg:CC FLAGS_REG))]
11066   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11067    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11068   "@
11069    {cltd|cdq}
11070    sar{l}\t{%2, %0|%0, %2}"
11071   [(set_attr "type" "imovx,ishift")
11072    (set_attr "prefix_0f" "0,*")
11073    (set_attr "length_immediate" "0,*")
11074    (set_attr "modrm" "0,1")
11075    (set_attr "mode" "SI")])
11076
11077 (define_insn "*ashrsi3_31_zext"
11078   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11079         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11080                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11081    (clobber (reg:CC FLAGS_REG))]
11082   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11083    && INTVAL (operands[2]) == 31
11084    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11085   "@
11086    {cltd|cdq}
11087    sar{l}\t{%2, %k0|%k0, %2}"
11088   [(set_attr "type" "imovx,ishift")
11089    (set_attr "prefix_0f" "0,*")
11090    (set_attr "length_immediate" "0,*")
11091    (set_attr "modrm" "0,1")
11092    (set_attr "mode" "SI")])
11093
11094 (define_expand "ashrsi3"
11095   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11096         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11097                      (match_operand:QI 2 "nonmemory_operand" "")))
11098    (clobber (reg:CC FLAGS_REG))]
11099   ""
11100   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11101
11102 (define_insn "*ashrsi3_1_one_bit"
11103   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11104         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11105                      (match_operand:QI 2 "const1_operand" "")))
11106    (clobber (reg:CC FLAGS_REG))]
11107   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11108    && (TARGET_SHIFT1 || optimize_size)"
11109   "sar{l}\t%0"
11110   [(set_attr "type" "ishift")
11111    (set (attr "length") 
11112      (if_then_else (match_operand:SI 0 "register_operand" "") 
11113         (const_string "2")
11114         (const_string "*")))])
11115
11116 (define_insn "*ashrsi3_1_one_bit_zext"
11117   [(set (match_operand:DI 0 "register_operand" "=r")
11118         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11119                                      (match_operand:QI 2 "const1_operand" ""))))
11120    (clobber (reg:CC FLAGS_REG))]
11121   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11122    && (TARGET_SHIFT1 || optimize_size)"
11123   "sar{l}\t%k0"
11124   [(set_attr "type" "ishift")
11125    (set_attr "length" "2")])
11126
11127 (define_insn "*ashrsi3_1"
11128   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11129         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11130                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11131    (clobber (reg:CC FLAGS_REG))]
11132   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11133   "@
11134    sar{l}\t{%2, %0|%0, %2}
11135    sar{l}\t{%b2, %0|%0, %b2}"
11136   [(set_attr "type" "ishift")
11137    (set_attr "mode" "SI")])
11138
11139 (define_insn "*ashrsi3_1_zext"
11140   [(set (match_operand:DI 0 "register_operand" "=r,r")
11141         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11142                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11143    (clobber (reg:CC FLAGS_REG))]
11144   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11145   "@
11146    sar{l}\t{%2, %k0|%k0, %2}
11147    sar{l}\t{%b2, %k0|%k0, %b2}"
11148   [(set_attr "type" "ishift")
11149    (set_attr "mode" "SI")])
11150
11151 ;; This pattern can't accept a variable shift count, since shifts by
11152 ;; zero don't affect the flags.  We assume that shifts by constant
11153 ;; zero are optimized away.
11154 (define_insn "*ashrsi3_one_bit_cmp"
11155   [(set (reg FLAGS_REG)
11156         (compare
11157           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11158                        (match_operand:QI 2 "const1_operand" ""))
11159           (const_int 0)))
11160    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11161         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11162   "ix86_match_ccmode (insn, CCGOCmode)
11163    && (TARGET_SHIFT1 || optimize_size)
11164    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11165   "sar{l}\t%0"
11166   [(set_attr "type" "ishift")
11167    (set (attr "length") 
11168      (if_then_else (match_operand:SI 0 "register_operand" "") 
11169         (const_string "2")
11170         (const_string "*")))])
11171
11172 (define_insn "*ashrsi3_one_bit_cmp_zext"
11173   [(set (reg FLAGS_REG)
11174         (compare
11175           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11176                        (match_operand:QI 2 "const1_operand" ""))
11177           (const_int 0)))
11178    (set (match_operand:DI 0 "register_operand" "=r")
11179         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11180   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11181    && (TARGET_SHIFT1 || optimize_size)
11182    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11183   "sar{l}\t%k0"
11184   [(set_attr "type" "ishift")
11185    (set_attr "length" "2")])
11186
11187 ;; This pattern can't accept a variable shift count, since shifts by
11188 ;; zero don't affect the flags.  We assume that shifts by constant
11189 ;; zero are optimized away.
11190 (define_insn "*ashrsi3_cmp"
11191   [(set (reg FLAGS_REG)
11192         (compare
11193           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11194                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11195           (const_int 0)))
11196    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11197         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11198   "ix86_match_ccmode (insn, CCGOCmode)
11199    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11200   "sar{l}\t{%2, %0|%0, %2}"
11201   [(set_attr "type" "ishift")
11202    (set_attr "mode" "SI")])
11203
11204 (define_insn "*ashrsi3_cmp_zext"
11205   [(set (reg FLAGS_REG)
11206         (compare
11207           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11208                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11209           (const_int 0)))
11210    (set (match_operand:DI 0 "register_operand" "=r")
11211         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11212   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11213    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11214   "sar{l}\t{%2, %k0|%k0, %2}"
11215   [(set_attr "type" "ishift")
11216    (set_attr "mode" "SI")])
11217
11218 (define_expand "ashrhi3"
11219   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11220         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11221                      (match_operand:QI 2 "nonmemory_operand" "")))
11222    (clobber (reg:CC FLAGS_REG))]
11223   "TARGET_HIMODE_MATH"
11224   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11225
11226 (define_insn "*ashrhi3_1_one_bit"
11227   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11228         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11229                      (match_operand:QI 2 "const1_operand" "")))
11230    (clobber (reg:CC FLAGS_REG))]
11231   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11232    && (TARGET_SHIFT1 || optimize_size)"
11233   "sar{w}\t%0"
11234   [(set_attr "type" "ishift")
11235    (set (attr "length") 
11236      (if_then_else (match_operand 0 "register_operand" "") 
11237         (const_string "2")
11238         (const_string "*")))])
11239
11240 (define_insn "*ashrhi3_1"
11241   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11242         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11243                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11244    (clobber (reg:CC FLAGS_REG))]
11245   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11246   "@
11247    sar{w}\t{%2, %0|%0, %2}
11248    sar{w}\t{%b2, %0|%0, %b2}"
11249   [(set_attr "type" "ishift")
11250    (set_attr "mode" "HI")])
11251
11252 ;; This pattern can't accept a variable shift count, since shifts by
11253 ;; zero don't affect the flags.  We assume that shifts by constant
11254 ;; zero are optimized away.
11255 (define_insn "*ashrhi3_one_bit_cmp"
11256   [(set (reg FLAGS_REG)
11257         (compare
11258           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11259                        (match_operand:QI 2 "const1_operand" ""))
11260           (const_int 0)))
11261    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11262         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11263   "ix86_match_ccmode (insn, CCGOCmode)
11264    && (TARGET_SHIFT1 || optimize_size)
11265    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11266   "sar{w}\t%0"
11267   [(set_attr "type" "ishift")
11268    (set (attr "length") 
11269      (if_then_else (match_operand 0 "register_operand" "") 
11270         (const_string "2")
11271         (const_string "*")))])
11272
11273 ;; This pattern can't accept a variable shift count, since shifts by
11274 ;; zero don't affect the flags.  We assume that shifts by constant
11275 ;; zero are optimized away.
11276 (define_insn "*ashrhi3_cmp"
11277   [(set (reg FLAGS_REG)
11278         (compare
11279           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11280                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11281           (const_int 0)))
11282    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11283         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11284   "ix86_match_ccmode (insn, CCGOCmode)
11285    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11286   "sar{w}\t{%2, %0|%0, %2}"
11287   [(set_attr "type" "ishift")
11288    (set_attr "mode" "HI")])
11289
11290 (define_expand "ashrqi3"
11291   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11292         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11293                      (match_operand:QI 2 "nonmemory_operand" "")))
11294    (clobber (reg:CC FLAGS_REG))]
11295   "TARGET_QIMODE_MATH"
11296   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11297
11298 (define_insn "*ashrqi3_1_one_bit"
11299   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11300         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11301                      (match_operand:QI 2 "const1_operand" "")))
11302    (clobber (reg:CC FLAGS_REG))]
11303   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11304    && (TARGET_SHIFT1 || optimize_size)"
11305   "sar{b}\t%0"
11306   [(set_attr "type" "ishift")
11307    (set (attr "length") 
11308      (if_then_else (match_operand 0 "register_operand" "") 
11309         (const_string "2")
11310         (const_string "*")))])
11311
11312 (define_insn "*ashrqi3_1_one_bit_slp"
11313   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11314         (ashiftrt:QI (match_dup 0)
11315                      (match_operand:QI 1 "const1_operand" "")))
11316    (clobber (reg:CC FLAGS_REG))]
11317   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11318    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11319    && (TARGET_SHIFT1 || optimize_size)"
11320   "sar{b}\t%0"
11321   [(set_attr "type" "ishift1")
11322    (set (attr "length") 
11323      (if_then_else (match_operand 0 "register_operand" "") 
11324         (const_string "2")
11325         (const_string "*")))])
11326
11327 (define_insn "*ashrqi3_1"
11328   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11329         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11330                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11331    (clobber (reg:CC FLAGS_REG))]
11332   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11333   "@
11334    sar{b}\t{%2, %0|%0, %2}
11335    sar{b}\t{%b2, %0|%0, %b2}"
11336   [(set_attr "type" "ishift")
11337    (set_attr "mode" "QI")])
11338
11339 (define_insn "*ashrqi3_1_slp"
11340   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11341         (ashiftrt:QI (match_dup 0)
11342                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11343    (clobber (reg:CC FLAGS_REG))]
11344   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11345    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11346   "@
11347    sar{b}\t{%1, %0|%0, %1}
11348    sar{b}\t{%b1, %0|%0, %b1}"
11349   [(set_attr "type" "ishift1")
11350    (set_attr "mode" "QI")])
11351
11352 ;; This pattern can't accept a variable shift count, since shifts by
11353 ;; zero don't affect the flags.  We assume that shifts by constant
11354 ;; zero are optimized away.
11355 (define_insn "*ashrqi3_one_bit_cmp"
11356   [(set (reg FLAGS_REG)
11357         (compare
11358           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11359                        (match_operand:QI 2 "const1_operand" "I"))
11360           (const_int 0)))
11361    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11362         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11363   "ix86_match_ccmode (insn, CCGOCmode)
11364    && (TARGET_SHIFT1 || optimize_size)
11365    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11366   "sar{b}\t%0"
11367   [(set_attr "type" "ishift")
11368    (set (attr "length") 
11369      (if_then_else (match_operand 0 "register_operand" "") 
11370         (const_string "2")
11371         (const_string "*")))])
11372
11373 ;; This pattern can't accept a variable shift count, since shifts by
11374 ;; zero don't affect the flags.  We assume that shifts by constant
11375 ;; zero are optimized away.
11376 (define_insn "*ashrqi3_cmp"
11377   [(set (reg FLAGS_REG)
11378         (compare
11379           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11380                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11381           (const_int 0)))
11382    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11383         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11384   "ix86_match_ccmode (insn, CCGOCmode)
11385    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11386   "sar{b}\t{%2, %0|%0, %2}"
11387   [(set_attr "type" "ishift")
11388    (set_attr "mode" "QI")])
11389 \f
11390 ;; Logical shift instructions
11391
11392 ;; See comment above `ashldi3' about how this works.
11393
11394 (define_expand "lshrdi3"
11395   [(set (match_operand:DI 0 "shiftdi_operand" "")
11396         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11397                      (match_operand:QI 2 "nonmemory_operand" "")))]
11398   ""
11399   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11400
11401 (define_insn "*lshrdi3_1_one_bit_rex64"
11402   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11403         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11404                      (match_operand:QI 2 "const1_operand" "")))
11405    (clobber (reg:CC FLAGS_REG))]
11406   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11407    && (TARGET_SHIFT1 || optimize_size)"
11408   "shr{q}\t%0"
11409   [(set_attr "type" "ishift")
11410    (set (attr "length") 
11411      (if_then_else (match_operand:DI 0 "register_operand" "") 
11412         (const_string "2")
11413         (const_string "*")))])
11414
11415 (define_insn "*lshrdi3_1_rex64"
11416   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11417         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11418                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11419    (clobber (reg:CC FLAGS_REG))]
11420   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11421   "@
11422    shr{q}\t{%2, %0|%0, %2}
11423    shr{q}\t{%b2, %0|%0, %b2}"
11424   [(set_attr "type" "ishift")
11425    (set_attr "mode" "DI")])
11426
11427 ;; This pattern can't accept a variable shift count, since shifts by
11428 ;; zero don't affect the flags.  We assume that shifts by constant
11429 ;; zero are optimized away.
11430 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11431   [(set (reg FLAGS_REG)
11432         (compare
11433           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11434                        (match_operand:QI 2 "const1_operand" ""))
11435           (const_int 0)))
11436    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11437         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11438   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11439    && (TARGET_SHIFT1 || optimize_size)
11440    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11441   "shr{q}\t%0"
11442   [(set_attr "type" "ishift")
11443    (set (attr "length") 
11444      (if_then_else (match_operand:DI 0 "register_operand" "") 
11445         (const_string "2")
11446         (const_string "*")))])
11447
11448 ;; This pattern can't accept a variable shift count, since shifts by
11449 ;; zero don't affect the flags.  We assume that shifts by constant
11450 ;; zero are optimized away.
11451 (define_insn "*lshrdi3_cmp_rex64"
11452   [(set (reg FLAGS_REG)
11453         (compare
11454           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11455                        (match_operand:QI 2 "const_int_operand" "e"))
11456           (const_int 0)))
11457    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11458         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11459   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11460    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11461   "shr{q}\t{%2, %0|%0, %2}"
11462   [(set_attr "type" "ishift")
11463    (set_attr "mode" "DI")])
11464
11465 (define_insn "*lshrdi3_1"
11466   [(set (match_operand:DI 0 "register_operand" "=r")
11467         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11468                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11469    (clobber (reg:CC FLAGS_REG))]
11470   "!TARGET_64BIT"
11471   "#"
11472   [(set_attr "type" "multi")])
11473
11474 ;; By default we don't ask for a scratch register, because when DImode
11475 ;; values are manipulated, registers are already at a premium.  But if
11476 ;; we have one handy, we won't turn it away.
11477 (define_peephole2
11478   [(match_scratch:SI 3 "r")
11479    (parallel [(set (match_operand:DI 0 "register_operand" "")
11480                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11481                                 (match_operand:QI 2 "nonmemory_operand" "")))
11482               (clobber (reg:CC FLAGS_REG))])
11483    (match_dup 3)]
11484   "!TARGET_64BIT && TARGET_CMOVE"
11485   [(const_int 0)]
11486   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11487
11488 (define_split 
11489   [(set (match_operand:DI 0 "register_operand" "")
11490         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11491                      (match_operand:QI 2 "nonmemory_operand" "")))
11492    (clobber (reg:CC FLAGS_REG))]
11493   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11494   [(const_int 0)]
11495   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11496
11497 (define_expand "lshrsi3"
11498   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11499         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11500                      (match_operand:QI 2 "nonmemory_operand" "")))
11501    (clobber (reg:CC FLAGS_REG))]
11502   ""
11503   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11504
11505 (define_insn "*lshrsi3_1_one_bit"
11506   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11507         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11508                      (match_operand:QI 2 "const1_operand" "")))
11509    (clobber (reg:CC FLAGS_REG))]
11510   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11511    && (TARGET_SHIFT1 || optimize_size)"
11512   "shr{l}\t%0"
11513   [(set_attr "type" "ishift")
11514    (set (attr "length") 
11515      (if_then_else (match_operand:SI 0 "register_operand" "") 
11516         (const_string "2")
11517         (const_string "*")))])
11518
11519 (define_insn "*lshrsi3_1_one_bit_zext"
11520   [(set (match_operand:DI 0 "register_operand" "=r")
11521         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11522                      (match_operand:QI 2 "const1_operand" "")))
11523    (clobber (reg:CC FLAGS_REG))]
11524   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11525    && (TARGET_SHIFT1 || optimize_size)"
11526   "shr{l}\t%k0"
11527   [(set_attr "type" "ishift")
11528    (set_attr "length" "2")])
11529
11530 (define_insn "*lshrsi3_1"
11531   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11532         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11533                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11534    (clobber (reg:CC FLAGS_REG))]
11535   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11536   "@
11537    shr{l}\t{%2, %0|%0, %2}
11538    shr{l}\t{%b2, %0|%0, %b2}"
11539   [(set_attr "type" "ishift")
11540    (set_attr "mode" "SI")])
11541
11542 (define_insn "*lshrsi3_1_zext"
11543   [(set (match_operand:DI 0 "register_operand" "=r,r")
11544         (zero_extend:DI
11545           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11546                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11547    (clobber (reg:CC FLAGS_REG))]
11548   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11549   "@
11550    shr{l}\t{%2, %k0|%k0, %2}
11551    shr{l}\t{%b2, %k0|%k0, %b2}"
11552   [(set_attr "type" "ishift")
11553    (set_attr "mode" "SI")])
11554
11555 ;; This pattern can't accept a variable shift count, since shifts by
11556 ;; zero don't affect the flags.  We assume that shifts by constant
11557 ;; zero are optimized away.
11558 (define_insn "*lshrsi3_one_bit_cmp"
11559   [(set (reg FLAGS_REG)
11560         (compare
11561           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11562                        (match_operand:QI 2 "const1_operand" ""))
11563           (const_int 0)))
11564    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11565         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11566   "ix86_match_ccmode (insn, CCGOCmode)
11567    && (TARGET_SHIFT1 || optimize_size)
11568    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11569   "shr{l}\t%0"
11570   [(set_attr "type" "ishift")
11571    (set (attr "length") 
11572      (if_then_else (match_operand:SI 0 "register_operand" "") 
11573         (const_string "2")
11574         (const_string "*")))])
11575
11576 (define_insn "*lshrsi3_cmp_one_bit_zext"
11577   [(set (reg FLAGS_REG)
11578         (compare
11579           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11580                        (match_operand:QI 2 "const1_operand" ""))
11581           (const_int 0)))
11582    (set (match_operand:DI 0 "register_operand" "=r")
11583         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11584   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11585    && (TARGET_SHIFT1 || optimize_size)
11586    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11587   "shr{l}\t%k0"
11588   [(set_attr "type" "ishift")
11589    (set_attr "length" "2")])
11590
11591 ;; This pattern can't accept a variable shift count, since shifts by
11592 ;; zero don't affect the flags.  We assume that shifts by constant
11593 ;; zero are optimized away.
11594 (define_insn "*lshrsi3_cmp"
11595   [(set (reg FLAGS_REG)
11596         (compare
11597           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11598                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11599           (const_int 0)))
11600    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11601         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11602   "ix86_match_ccmode (insn, CCGOCmode)
11603    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11604   "shr{l}\t{%2, %0|%0, %2}"
11605   [(set_attr "type" "ishift")
11606    (set_attr "mode" "SI")])
11607
11608 (define_insn "*lshrsi3_cmp_zext"
11609   [(set (reg FLAGS_REG)
11610         (compare
11611           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11612                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11613           (const_int 0)))
11614    (set (match_operand:DI 0 "register_operand" "=r")
11615         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11616   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11617    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11618   "shr{l}\t{%2, %k0|%k0, %2}"
11619   [(set_attr "type" "ishift")
11620    (set_attr "mode" "SI")])
11621
11622 (define_expand "lshrhi3"
11623   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11624         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11625                      (match_operand:QI 2 "nonmemory_operand" "")))
11626    (clobber (reg:CC FLAGS_REG))]
11627   "TARGET_HIMODE_MATH"
11628   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11629
11630 (define_insn "*lshrhi3_1_one_bit"
11631   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11632         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11633                      (match_operand:QI 2 "const1_operand" "")))
11634    (clobber (reg:CC FLAGS_REG))]
11635   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11636    && (TARGET_SHIFT1 || optimize_size)"
11637   "shr{w}\t%0"
11638   [(set_attr "type" "ishift")
11639    (set (attr "length") 
11640      (if_then_else (match_operand 0 "register_operand" "") 
11641         (const_string "2")
11642         (const_string "*")))])
11643
11644 (define_insn "*lshrhi3_1"
11645   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11646         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11647                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11648    (clobber (reg:CC FLAGS_REG))]
11649   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11650   "@
11651    shr{w}\t{%2, %0|%0, %2}
11652    shr{w}\t{%b2, %0|%0, %b2}"
11653   [(set_attr "type" "ishift")
11654    (set_attr "mode" "HI")])
11655
11656 ;; This pattern can't accept a variable shift count, since shifts by
11657 ;; zero don't affect the flags.  We assume that shifts by constant
11658 ;; zero are optimized away.
11659 (define_insn "*lshrhi3_one_bit_cmp"
11660   [(set (reg FLAGS_REG)
11661         (compare
11662           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11663                        (match_operand:QI 2 "const1_operand" ""))
11664           (const_int 0)))
11665    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11666         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11667   "ix86_match_ccmode (insn, CCGOCmode)
11668    && (TARGET_SHIFT1 || optimize_size)
11669    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11670   "shr{w}\t%0"
11671   [(set_attr "type" "ishift")
11672    (set (attr "length") 
11673      (if_then_else (match_operand:SI 0 "register_operand" "") 
11674         (const_string "2")
11675         (const_string "*")))])
11676
11677 ;; This pattern can't accept a variable shift count, since shifts by
11678 ;; zero don't affect the flags.  We assume that shifts by constant
11679 ;; zero are optimized away.
11680 (define_insn "*lshrhi3_cmp"
11681   [(set (reg FLAGS_REG)
11682         (compare
11683           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11684                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11685           (const_int 0)))
11686    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11687         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11688   "ix86_match_ccmode (insn, CCGOCmode)
11689    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11690   "shr{w}\t{%2, %0|%0, %2}"
11691   [(set_attr "type" "ishift")
11692    (set_attr "mode" "HI")])
11693
11694 (define_expand "lshrqi3"
11695   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11696         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11697                      (match_operand:QI 2 "nonmemory_operand" "")))
11698    (clobber (reg:CC FLAGS_REG))]
11699   "TARGET_QIMODE_MATH"
11700   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11701
11702 (define_insn "*lshrqi3_1_one_bit"
11703   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11704         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11705                      (match_operand:QI 2 "const1_operand" "")))
11706    (clobber (reg:CC FLAGS_REG))]
11707   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11708    && (TARGET_SHIFT1 || optimize_size)"
11709   "shr{b}\t%0"
11710   [(set_attr "type" "ishift")
11711    (set (attr "length") 
11712      (if_then_else (match_operand 0 "register_operand" "") 
11713         (const_string "2")
11714         (const_string "*")))])
11715
11716 (define_insn "*lshrqi3_1_one_bit_slp"
11717   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11718         (lshiftrt:QI (match_dup 0)
11719                      (match_operand:QI 1 "const1_operand" "")))
11720    (clobber (reg:CC FLAGS_REG))]
11721   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11722    && (TARGET_SHIFT1 || optimize_size)"
11723   "shr{b}\t%0"
11724   [(set_attr "type" "ishift1")
11725    (set (attr "length") 
11726      (if_then_else (match_operand 0 "register_operand" "") 
11727         (const_string "2")
11728         (const_string "*")))])
11729
11730 (define_insn "*lshrqi3_1"
11731   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11732         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11733                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11734    (clobber (reg:CC FLAGS_REG))]
11735   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11736   "@
11737    shr{b}\t{%2, %0|%0, %2}
11738    shr{b}\t{%b2, %0|%0, %b2}"
11739   [(set_attr "type" "ishift")
11740    (set_attr "mode" "QI")])
11741
11742 (define_insn "*lshrqi3_1_slp"
11743   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11744         (lshiftrt:QI (match_dup 0)
11745                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11746    (clobber (reg:CC FLAGS_REG))]
11747   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11748    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11749   "@
11750    shr{b}\t{%1, %0|%0, %1}
11751    shr{b}\t{%b1, %0|%0, %b1}"
11752   [(set_attr "type" "ishift1")
11753    (set_attr "mode" "QI")])
11754
11755 ;; This pattern can't accept a variable shift count, since shifts by
11756 ;; zero don't affect the flags.  We assume that shifts by constant
11757 ;; zero are optimized away.
11758 (define_insn "*lshrqi2_one_bit_cmp"
11759   [(set (reg FLAGS_REG)
11760         (compare
11761           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11762                        (match_operand:QI 2 "const1_operand" ""))
11763           (const_int 0)))
11764    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11765         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11766   "ix86_match_ccmode (insn, CCGOCmode)
11767    && (TARGET_SHIFT1 || optimize_size)
11768    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11769   "shr{b}\t%0"
11770   [(set_attr "type" "ishift")
11771    (set (attr "length") 
11772      (if_then_else (match_operand:SI 0 "register_operand" "") 
11773         (const_string "2")
11774         (const_string "*")))])
11775
11776 ;; This pattern can't accept a variable shift count, since shifts by
11777 ;; zero don't affect the flags.  We assume that shifts by constant
11778 ;; zero are optimized away.
11779 (define_insn "*lshrqi2_cmp"
11780   [(set (reg FLAGS_REG)
11781         (compare
11782           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11783                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11784           (const_int 0)))
11785    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11786         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11787   "ix86_match_ccmode (insn, CCGOCmode)
11788    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11789   "shr{b}\t{%2, %0|%0, %2}"
11790   [(set_attr "type" "ishift")
11791    (set_attr "mode" "QI")])
11792 \f
11793 ;; Rotate instructions
11794
11795 (define_expand "rotldi3"
11796   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11797         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11798                    (match_operand:QI 2 "nonmemory_operand" "")))
11799    (clobber (reg:CC FLAGS_REG))]
11800   "TARGET_64BIT"
11801   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11802
11803 (define_insn "*rotlsi3_1_one_bit_rex64"
11804   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11805         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11806                    (match_operand:QI 2 "const1_operand" "")))
11807    (clobber (reg:CC FLAGS_REG))]
11808   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11809    && (TARGET_SHIFT1 || optimize_size)"
11810   "rol{q}\t%0"
11811   [(set_attr "type" "rotate")
11812    (set (attr "length") 
11813      (if_then_else (match_operand:DI 0 "register_operand" "") 
11814         (const_string "2")
11815         (const_string "*")))])
11816
11817 (define_insn "*rotldi3_1_rex64"
11818   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11819         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11820                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11821    (clobber (reg:CC FLAGS_REG))]
11822   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11823   "@
11824    rol{q}\t{%2, %0|%0, %2}
11825    rol{q}\t{%b2, %0|%0, %b2}"
11826   [(set_attr "type" "rotate")
11827    (set_attr "mode" "DI")])
11828
11829 (define_expand "rotlsi3"
11830   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11831         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11832                    (match_operand:QI 2 "nonmemory_operand" "")))
11833    (clobber (reg:CC FLAGS_REG))]
11834   ""
11835   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11836
11837 (define_insn "*rotlsi3_1_one_bit"
11838   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11839         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11840                    (match_operand:QI 2 "const1_operand" "")))
11841    (clobber (reg:CC FLAGS_REG))]
11842   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11843    && (TARGET_SHIFT1 || optimize_size)"
11844   "rol{l}\t%0"
11845   [(set_attr "type" "rotate")
11846    (set (attr "length") 
11847      (if_then_else (match_operand:SI 0 "register_operand" "") 
11848         (const_string "2")
11849         (const_string "*")))])
11850
11851 (define_insn "*rotlsi3_1_one_bit_zext"
11852   [(set (match_operand:DI 0 "register_operand" "=r")
11853         (zero_extend:DI
11854           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11855                      (match_operand:QI 2 "const1_operand" ""))))
11856    (clobber (reg:CC FLAGS_REG))]
11857   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11858    && (TARGET_SHIFT1 || optimize_size)"
11859   "rol{l}\t%k0"
11860   [(set_attr "type" "rotate")
11861    (set_attr "length" "2")])
11862
11863 (define_insn "*rotlsi3_1"
11864   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11865         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11866                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11867    (clobber (reg:CC FLAGS_REG))]
11868   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11869   "@
11870    rol{l}\t{%2, %0|%0, %2}
11871    rol{l}\t{%b2, %0|%0, %b2}"
11872   [(set_attr "type" "rotate")
11873    (set_attr "mode" "SI")])
11874
11875 (define_insn "*rotlsi3_1_zext"
11876   [(set (match_operand:DI 0 "register_operand" "=r,r")
11877         (zero_extend:DI
11878           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11879                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11880    (clobber (reg:CC FLAGS_REG))]
11881   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11882   "@
11883    rol{l}\t{%2, %k0|%k0, %2}
11884    rol{l}\t{%b2, %k0|%k0, %b2}"
11885   [(set_attr "type" "rotate")
11886    (set_attr "mode" "SI")])
11887
11888 (define_expand "rotlhi3"
11889   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11890         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11891                    (match_operand:QI 2 "nonmemory_operand" "")))
11892    (clobber (reg:CC FLAGS_REG))]
11893   "TARGET_HIMODE_MATH"
11894   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11895
11896 (define_insn "*rotlhi3_1_one_bit"
11897   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11898         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11899                    (match_operand:QI 2 "const1_operand" "")))
11900    (clobber (reg:CC FLAGS_REG))]
11901   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11902    && (TARGET_SHIFT1 || optimize_size)"
11903   "rol{w}\t%0"
11904   [(set_attr "type" "rotate")
11905    (set (attr "length") 
11906      (if_then_else (match_operand 0 "register_operand" "") 
11907         (const_string "2")
11908         (const_string "*")))])
11909
11910 (define_insn "*rotlhi3_1"
11911   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11912         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11913                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11914    (clobber (reg:CC FLAGS_REG))]
11915   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11916   "@
11917    rol{w}\t{%2, %0|%0, %2}
11918    rol{w}\t{%b2, %0|%0, %b2}"
11919   [(set_attr "type" "rotate")
11920    (set_attr "mode" "HI")])
11921
11922 (define_expand "rotlqi3"
11923   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11924         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11925                    (match_operand:QI 2 "nonmemory_operand" "")))
11926    (clobber (reg:CC FLAGS_REG))]
11927   "TARGET_QIMODE_MATH"
11928   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11929
11930 (define_insn "*rotlqi3_1_one_bit_slp"
11931   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11932         (rotate:QI (match_dup 0)
11933                    (match_operand:QI 1 "const1_operand" "")))
11934    (clobber (reg:CC FLAGS_REG))]
11935   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11936    && (TARGET_SHIFT1 || optimize_size)"
11937   "rol{b}\t%0"
11938   [(set_attr "type" "rotate1")
11939    (set (attr "length") 
11940      (if_then_else (match_operand 0 "register_operand" "") 
11941         (const_string "2")
11942         (const_string "*")))])
11943
11944 (define_insn "*rotlqi3_1_one_bit"
11945   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11946         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11947                    (match_operand:QI 2 "const1_operand" "")))
11948    (clobber (reg:CC FLAGS_REG))]
11949   "ix86_binary_operator_ok (ROTATE, QImode, operands)
11950    && (TARGET_SHIFT1 || optimize_size)"
11951   "rol{b}\t%0"
11952   [(set_attr "type" "rotate")
11953    (set (attr "length") 
11954      (if_then_else (match_operand 0 "register_operand" "") 
11955         (const_string "2")
11956         (const_string "*")))])
11957
11958 (define_insn "*rotlqi3_1_slp"
11959   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11960         (rotate:QI (match_dup 0)
11961                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
11962    (clobber (reg:CC FLAGS_REG))]
11963   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11964    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11965   "@
11966    rol{b}\t{%1, %0|%0, %1}
11967    rol{b}\t{%b1, %0|%0, %b1}"
11968   [(set_attr "type" "rotate1")
11969    (set_attr "mode" "QI")])
11970
11971 (define_insn "*rotlqi3_1"
11972   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11973         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11974                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11975    (clobber (reg:CC FLAGS_REG))]
11976   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11977   "@
11978    rol{b}\t{%2, %0|%0, %2}
11979    rol{b}\t{%b2, %0|%0, %b2}"
11980   [(set_attr "type" "rotate")
11981    (set_attr "mode" "QI")])
11982
11983 (define_expand "rotrdi3"
11984   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11985         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11986                      (match_operand:QI 2 "nonmemory_operand" "")))
11987    (clobber (reg:CC FLAGS_REG))]
11988   "TARGET_64BIT"
11989   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11990
11991 (define_insn "*rotrdi3_1_one_bit_rex64"
11992   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11993         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11994                      (match_operand:QI 2 "const1_operand" "")))
11995    (clobber (reg:CC FLAGS_REG))]
11996   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11997    && (TARGET_SHIFT1 || optimize_size)"
11998   "ror{q}\t%0"
11999   [(set_attr "type" "rotate")
12000    (set (attr "length") 
12001      (if_then_else (match_operand:DI 0 "register_operand" "") 
12002         (const_string "2")
12003         (const_string "*")))])
12004
12005 (define_insn "*rotrdi3_1_rex64"
12006   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12007         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12008                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12009    (clobber (reg:CC FLAGS_REG))]
12010   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12011   "@
12012    ror{q}\t{%2, %0|%0, %2}
12013    ror{q}\t{%b2, %0|%0, %b2}"
12014   [(set_attr "type" "rotate")
12015    (set_attr "mode" "DI")])
12016
12017 (define_expand "rotrsi3"
12018   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12019         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12020                      (match_operand:QI 2 "nonmemory_operand" "")))
12021    (clobber (reg:CC FLAGS_REG))]
12022   ""
12023   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12024
12025 (define_insn "*rotrsi3_1_one_bit"
12026   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12027         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12028                      (match_operand:QI 2 "const1_operand" "")))
12029    (clobber (reg:CC FLAGS_REG))]
12030   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12031    && (TARGET_SHIFT1 || optimize_size)"
12032   "ror{l}\t%0"
12033   [(set_attr "type" "rotate")
12034    (set (attr "length") 
12035      (if_then_else (match_operand:SI 0 "register_operand" "") 
12036         (const_string "2")
12037         (const_string "*")))])
12038
12039 (define_insn "*rotrsi3_1_one_bit_zext"
12040   [(set (match_operand:DI 0 "register_operand" "=r")
12041         (zero_extend:DI
12042           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12043                        (match_operand:QI 2 "const1_operand" ""))))
12044    (clobber (reg:CC FLAGS_REG))]
12045   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12046    && (TARGET_SHIFT1 || optimize_size)"
12047   "ror{l}\t%k0"
12048   [(set_attr "type" "rotate")
12049    (set (attr "length") 
12050      (if_then_else (match_operand:SI 0 "register_operand" "") 
12051         (const_string "2")
12052         (const_string "*")))])
12053
12054 (define_insn "*rotrsi3_1"
12055   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12056         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12057                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12058    (clobber (reg:CC FLAGS_REG))]
12059   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12060   "@
12061    ror{l}\t{%2, %0|%0, %2}
12062    ror{l}\t{%b2, %0|%0, %b2}"
12063   [(set_attr "type" "rotate")
12064    (set_attr "mode" "SI")])
12065
12066 (define_insn "*rotrsi3_1_zext"
12067   [(set (match_operand:DI 0 "register_operand" "=r,r")
12068         (zero_extend:DI
12069           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12070                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12071    (clobber (reg:CC FLAGS_REG))]
12072   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12073   "@
12074    ror{l}\t{%2, %k0|%k0, %2}
12075    ror{l}\t{%b2, %k0|%k0, %b2}"
12076   [(set_attr "type" "rotate")
12077    (set_attr "mode" "SI")])
12078
12079 (define_expand "rotrhi3"
12080   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12081         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12082                      (match_operand:QI 2 "nonmemory_operand" "")))
12083    (clobber (reg:CC FLAGS_REG))]
12084   "TARGET_HIMODE_MATH"
12085   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12086
12087 (define_insn "*rotrhi3_one_bit"
12088   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12089         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12090                      (match_operand:QI 2 "const1_operand" "")))
12091    (clobber (reg:CC FLAGS_REG))]
12092   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12093    && (TARGET_SHIFT1 || optimize_size)"
12094   "ror{w}\t%0"
12095   [(set_attr "type" "rotate")
12096    (set (attr "length") 
12097      (if_then_else (match_operand 0 "register_operand" "") 
12098         (const_string "2")
12099         (const_string "*")))])
12100
12101 (define_insn "*rotrhi3"
12102   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12103         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12104                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12105    (clobber (reg:CC FLAGS_REG))]
12106   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12107   "@
12108    ror{w}\t{%2, %0|%0, %2}
12109    ror{w}\t{%b2, %0|%0, %b2}"
12110   [(set_attr "type" "rotate")
12111    (set_attr "mode" "HI")])
12112
12113 (define_expand "rotrqi3"
12114   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12115         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12116                      (match_operand:QI 2 "nonmemory_operand" "")))
12117    (clobber (reg:CC FLAGS_REG))]
12118   "TARGET_QIMODE_MATH"
12119   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12120
12121 (define_insn "*rotrqi3_1_one_bit"
12122   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12123         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12124                      (match_operand:QI 2 "const1_operand" "")))
12125    (clobber (reg:CC FLAGS_REG))]
12126   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12127    && (TARGET_SHIFT1 || optimize_size)"
12128   "ror{b}\t%0"
12129   [(set_attr "type" "rotate")
12130    (set (attr "length") 
12131      (if_then_else (match_operand 0 "register_operand" "") 
12132         (const_string "2")
12133         (const_string "*")))])
12134
12135 (define_insn "*rotrqi3_1_one_bit_slp"
12136   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12137         (rotatert:QI (match_dup 0)
12138                      (match_operand:QI 1 "const1_operand" "")))
12139    (clobber (reg:CC FLAGS_REG))]
12140   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12141    && (TARGET_SHIFT1 || optimize_size)"
12142   "ror{b}\t%0"
12143   [(set_attr "type" "rotate1")
12144    (set (attr "length") 
12145      (if_then_else (match_operand 0 "register_operand" "") 
12146         (const_string "2")
12147         (const_string "*")))])
12148
12149 (define_insn "*rotrqi3_1"
12150   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12151         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12152                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12153    (clobber (reg:CC FLAGS_REG))]
12154   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12155   "@
12156    ror{b}\t{%2, %0|%0, %2}
12157    ror{b}\t{%b2, %0|%0, %b2}"
12158   [(set_attr "type" "rotate")
12159    (set_attr "mode" "QI")])
12160
12161 (define_insn "*rotrqi3_1_slp"
12162   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12163         (rotatert:QI (match_dup 0)
12164                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12165    (clobber (reg:CC FLAGS_REG))]
12166   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12167    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12168   "@
12169    ror{b}\t{%1, %0|%0, %1}
12170    ror{b}\t{%b1, %0|%0, %b1}"
12171   [(set_attr "type" "rotate1")
12172    (set_attr "mode" "QI")])
12173 \f
12174 ;; Bit set / bit test instructions
12175
12176 (define_expand "extv"
12177   [(set (match_operand:SI 0 "register_operand" "")
12178         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12179                          (match_operand:SI 2 "immediate_operand" "")
12180                          (match_operand:SI 3 "immediate_operand" "")))]
12181   ""
12182 {
12183   /* Handle extractions from %ah et al.  */
12184   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12185     FAIL;
12186
12187   /* From mips.md: extract_bit_field doesn't verify that our source
12188      matches the predicate, so check it again here.  */
12189   if (! register_operand (operands[1], VOIDmode))
12190     FAIL;
12191 })
12192
12193 (define_expand "extzv"
12194   [(set (match_operand:SI 0 "register_operand" "")
12195         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12196                          (match_operand:SI 2 "immediate_operand" "")
12197                          (match_operand:SI 3 "immediate_operand" "")))]
12198   ""
12199 {
12200   /* Handle extractions from %ah et al.  */
12201   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12202     FAIL;
12203
12204   /* From mips.md: extract_bit_field doesn't verify that our source
12205      matches the predicate, so check it again here.  */
12206   if (! register_operand (operands[1], VOIDmode))
12207     FAIL;
12208 })
12209
12210 (define_expand "insv"
12211   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12212                       (match_operand 1 "immediate_operand" "")
12213                       (match_operand 2 "immediate_operand" ""))
12214         (match_operand 3 "register_operand" ""))]
12215   ""
12216 {
12217   /* Handle extractions from %ah et al.  */
12218   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12219     FAIL;
12220
12221   /* From mips.md: insert_bit_field doesn't verify that our source
12222      matches the predicate, so check it again here.  */
12223   if (! register_operand (operands[0], VOIDmode))
12224     FAIL;
12225
12226   if (TARGET_64BIT)
12227     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12228   else
12229     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12230
12231   DONE;
12232 })
12233
12234 ;; %%% bts, btr, btc, bt.
12235 ;; In general these instructions are *slow* when applied to memory,
12236 ;; since they enforce atomic operation.  When applied to registers,
12237 ;; it depends on the cpu implementation.  They're never faster than
12238 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12239 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12240 ;; within the instruction itself, so operating on bits in the high
12241 ;; 32-bits of a register becomes easier.
12242 ;;
12243 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12244 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12245 ;; negdf respectively, so they can never be disabled entirely.
12246
12247 (define_insn "*btsq"
12248   [(set (zero_extract:DI (match_operand 0 "register_operand" "+r")
12249                          (const_int 1)
12250                          (match_operand 1 "const_0_to_63_operand" ""))
12251         (const_int 1))
12252    (clobber (reg:CC FLAGS_REG))]
12253   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12254   "bts{q} %1,%0"
12255   [(set_attr "type" "alu1")])
12256
12257 (define_insn "*btrq"
12258   [(set (zero_extract:DI (match_operand 0 "register_operand" "+r")
12259                          (const_int 1)
12260                          (match_operand 1 "const_0_to_63_operand" ""))
12261         (const_int 0))
12262    (clobber (reg:CC FLAGS_REG))]
12263   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12264   "btr{q} %1,%0"
12265   [(set_attr "type" "alu1")])
12266
12267 (define_insn "*btcq"
12268   [(set (zero_extract:DI (match_operand 0 "register_operand" "+r")
12269                          (const_int 1)
12270                          (match_operand 1 "const_0_to_63_operand" ""))
12271         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12272    (clobber (reg:CC FLAGS_REG))]
12273   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12274   "btc{q} %1,%0"
12275   [(set_attr "type" "alu1")])
12276
12277 ;; Allow Nocona to avoid these instructions if a register is available.
12278
12279 (define_peephole2
12280   [(match_scratch:DI 2 "r")
12281    (parallel [(set (zero_extract:DI
12282                      (match_operand 0 "register_operand" "")
12283                      (const_int 1)
12284                      (match_operand 1 "const_0_to_63_operand" ""))
12285                    (const_int 1))
12286               (clobber (reg:CC FLAGS_REG))])]
12287   "TARGET_64BIT && !TARGET_USE_BT"
12288   [(const_int 0)]
12289 {
12290   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12291   rtx op1;
12292
12293   if (HOST_BITS_PER_WIDE_INT >= 64)
12294     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12295   else if (i < HOST_BITS_PER_WIDE_INT)
12296     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12297   else
12298     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12299
12300   op1 = immed_double_const (lo, hi, DImode);
12301   if (i >= 31)
12302     {
12303       emit_move_insn (operands[2], op1);
12304       op1 = operands[2];
12305     }
12306
12307   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12308   DONE;
12309 })
12310
12311 (define_peephole2
12312   [(match_scratch:DI 2 "r")
12313    (parallel [(set (zero_extract:DI
12314                      (match_operand 0 "register_operand" "")
12315                      (const_int 1)
12316                      (match_operand 1 "const_0_to_63_operand" ""))
12317                    (const_int 0))
12318               (clobber (reg:CC FLAGS_REG))])]
12319   "TARGET_64BIT && !TARGET_USE_BT"
12320   [(const_int 0)]
12321 {
12322   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12323   rtx op1;
12324
12325   if (HOST_BITS_PER_WIDE_INT >= 64)
12326     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12327   else if (i < HOST_BITS_PER_WIDE_INT)
12328     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12329   else
12330     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12331
12332   op1 = immed_double_const (~lo, ~hi, DImode);
12333   if (i >= 32)
12334     {
12335       emit_move_insn (operands[2], op1);
12336       op1 = operands[2];
12337     }
12338
12339   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12340   DONE;
12341 })
12342
12343 (define_peephole2
12344   [(match_scratch:DI 2 "r")
12345    (parallel [(set (zero_extract:DI
12346                      (match_operand 0 "register_operand" "")
12347                      (const_int 1)
12348                      (match_operand 1 "const_0_to_63_operand" ""))
12349               (not:DI (zero_extract:DI
12350                         (match_dup 0) (const_int 1) (match_dup 1))))
12351               (clobber (reg:CC FLAGS_REG))])]
12352   "TARGET_64BIT && !TARGET_USE_BT"
12353   [(const_int 0)]
12354 {
12355   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12356   rtx op1;
12357
12358   if (HOST_BITS_PER_WIDE_INT >= 64)
12359     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12360   else if (i < HOST_BITS_PER_WIDE_INT)
12361     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12362   else
12363     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12364
12365   op1 = immed_double_const (lo, hi, DImode);
12366   if (i >= 31)
12367     {
12368       emit_move_insn (operands[2], op1);
12369       op1 = operands[2];
12370     }
12371
12372   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12373   DONE;
12374 })
12375 \f
12376 ;; Store-flag instructions.
12377
12378 ;; For all sCOND expanders, also expand the compare or test insn that
12379 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12380
12381 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12382 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12383 ;; way, which can later delete the movzx if only QImode is needed.
12384
12385 (define_expand "seq"
12386   [(set (match_operand:QI 0 "register_operand" "")
12387         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12388   ""
12389   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12390
12391 (define_expand "sne"
12392   [(set (match_operand:QI 0 "register_operand" "")
12393         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12394   ""
12395   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12396
12397 (define_expand "sgt"
12398   [(set (match_operand:QI 0 "register_operand" "")
12399         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12400   ""
12401   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12402
12403 (define_expand "sgtu"
12404   [(set (match_operand:QI 0 "register_operand" "")
12405         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12406   ""
12407   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12408
12409 (define_expand "slt"
12410   [(set (match_operand:QI 0 "register_operand" "")
12411         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12412   ""
12413   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12414
12415 (define_expand "sltu"
12416   [(set (match_operand:QI 0 "register_operand" "")
12417         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12418   ""
12419   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12420
12421 (define_expand "sge"
12422   [(set (match_operand:QI 0 "register_operand" "")
12423         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12424   ""
12425   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12426
12427 (define_expand "sgeu"
12428   [(set (match_operand:QI 0 "register_operand" "")
12429         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12430   ""
12431   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12432
12433 (define_expand "sle"
12434   [(set (match_operand:QI 0 "register_operand" "")
12435         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12436   ""
12437   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12438
12439 (define_expand "sleu"
12440   [(set (match_operand:QI 0 "register_operand" "")
12441         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12442   ""
12443   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12444
12445 (define_expand "sunordered"
12446   [(set (match_operand:QI 0 "register_operand" "")
12447         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12448   "TARGET_80387 || TARGET_SSE"
12449   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12450
12451 (define_expand "sordered"
12452   [(set (match_operand:QI 0 "register_operand" "")
12453         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12454   "TARGET_80387"
12455   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12456
12457 (define_expand "suneq"
12458   [(set (match_operand:QI 0 "register_operand" "")
12459         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12460   "TARGET_80387 || TARGET_SSE"
12461   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12462
12463 (define_expand "sunge"
12464   [(set (match_operand:QI 0 "register_operand" "")
12465         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12466   "TARGET_80387 || TARGET_SSE"
12467   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12468
12469 (define_expand "sungt"
12470   [(set (match_operand:QI 0 "register_operand" "")
12471         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12472   "TARGET_80387 || TARGET_SSE"
12473   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12474
12475 (define_expand "sunle"
12476   [(set (match_operand:QI 0 "register_operand" "")
12477         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12478   "TARGET_80387 || TARGET_SSE"
12479   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12480
12481 (define_expand "sunlt"
12482   [(set (match_operand:QI 0 "register_operand" "")
12483         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12484   "TARGET_80387 || TARGET_SSE"
12485   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12486
12487 (define_expand "sltgt"
12488   [(set (match_operand:QI 0 "register_operand" "")
12489         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12490   "TARGET_80387 || TARGET_SSE"
12491   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12492
12493 (define_insn "*setcc_1"
12494   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12495         (match_operator:QI 1 "ix86_comparison_operator"
12496           [(reg FLAGS_REG) (const_int 0)]))]
12497   ""
12498   "set%C1\t%0"
12499   [(set_attr "type" "setcc")
12500    (set_attr "mode" "QI")])
12501
12502 (define_insn "*setcc_2"
12503   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12504         (match_operator:QI 1 "ix86_comparison_operator"
12505           [(reg FLAGS_REG) (const_int 0)]))]
12506   ""
12507   "set%C1\t%0"
12508   [(set_attr "type" "setcc")
12509    (set_attr "mode" "QI")])
12510
12511 ;; In general it is not safe to assume too much about CCmode registers,
12512 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12513 ;; conditions this is safe on x86, so help combine not create
12514 ;;
12515 ;;      seta    %al
12516 ;;      testb   %al, %al
12517 ;;      sete    %al
12518
12519 (define_split 
12520   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12521         (ne:QI (match_operator 1 "ix86_comparison_operator"
12522                  [(reg FLAGS_REG) (const_int 0)])
12523             (const_int 0)))]
12524   ""
12525   [(set (match_dup 0) (match_dup 1))]
12526 {
12527   PUT_MODE (operands[1], QImode);
12528 })
12529
12530 (define_split 
12531   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12532         (ne:QI (match_operator 1 "ix86_comparison_operator"
12533                  [(reg FLAGS_REG) (const_int 0)])
12534             (const_int 0)))]
12535   ""
12536   [(set (match_dup 0) (match_dup 1))]
12537 {
12538   PUT_MODE (operands[1], QImode);
12539 })
12540
12541 (define_split 
12542   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12543         (eq:QI (match_operator 1 "ix86_comparison_operator"
12544                  [(reg FLAGS_REG) (const_int 0)])
12545             (const_int 0)))]
12546   ""
12547   [(set (match_dup 0) (match_dup 1))]
12548 {
12549   rtx new_op1 = copy_rtx (operands[1]);
12550   operands[1] = new_op1;
12551   PUT_MODE (new_op1, QImode);
12552   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12553                                              GET_MODE (XEXP (new_op1, 0))));
12554
12555   /* Make sure that (a) the CCmode we have for the flags is strong
12556      enough for the reversed compare or (b) we have a valid FP compare.  */
12557   if (! ix86_comparison_operator (new_op1, VOIDmode))
12558     FAIL;
12559 })
12560
12561 (define_split 
12562   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12563         (eq:QI (match_operator 1 "ix86_comparison_operator"
12564                  [(reg FLAGS_REG) (const_int 0)])
12565             (const_int 0)))]
12566   ""
12567   [(set (match_dup 0) (match_dup 1))]
12568 {
12569   rtx new_op1 = copy_rtx (operands[1]);
12570   operands[1] = new_op1;
12571   PUT_MODE (new_op1, QImode);
12572   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12573                                              GET_MODE (XEXP (new_op1, 0))));
12574
12575   /* Make sure that (a) the CCmode we have for the flags is strong
12576      enough for the reversed compare or (b) we have a valid FP compare.  */
12577   if (! ix86_comparison_operator (new_op1, VOIDmode))
12578     FAIL;
12579 })
12580
12581 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12582 ;; subsequent logical operations are used to imitate conditional moves.
12583 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12584 ;; it directly.  Further holding this value in pseudo register might bring
12585 ;; problem in implicit normalization in spill code.
12586 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12587 ;; instructions after reload by splitting the conditional move patterns.
12588
12589 (define_insn "*sse_setccsf"
12590   [(set (match_operand:SF 0 "register_operand" "=x")
12591         (match_operator:SF 1 "sse_comparison_operator"
12592           [(match_operand:SF 2 "register_operand" "0")
12593            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12594   "TARGET_SSE && reload_completed"
12595   "cmp%D1ss\t{%3, %0|%0, %3}"
12596   [(set_attr "type" "ssecmp")
12597    (set_attr "mode" "SF")])
12598
12599 (define_insn "*sse_setccdf"
12600   [(set (match_operand:DF 0 "register_operand" "=Y")
12601         (match_operator:DF 1 "sse_comparison_operator"
12602           [(match_operand:DF 2 "register_operand" "0")
12603            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12604   "TARGET_SSE2 && reload_completed"
12605   "cmp%D1sd\t{%3, %0|%0, %3}"
12606   [(set_attr "type" "ssecmp")
12607    (set_attr "mode" "DF")])
12608 \f
12609 ;; Basic conditional jump instructions.
12610 ;; We ignore the overflow flag for signed branch instructions.
12611
12612 ;; For all bCOND expanders, also expand the compare or test insn that
12613 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12614
12615 (define_expand "beq"
12616   [(set (pc)
12617         (if_then_else (match_dup 1)
12618                       (label_ref (match_operand 0 "" ""))
12619                       (pc)))]
12620   ""
12621   "ix86_expand_branch (EQ, operands[0]); DONE;")
12622
12623 (define_expand "bne"
12624   [(set (pc)
12625         (if_then_else (match_dup 1)
12626                       (label_ref (match_operand 0 "" ""))
12627                       (pc)))]
12628   ""
12629   "ix86_expand_branch (NE, operands[0]); DONE;")
12630
12631 (define_expand "bgt"
12632   [(set (pc)
12633         (if_then_else (match_dup 1)
12634                       (label_ref (match_operand 0 "" ""))
12635                       (pc)))]
12636   ""
12637   "ix86_expand_branch (GT, operands[0]); DONE;")
12638
12639 (define_expand "bgtu"
12640   [(set (pc)
12641         (if_then_else (match_dup 1)
12642                       (label_ref (match_operand 0 "" ""))
12643                       (pc)))]
12644   ""
12645   "ix86_expand_branch (GTU, operands[0]); DONE;")
12646
12647 (define_expand "blt"
12648   [(set (pc)
12649         (if_then_else (match_dup 1)
12650                       (label_ref (match_operand 0 "" ""))
12651                       (pc)))]
12652   ""
12653   "ix86_expand_branch (LT, operands[0]); DONE;")
12654
12655 (define_expand "bltu"
12656   [(set (pc)
12657         (if_then_else (match_dup 1)
12658                       (label_ref (match_operand 0 "" ""))
12659                       (pc)))]
12660   ""
12661   "ix86_expand_branch (LTU, operands[0]); DONE;")
12662
12663 (define_expand "bge"
12664   [(set (pc)
12665         (if_then_else (match_dup 1)
12666                       (label_ref (match_operand 0 "" ""))
12667                       (pc)))]
12668   ""
12669   "ix86_expand_branch (GE, operands[0]); DONE;")
12670
12671 (define_expand "bgeu"
12672   [(set (pc)
12673         (if_then_else (match_dup 1)
12674                       (label_ref (match_operand 0 "" ""))
12675                       (pc)))]
12676   ""
12677   "ix86_expand_branch (GEU, operands[0]); DONE;")
12678
12679 (define_expand "ble"
12680   [(set (pc)
12681         (if_then_else (match_dup 1)
12682                       (label_ref (match_operand 0 "" ""))
12683                       (pc)))]
12684   ""
12685   "ix86_expand_branch (LE, operands[0]); DONE;")
12686
12687 (define_expand "bleu"
12688   [(set (pc)
12689         (if_then_else (match_dup 1)
12690                       (label_ref (match_operand 0 "" ""))
12691                       (pc)))]
12692   ""
12693   "ix86_expand_branch (LEU, operands[0]); DONE;")
12694
12695 (define_expand "bunordered"
12696   [(set (pc)
12697         (if_then_else (match_dup 1)
12698                       (label_ref (match_operand 0 "" ""))
12699                       (pc)))]
12700   "TARGET_80387 || TARGET_SSE"
12701   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12702
12703 (define_expand "bordered"
12704   [(set (pc)
12705         (if_then_else (match_dup 1)
12706                       (label_ref (match_operand 0 "" ""))
12707                       (pc)))]
12708   "TARGET_80387 || TARGET_SSE"
12709   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12710
12711 (define_expand "buneq"
12712   [(set (pc)
12713         (if_then_else (match_dup 1)
12714                       (label_ref (match_operand 0 "" ""))
12715                       (pc)))]
12716   "TARGET_80387 || TARGET_SSE"
12717   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12718
12719 (define_expand "bunge"
12720   [(set (pc)
12721         (if_then_else (match_dup 1)
12722                       (label_ref (match_operand 0 "" ""))
12723                       (pc)))]
12724   "TARGET_80387 || TARGET_SSE"
12725   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12726
12727 (define_expand "bungt"
12728   [(set (pc)
12729         (if_then_else (match_dup 1)
12730                       (label_ref (match_operand 0 "" ""))
12731                       (pc)))]
12732   "TARGET_80387 || TARGET_SSE"
12733   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12734
12735 (define_expand "bunle"
12736   [(set (pc)
12737         (if_then_else (match_dup 1)
12738                       (label_ref (match_operand 0 "" ""))
12739                       (pc)))]
12740   "TARGET_80387 || TARGET_SSE"
12741   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12742
12743 (define_expand "bunlt"
12744   [(set (pc)
12745         (if_then_else (match_dup 1)
12746                       (label_ref (match_operand 0 "" ""))
12747                       (pc)))]
12748   "TARGET_80387 || TARGET_SSE"
12749   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12750
12751 (define_expand "bltgt"
12752   [(set (pc)
12753         (if_then_else (match_dup 1)
12754                       (label_ref (match_operand 0 "" ""))
12755                       (pc)))]
12756   "TARGET_80387 || TARGET_SSE"
12757   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12758
12759 (define_insn "*jcc_1"
12760   [(set (pc)
12761         (if_then_else (match_operator 1 "ix86_comparison_operator"
12762                                       [(reg FLAGS_REG) (const_int 0)])
12763                       (label_ref (match_operand 0 "" ""))
12764                       (pc)))]
12765   ""
12766   "%+j%C1\t%l0"
12767   [(set_attr "type" "ibr")
12768    (set_attr "modrm" "0")
12769    (set (attr "length")
12770            (if_then_else (and (ge (minus (match_dup 0) (pc))
12771                                   (const_int -126))
12772                               (lt (minus (match_dup 0) (pc))
12773                                   (const_int 128)))
12774              (const_int 2)
12775              (const_int 6)))])
12776
12777 (define_insn "*jcc_2"
12778   [(set (pc)
12779         (if_then_else (match_operator 1 "ix86_comparison_operator"
12780                                       [(reg FLAGS_REG) (const_int 0)])
12781                       (pc)
12782                       (label_ref (match_operand 0 "" ""))))]
12783   ""
12784   "%+j%c1\t%l0"
12785   [(set_attr "type" "ibr")
12786    (set_attr "modrm" "0")
12787    (set (attr "length")
12788            (if_then_else (and (ge (minus (match_dup 0) (pc))
12789                                   (const_int -126))
12790                               (lt (minus (match_dup 0) (pc))
12791                                   (const_int 128)))
12792              (const_int 2)
12793              (const_int 6)))])
12794
12795 ;; In general it is not safe to assume too much about CCmode registers,
12796 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12797 ;; conditions this is safe on x86, so help combine not create
12798 ;;
12799 ;;      seta    %al
12800 ;;      testb   %al, %al
12801 ;;      je      Lfoo
12802
12803 (define_split 
12804   [(set (pc)
12805         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12806                                       [(reg FLAGS_REG) (const_int 0)])
12807                           (const_int 0))
12808                       (label_ref (match_operand 1 "" ""))
12809                       (pc)))]
12810   ""
12811   [(set (pc)
12812         (if_then_else (match_dup 0)
12813                       (label_ref (match_dup 1))
12814                       (pc)))]
12815 {
12816   PUT_MODE (operands[0], VOIDmode);
12817 })
12818   
12819 (define_split 
12820   [(set (pc)
12821         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12822                                       [(reg FLAGS_REG) (const_int 0)])
12823                           (const_int 0))
12824                       (label_ref (match_operand 1 "" ""))
12825                       (pc)))]
12826   ""
12827   [(set (pc)
12828         (if_then_else (match_dup 0)
12829                       (label_ref (match_dup 1))
12830                       (pc)))]
12831 {
12832   rtx new_op0 = copy_rtx (operands[0]);
12833   operands[0] = new_op0;
12834   PUT_MODE (new_op0, VOIDmode);
12835   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12836                                              GET_MODE (XEXP (new_op0, 0))));
12837
12838   /* Make sure that (a) the CCmode we have for the flags is strong
12839      enough for the reversed compare or (b) we have a valid FP compare.  */
12840   if (! ix86_comparison_operator (new_op0, VOIDmode))
12841     FAIL;
12842 })
12843
12844 ;; Define combination compare-and-branch fp compare instructions to use
12845 ;; during early optimization.  Splitting the operation apart early makes
12846 ;; for bad code when we want to reverse the operation.
12847
12848 (define_insn "*fp_jcc_1"
12849   [(set (pc)
12850         (if_then_else (match_operator 0 "comparison_operator"
12851                         [(match_operand 1 "register_operand" "f")
12852                          (match_operand 2 "register_operand" "f")])
12853           (label_ref (match_operand 3 "" ""))
12854           (pc)))
12855    (clobber (reg:CCFP FPSR_REG))
12856    (clobber (reg:CCFP FLAGS_REG))]
12857   "TARGET_CMOVE && TARGET_80387
12858    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12859    && FLOAT_MODE_P (GET_MODE (operands[1]))
12860    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12861    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12862   "#")
12863
12864 (define_insn "*fp_jcc_1_sse"
12865   [(set (pc)
12866         (if_then_else (match_operator 0 "comparison_operator"
12867                         [(match_operand 1 "register_operand" "f#x,x#f")
12868                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12869           (label_ref (match_operand 3 "" ""))
12870           (pc)))
12871    (clobber (reg:CCFP FPSR_REG))
12872    (clobber (reg:CCFP FLAGS_REG))]
12873   "TARGET_80387
12874    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12875    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12876    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12877   "#")
12878
12879 (define_insn "*fp_jcc_1_sse_only"
12880   [(set (pc)
12881         (if_then_else (match_operator 0 "comparison_operator"
12882                         [(match_operand 1 "register_operand" "x")
12883                          (match_operand 2 "nonimmediate_operand" "xm")])
12884           (label_ref (match_operand 3 "" ""))
12885           (pc)))
12886    (clobber (reg:CCFP FPSR_REG))
12887    (clobber (reg:CCFP FLAGS_REG))]
12888   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12889    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12890    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12891   "#")
12892
12893 (define_insn "*fp_jcc_2"
12894   [(set (pc)
12895         (if_then_else (match_operator 0 "comparison_operator"
12896                         [(match_operand 1 "register_operand" "f")
12897                          (match_operand 2 "register_operand" "f")])
12898           (pc)
12899           (label_ref (match_operand 3 "" ""))))
12900    (clobber (reg:CCFP FPSR_REG))
12901    (clobber (reg:CCFP FLAGS_REG))]
12902   "TARGET_CMOVE && TARGET_80387
12903    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12904    && FLOAT_MODE_P (GET_MODE (operands[1]))
12905    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12906    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12907   "#")
12908
12909 (define_insn "*fp_jcc_2_sse"
12910   [(set (pc)
12911         (if_then_else (match_operator 0 "comparison_operator"
12912                         [(match_operand 1 "register_operand" "f#x,x#f")
12913                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12914           (pc)
12915           (label_ref (match_operand 3 "" ""))))
12916    (clobber (reg:CCFP FPSR_REG))
12917    (clobber (reg:CCFP FLAGS_REG))]
12918   "TARGET_80387
12919    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12920    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12921    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12922   "#")
12923
12924 (define_insn "*fp_jcc_2_sse_only"
12925   [(set (pc)
12926         (if_then_else (match_operator 0 "comparison_operator"
12927                         [(match_operand 1 "register_operand" "x")
12928                          (match_operand 2 "nonimmediate_operand" "xm")])
12929           (pc)
12930           (label_ref (match_operand 3 "" ""))))
12931    (clobber (reg:CCFP FPSR_REG))
12932    (clobber (reg:CCFP FLAGS_REG))]
12933   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12934    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12935    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12936   "#")
12937
12938 (define_insn "*fp_jcc_3"
12939   [(set (pc)
12940         (if_then_else (match_operator 0 "comparison_operator"
12941                         [(match_operand 1 "register_operand" "f")
12942                          (match_operand 2 "nonimmediate_operand" "fm")])
12943           (label_ref (match_operand 3 "" ""))
12944           (pc)))
12945    (clobber (reg:CCFP FPSR_REG))
12946    (clobber (reg:CCFP FLAGS_REG))
12947    (clobber (match_scratch:HI 4 "=a"))]
12948   "TARGET_80387
12949    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12950    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12951    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12952    && SELECT_CC_MODE (GET_CODE (operands[0]),
12953                       operands[1], operands[2]) == CCFPmode
12954    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12955   "#")
12956
12957 (define_insn "*fp_jcc_4"
12958   [(set (pc)
12959         (if_then_else (match_operator 0 "comparison_operator"
12960                         [(match_operand 1 "register_operand" "f")
12961                          (match_operand 2 "nonimmediate_operand" "fm")])
12962           (pc)
12963           (label_ref (match_operand 3 "" ""))))
12964    (clobber (reg:CCFP FPSR_REG))
12965    (clobber (reg:CCFP FLAGS_REG))
12966    (clobber (match_scratch:HI 4 "=a"))]
12967   "TARGET_80387
12968    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12969    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12970    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12971    && SELECT_CC_MODE (GET_CODE (operands[0]),
12972                       operands[1], operands[2]) == CCFPmode
12973    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12974   "#")
12975
12976 (define_insn "*fp_jcc_5"
12977   [(set (pc)
12978         (if_then_else (match_operator 0 "comparison_operator"
12979                         [(match_operand 1 "register_operand" "f")
12980                          (match_operand 2 "register_operand" "f")])
12981           (label_ref (match_operand 3 "" ""))
12982           (pc)))
12983    (clobber (reg:CCFP FPSR_REG))
12984    (clobber (reg:CCFP FLAGS_REG))
12985    (clobber (match_scratch:HI 4 "=a"))]
12986   "TARGET_80387
12987    && FLOAT_MODE_P (GET_MODE (operands[1]))
12988    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12989    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12990   "#")
12991
12992 (define_insn "*fp_jcc_6"
12993   [(set (pc)
12994         (if_then_else (match_operator 0 "comparison_operator"
12995                         [(match_operand 1 "register_operand" "f")
12996                          (match_operand 2 "register_operand" "f")])
12997           (pc)
12998           (label_ref (match_operand 3 "" ""))))
12999    (clobber (reg:CCFP FPSR_REG))
13000    (clobber (reg:CCFP FLAGS_REG))
13001    (clobber (match_scratch:HI 4 "=a"))]
13002   "TARGET_80387
13003    && FLOAT_MODE_P (GET_MODE (operands[1]))
13004    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13005    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13006   "#")
13007
13008 (define_insn "*fp_jcc_7"
13009   [(set (pc)
13010         (if_then_else (match_operator 0 "comparison_operator"
13011                         [(match_operand 1 "register_operand" "f")
13012                          (match_operand 2 "const_double_operand" "C")])
13013           (label_ref (match_operand 3 "" ""))
13014           (pc)))
13015    (clobber (reg:CCFP FPSR_REG))
13016    (clobber (reg:CCFP FLAGS_REG))
13017    (clobber (match_scratch:HI 4 "=a"))]
13018   "TARGET_80387
13019    && FLOAT_MODE_P (GET_MODE (operands[1]))
13020    && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
13021    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13022    && SELECT_CC_MODE (GET_CODE (operands[0]),
13023                       operands[1], operands[2]) == CCFPmode
13024    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13025   "#")
13026
13027 ;; The order of operands in *fp_jcc_8 is forced by combine in
13028 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13029 ;; with a precedence over other operators and is always put in the first
13030 ;; place. Swap condition and operands to match ficom instruction.
13031
13032 (define_insn "*fp_jcc_8"
13033   [(set (pc)
13034         (if_then_else (match_operator 0 "comparison_operator"
13035                         [(match_operator 1 "float_operator"
13036                            [(match_operand:SI 2 "nonimmediate_operand" "m,?r")])
13037                            (match_operand 3 "register_operand" "f,f")])
13038           (label_ref (match_operand 4 "" ""))
13039           (pc)))
13040    (clobber (reg:CCFP FPSR_REG))
13041    (clobber (reg:CCFP FLAGS_REG))
13042    (clobber (match_scratch:HI 5 "=a,a"))]
13043   "TARGET_80387 && TARGET_USE_FIOP
13044    && FLOAT_MODE_P (GET_MODE (operands[3]))
13045    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13046    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13047    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13048    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13049   "#")
13050
13051 (define_split
13052   [(set (pc)
13053         (if_then_else (match_operator 0 "comparison_operator"
13054                         [(match_operand 1 "register_operand" "")
13055                          (match_operand 2 "nonimmediate_operand" "")])
13056           (match_operand 3 "" "")
13057           (match_operand 4 "" "")))
13058    (clobber (reg:CCFP FPSR_REG))
13059    (clobber (reg:CCFP FLAGS_REG))]
13060   "reload_completed"
13061   [(const_int 0)]
13062 {
13063   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13064                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13065   DONE;
13066 })
13067
13068 (define_split
13069   [(set (pc)
13070         (if_then_else (match_operator 0 "comparison_operator"
13071                         [(match_operand 1 "register_operand" "")
13072                          (match_operand 2 "general_operand" "")])
13073           (match_operand 3 "" "")
13074           (match_operand 4 "" "")))
13075    (clobber (reg:CCFP FPSR_REG))
13076    (clobber (reg:CCFP FLAGS_REG))
13077    (clobber (match_scratch:HI 5 "=a"))]
13078   "reload_completed"
13079   [(const_int 0)]
13080 {
13081   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13082                         operands[3], operands[4], operands[5], NULL_RTX);
13083   DONE;
13084 })
13085
13086 (define_split
13087   [(set (pc)
13088         (if_then_else (match_operator 0 "comparison_operator"
13089                         [(match_operator 1 "float_operator"
13090                            [(match_operand:SI 2 "memory_operand" "")])
13091                            (match_operand 3 "register_operand" "")])
13092           (match_operand 4 "" "")
13093           (match_operand 5 "" "")))
13094    (clobber (reg:CCFP FPSR_REG))
13095    (clobber (reg:CCFP FLAGS_REG))
13096    (clobber (match_scratch:HI 6 "=a"))]
13097   "reload_completed"
13098   [(const_int 0)]
13099 {
13100   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13101   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13102                         operands[3], operands[7],
13103                         operands[4], operands[5], operands[6], NULL_RTX);
13104   DONE;
13105 })
13106
13107 ;; %%% Kill this when reload knows how to do it.
13108 (define_split
13109   [(set (pc)
13110         (if_then_else (match_operator 0 "comparison_operator"
13111                         [(match_operator 1 "float_operator"
13112                            [(match_operand:SI 2 "register_operand" "")])
13113                            (match_operand 3 "register_operand" "")])
13114           (match_operand 4 "" "")
13115           (match_operand 5 "" "")))
13116    (clobber (reg:CCFP FPSR_REG))
13117    (clobber (reg:CCFP FLAGS_REG))
13118    (clobber (match_scratch:HI 6 "=a"))]
13119   "reload_completed"
13120   [(const_int 0)]
13121 {
13122   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13123   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13124   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13125                         operands[3], operands[7],
13126                         operands[4], operands[5], operands[6], operands[2]);
13127   DONE;
13128 })
13129 \f
13130 ;; Unconditional and other jump instructions
13131
13132 (define_insn "jump"
13133   [(set (pc)
13134         (label_ref (match_operand 0 "" "")))]
13135   ""
13136   "jmp\t%l0"
13137   [(set_attr "type" "ibr")
13138    (set (attr "length")
13139            (if_then_else (and (ge (minus (match_dup 0) (pc))
13140                                   (const_int -126))
13141                               (lt (minus (match_dup 0) (pc))
13142                                   (const_int 128)))
13143              (const_int 2)
13144              (const_int 5)))
13145    (set_attr "modrm" "0")])
13146
13147 (define_expand "indirect_jump"
13148   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13149   ""
13150   "")
13151
13152 (define_insn "*indirect_jump"
13153   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13154   "!TARGET_64BIT"
13155   "jmp\t%A0"
13156   [(set_attr "type" "ibr")
13157    (set_attr "length_immediate" "0")])
13158
13159 (define_insn "*indirect_jump_rtx64"
13160   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13161   "TARGET_64BIT"
13162   "jmp\t%A0"
13163   [(set_attr "type" "ibr")
13164    (set_attr "length_immediate" "0")])
13165
13166 (define_expand "tablejump"
13167   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13168               (use (label_ref (match_operand 1 "" "")))])]
13169   ""
13170 {
13171   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13172      relative.  Convert the relative address to an absolute address.  */
13173   if (flag_pic)
13174     {
13175       rtx op0, op1;
13176       enum rtx_code code;
13177
13178       if (TARGET_64BIT)
13179         {
13180           code = PLUS;
13181           op0 = operands[0];
13182           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13183         }
13184       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13185         {
13186           code = PLUS;
13187           op0 = operands[0];
13188           op1 = pic_offset_table_rtx;
13189         }
13190       else
13191         {
13192           code = MINUS;
13193           op0 = pic_offset_table_rtx;
13194           op1 = operands[0];
13195         }
13196
13197       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13198                                          OPTAB_DIRECT);
13199     }
13200 })
13201
13202 (define_insn "*tablejump_1"
13203   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13204    (use (label_ref (match_operand 1 "" "")))]
13205   "!TARGET_64BIT"
13206   "jmp\t%A0"
13207   [(set_attr "type" "ibr")
13208    (set_attr "length_immediate" "0")])
13209
13210 (define_insn "*tablejump_1_rtx64"
13211   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13212    (use (label_ref (match_operand 1 "" "")))]
13213   "TARGET_64BIT"
13214   "jmp\t%A0"
13215   [(set_attr "type" "ibr")
13216    (set_attr "length_immediate" "0")])
13217 \f
13218 ;; Loop instruction
13219 ;;
13220 ;; This is all complicated by the fact that since this is a jump insn
13221 ;; we must handle our own reloads.
13222
13223 (define_expand "doloop_end"
13224   [(use (match_operand 0 "" ""))        ; loop pseudo
13225    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13226    (use (match_operand 2 "" ""))        ; max iterations
13227    (use (match_operand 3 "" ""))        ; loop level 
13228    (use (match_operand 4 "" ""))]       ; label
13229   "!TARGET_64BIT && TARGET_USE_LOOP"
13230   "                                 
13231 {
13232   /* Only use cloop on innermost loops.  */
13233   if (INTVAL (operands[3]) > 1)
13234     FAIL;
13235   if (GET_MODE (operands[0]) != SImode)
13236     FAIL;
13237   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13238                                            operands[0]));
13239   DONE;
13240 }")
13241
13242 (define_insn "doloop_end_internal"
13243   [(set (pc)
13244         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13245                           (const_int 1))
13246                       (label_ref (match_operand 0 "" ""))
13247                       (pc)))
13248    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13249         (plus:SI (match_dup 1)
13250                  (const_int -1)))
13251    (clobber (match_scratch:SI 3 "=X,X,r"))
13252    (clobber (reg:CC FLAGS_REG))]
13253   "!TARGET_64BIT && TARGET_USE_LOOP
13254    && (reload_in_progress || reload_completed
13255        || register_operand (operands[2], VOIDmode))"
13256 {
13257   if (which_alternative != 0)
13258     return "#";
13259   if (get_attr_length (insn) == 2)
13260     return "%+loop\t%l0";
13261   else
13262     return "dec{l}\t%1\;%+jne\t%l0";
13263 }
13264   [(set (attr "length")
13265         (if_then_else (and (eq_attr "alternative" "0")
13266                            (and (ge (minus (match_dup 0) (pc))
13267                                     (const_int -126))
13268                                 (lt (minus (match_dup 0) (pc))
13269                                     (const_int 128))))
13270                       (const_int 2)
13271                       (const_int 16)))
13272    ;; We don't know the type before shorten branches.  Optimistically expect
13273    ;; the loop instruction to match.
13274    (set (attr "type") (const_string "ibr"))])
13275
13276 (define_split
13277   [(set (pc)
13278         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13279                           (const_int 1))
13280                       (match_operand 0 "" "")
13281                       (pc)))
13282    (set (match_dup 1)
13283         (plus:SI (match_dup 1)
13284                  (const_int -1)))
13285    (clobber (match_scratch:SI 2 ""))
13286    (clobber (reg:CC FLAGS_REG))]
13287   "!TARGET_64BIT && TARGET_USE_LOOP
13288    && reload_completed
13289    && REGNO (operands[1]) != 2"
13290   [(parallel [(set (reg:CCZ FLAGS_REG)
13291                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13292                                  (const_int 0)))
13293               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13294    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13295                            (match_dup 0)
13296                            (pc)))]
13297   "")
13298   
13299 (define_split
13300   [(set (pc)
13301         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13302                           (const_int 1))
13303                       (match_operand 0 "" "")
13304                       (pc)))
13305    (set (match_operand:SI 2 "nonimmediate_operand" "")
13306         (plus:SI (match_dup 1)
13307                  (const_int -1)))
13308    (clobber (match_scratch:SI 3 ""))
13309    (clobber (reg:CC FLAGS_REG))]
13310   "!TARGET_64BIT && TARGET_USE_LOOP
13311    && reload_completed
13312    && (! REG_P (operands[2])
13313        || ! rtx_equal_p (operands[1], operands[2]))"
13314   [(set (match_dup 3) (match_dup 1))
13315    (parallel [(set (reg:CCZ FLAGS_REG)
13316                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13317                                 (const_int 0)))
13318               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13319    (set (match_dup 2) (match_dup 3))
13320    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13321                            (match_dup 0)
13322                            (pc)))]
13323   "")
13324
13325 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13326
13327 (define_peephole2
13328   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13329    (set (match_operand:QI 1 "register_operand" "")
13330         (match_operator:QI 2 "ix86_comparison_operator"
13331           [(reg FLAGS_REG) (const_int 0)]))
13332    (set (match_operand 3 "q_regs_operand" "")
13333         (zero_extend (match_dup 1)))]
13334   "(peep2_reg_dead_p (3, operands[1])
13335     || operands_match_p (operands[1], operands[3]))
13336    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13337   [(set (match_dup 4) (match_dup 0))
13338    (set (strict_low_part (match_dup 5))
13339         (match_dup 2))]
13340 {
13341   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13342   operands[5] = gen_lowpart (QImode, operands[3]);
13343   ix86_expand_clear (operands[3]);
13344 })
13345
13346 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13347
13348 (define_peephole2
13349   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13350    (set (match_operand:QI 1 "register_operand" "")
13351         (match_operator:QI 2 "ix86_comparison_operator"
13352           [(reg FLAGS_REG) (const_int 0)]))
13353    (parallel [(set (match_operand 3 "q_regs_operand" "")
13354                    (zero_extend (match_dup 1)))
13355               (clobber (reg:CC FLAGS_REG))])]
13356   "(peep2_reg_dead_p (3, operands[1])
13357     || operands_match_p (operands[1], operands[3]))
13358    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13359   [(set (match_dup 4) (match_dup 0))
13360    (set (strict_low_part (match_dup 5))
13361         (match_dup 2))]
13362 {
13363   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13364   operands[5] = gen_lowpart (QImode, operands[3]);
13365   ix86_expand_clear (operands[3]);
13366 })
13367 \f
13368 ;; Call instructions.
13369
13370 ;; The predicates normally associated with named expanders are not properly
13371 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13372 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13373
13374 ;; Call subroutine returning no value.
13375
13376 (define_expand "call_pop"
13377   [(parallel [(call (match_operand:QI 0 "" "")
13378                     (match_operand:SI 1 "" ""))
13379               (set (reg:SI SP_REG)
13380                    (plus:SI (reg:SI SP_REG)
13381                             (match_operand:SI 3 "" "")))])]
13382   "!TARGET_64BIT"
13383 {
13384   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13385   DONE;
13386 })
13387
13388 (define_insn "*call_pop_0"
13389   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13390          (match_operand:SI 1 "" ""))
13391    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13392                             (match_operand:SI 2 "immediate_operand" "")))]
13393   "!TARGET_64BIT"
13394 {
13395   if (SIBLING_CALL_P (insn))
13396     return "jmp\t%P0";
13397   else
13398     return "call\t%P0";
13399 }
13400   [(set_attr "type" "call")])
13401   
13402 (define_insn "*call_pop_1"
13403   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13404          (match_operand:SI 1 "" ""))
13405    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13406                             (match_operand:SI 2 "immediate_operand" "i")))]
13407   "!TARGET_64BIT"
13408 {
13409   if (constant_call_address_operand (operands[0], Pmode))
13410     {
13411       if (SIBLING_CALL_P (insn))
13412         return "jmp\t%P0";
13413       else
13414         return "call\t%P0";
13415     }
13416   if (SIBLING_CALL_P (insn))
13417     return "jmp\t%A0";
13418   else
13419     return "call\t%A0";
13420 }
13421   [(set_attr "type" "call")])
13422
13423 (define_expand "call"
13424   [(call (match_operand:QI 0 "" "")
13425          (match_operand 1 "" ""))
13426    (use (match_operand 2 "" ""))]
13427   ""
13428 {
13429   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13430   DONE;
13431 })
13432
13433 (define_expand "sibcall"
13434   [(call (match_operand:QI 0 "" "")
13435          (match_operand 1 "" ""))
13436    (use (match_operand 2 "" ""))]
13437   ""
13438 {
13439   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13440   DONE;
13441 })
13442
13443 (define_insn "*call_0"
13444   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13445          (match_operand 1 "" ""))]
13446   ""
13447 {
13448   if (SIBLING_CALL_P (insn))
13449     return "jmp\t%P0";
13450   else
13451     return "call\t%P0";
13452 }
13453   [(set_attr "type" "call")])
13454
13455 (define_insn "*call_1"
13456   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13457          (match_operand 1 "" ""))]
13458   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13459 {
13460   if (constant_call_address_operand (operands[0], Pmode))
13461     return "call\t%P0";
13462   return "call\t%A0";
13463 }
13464   [(set_attr "type" "call")])
13465
13466 (define_insn "*sibcall_1"
13467   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13468          (match_operand 1 "" ""))]
13469   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13470 {
13471   if (constant_call_address_operand (operands[0], Pmode))
13472     return "jmp\t%P0";
13473   return "jmp\t%A0";
13474 }
13475   [(set_attr "type" "call")])
13476
13477 (define_insn "*call_1_rex64"
13478   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13479          (match_operand 1 "" ""))]
13480   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13481 {
13482   if (constant_call_address_operand (operands[0], Pmode))
13483     return "call\t%P0";
13484   return "call\t%A0";
13485 }
13486   [(set_attr "type" "call")])
13487
13488 (define_insn "*sibcall_1_rex64"
13489   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13490          (match_operand 1 "" ""))]
13491   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13492   "jmp\t%P0"
13493   [(set_attr "type" "call")])
13494
13495 (define_insn "*sibcall_1_rex64_v"
13496   [(call (mem:QI (reg:DI 40))
13497          (match_operand 0 "" ""))]
13498   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13499   "jmp\t*%%r11"
13500   [(set_attr "type" "call")])
13501
13502
13503 ;; Call subroutine, returning value in operand 0
13504
13505 (define_expand "call_value_pop"
13506   [(parallel [(set (match_operand 0 "" "")
13507                    (call (match_operand:QI 1 "" "")
13508                          (match_operand:SI 2 "" "")))
13509               (set (reg:SI SP_REG)
13510                    (plus:SI (reg:SI SP_REG)
13511                             (match_operand:SI 4 "" "")))])]
13512   "!TARGET_64BIT"
13513 {
13514   ix86_expand_call (operands[0], operands[1], operands[2],
13515                     operands[3], operands[4], 0);
13516   DONE;
13517 })
13518
13519 (define_expand "call_value"
13520   [(set (match_operand 0 "" "")
13521         (call (match_operand:QI 1 "" "")
13522               (match_operand:SI 2 "" "")))
13523    (use (match_operand:SI 3 "" ""))]
13524   ;; Operand 2 not used on the i386.
13525   ""
13526 {
13527   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13528   DONE;
13529 })
13530
13531 (define_expand "sibcall_value"
13532   [(set (match_operand 0 "" "")
13533         (call (match_operand:QI 1 "" "")
13534               (match_operand:SI 2 "" "")))
13535    (use (match_operand:SI 3 "" ""))]
13536   ;; Operand 2 not used on the i386.
13537   ""
13538 {
13539   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13540   DONE;
13541 })
13542
13543 ;; Call subroutine returning any type.
13544
13545 (define_expand "untyped_call"
13546   [(parallel [(call (match_operand 0 "" "")
13547                     (const_int 0))
13548               (match_operand 1 "" "")
13549               (match_operand 2 "" "")])]
13550   ""
13551 {
13552   int i;
13553
13554   /* In order to give reg-stack an easier job in validating two
13555      coprocessor registers as containing a possible return value,
13556      simply pretend the untyped call returns a complex long double
13557      value.  */
13558
13559   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13560                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13561                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13562                     NULL, 0);
13563
13564   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13565     {
13566       rtx set = XVECEXP (operands[2], 0, i);
13567       emit_move_insn (SET_DEST (set), SET_SRC (set));
13568     }
13569
13570   /* The optimizer does not know that the call sets the function value
13571      registers we stored in the result block.  We avoid problems by
13572      claiming that all hard registers are used and clobbered at this
13573      point.  */
13574   emit_insn (gen_blockage (const0_rtx));
13575
13576   DONE;
13577 })
13578 \f
13579 ;; Prologue and epilogue instructions
13580
13581 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13582 ;; all of memory.  This blocks insns from being moved across this point.
13583
13584 (define_insn "blockage"
13585   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13586   ""
13587   ""
13588   [(set_attr "length" "0")])
13589
13590 ;; Insn emitted into the body of a function to return from a function.
13591 ;; This is only done if the function's epilogue is known to be simple.
13592 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13593
13594 (define_expand "return"
13595   [(return)]
13596   "ix86_can_use_return_insn_p ()"
13597 {
13598   if (current_function_pops_args)
13599     {
13600       rtx popc = GEN_INT (current_function_pops_args);
13601       emit_jump_insn (gen_return_pop_internal (popc));
13602       DONE;
13603     }
13604 })
13605
13606 (define_insn "return_internal"
13607   [(return)]
13608   "reload_completed"
13609   "ret"
13610   [(set_attr "length" "1")
13611    (set_attr "length_immediate" "0")
13612    (set_attr "modrm" "0")])
13613
13614 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13615 ;; instruction Athlon and K8 have.
13616
13617 (define_insn "return_internal_long"
13618   [(return)
13619    (unspec [(const_int 0)] UNSPEC_REP)]
13620   "reload_completed"
13621   "rep {;} ret"
13622   [(set_attr "length" "1")
13623    (set_attr "length_immediate" "0")
13624    (set_attr "prefix_rep" "1")
13625    (set_attr "modrm" "0")])
13626
13627 (define_insn "return_pop_internal"
13628   [(return)
13629    (use (match_operand:SI 0 "const_int_operand" ""))]
13630   "reload_completed"
13631   "ret\t%0"
13632   [(set_attr "length" "3")
13633    (set_attr "length_immediate" "2")
13634    (set_attr "modrm" "0")])
13635
13636 (define_insn "return_indirect_internal"
13637   [(return)
13638    (use (match_operand:SI 0 "register_operand" "r"))]
13639   "reload_completed"
13640   "jmp\t%A0"
13641   [(set_attr "type" "ibr")
13642    (set_attr "length_immediate" "0")])
13643
13644 (define_insn "nop"
13645   [(const_int 0)]
13646   ""
13647   "nop"
13648   [(set_attr "length" "1")
13649    (set_attr "length_immediate" "0")
13650    (set_attr "modrm" "0")])
13651
13652 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13653 ;; branch prediction penalty for the third jump in a 16-byte
13654 ;; block on K8.
13655
13656 (define_insn "align"
13657   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13658   ""
13659 {
13660 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13661   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13662 #else
13663   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13664      The align insn is used to avoid 3 jump instructions in the row to improve
13665      branch prediction and the benefits hardly outweight the cost of extra 8
13666      nops on the average inserted by full alignment pseudo operation.  */
13667 #endif
13668   return "";
13669 }
13670   [(set_attr "length" "16")])
13671
13672 (define_expand "prologue"
13673   [(const_int 1)]
13674   ""
13675   "ix86_expand_prologue (); DONE;")
13676
13677 (define_insn "set_got"
13678   [(set (match_operand:SI 0 "register_operand" "=r")
13679         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13680    (clobber (reg:CC FLAGS_REG))]
13681   "!TARGET_64BIT"
13682   { return output_set_got (operands[0]); }
13683   [(set_attr "type" "multi")
13684    (set_attr "length" "12")])
13685
13686 (define_expand "epilogue"
13687   [(const_int 1)]
13688   ""
13689   "ix86_expand_epilogue (1); DONE;")
13690
13691 (define_expand "sibcall_epilogue"
13692   [(const_int 1)]
13693   ""
13694   "ix86_expand_epilogue (0); DONE;")
13695
13696 (define_expand "eh_return"
13697   [(use (match_operand 0 "register_operand" ""))]
13698   ""
13699 {
13700   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13701
13702   /* Tricky bit: we write the address of the handler to which we will
13703      be returning into someone else's stack frame, one word below the
13704      stack address we wish to restore.  */
13705   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13706   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13707   tmp = gen_rtx_MEM (Pmode, tmp);
13708   emit_move_insn (tmp, ra);
13709
13710   if (Pmode == SImode)
13711     emit_jump_insn (gen_eh_return_si (sa));
13712   else
13713     emit_jump_insn (gen_eh_return_di (sa));
13714   emit_barrier ();
13715   DONE;
13716 })
13717
13718 (define_insn_and_split "eh_return_si"
13719   [(set (pc) 
13720         (unspec [(match_operand:SI 0 "register_operand" "c")]
13721                  UNSPEC_EH_RETURN))]
13722   "!TARGET_64BIT"
13723   "#"
13724   "reload_completed"
13725   [(const_int 1)]
13726   "ix86_expand_epilogue (2); DONE;")
13727
13728 (define_insn_and_split "eh_return_di"
13729   [(set (pc) 
13730         (unspec [(match_operand:DI 0 "register_operand" "c")]
13731                  UNSPEC_EH_RETURN))]
13732   "TARGET_64BIT"
13733   "#"
13734   "reload_completed"
13735   [(const_int 1)]
13736   "ix86_expand_epilogue (2); DONE;")
13737
13738 (define_insn "leave"
13739   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13740    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13741    (clobber (mem:BLK (scratch)))]
13742   "!TARGET_64BIT"
13743   "leave"
13744   [(set_attr "type" "leave")])
13745
13746 (define_insn "leave_rex64"
13747   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13748    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13749    (clobber (mem:BLK (scratch)))]
13750   "TARGET_64BIT"
13751   "leave"
13752   [(set_attr "type" "leave")])
13753 \f
13754 (define_expand "ffssi2"
13755   [(parallel
13756      [(set (match_operand:SI 0 "register_operand" "") 
13757            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13758       (clobber (match_scratch:SI 2 ""))
13759       (clobber (reg:CC FLAGS_REG))])]
13760   ""
13761   "")
13762
13763 (define_insn_and_split "*ffs_cmove"
13764   [(set (match_operand:SI 0 "register_operand" "=r") 
13765         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13766    (clobber (match_scratch:SI 2 "=&r"))
13767    (clobber (reg:CC FLAGS_REG))]
13768   "TARGET_CMOVE"
13769   "#"
13770   "&& reload_completed"
13771   [(set (match_dup 2) (const_int -1))
13772    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13773               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13774    (set (match_dup 0) (if_then_else:SI
13775                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13776                         (match_dup 2)
13777                         (match_dup 0)))
13778    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13779               (clobber (reg:CC FLAGS_REG))])]
13780   "")
13781
13782 (define_insn_and_split "*ffs_no_cmove"
13783   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13784         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13785    (clobber (match_scratch:SI 2 "=&q"))
13786    (clobber (reg:CC FLAGS_REG))]
13787   ""
13788   "#"
13789   "reload_completed"
13790   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13791               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13792    (set (strict_low_part (match_dup 3))
13793         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13794    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13795               (clobber (reg:CC FLAGS_REG))])
13796    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13797               (clobber (reg:CC FLAGS_REG))])
13798    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13799               (clobber (reg:CC FLAGS_REG))])]
13800 {
13801   operands[3] = gen_lowpart (QImode, operands[2]);
13802   ix86_expand_clear (operands[2]);
13803 })
13804
13805 (define_insn "*ffssi_1"
13806   [(set (reg:CCZ FLAGS_REG)
13807         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13808                      (const_int 0)))
13809    (set (match_operand:SI 0 "register_operand" "=r")
13810         (ctz:SI (match_dup 1)))]
13811   ""
13812   "bsf{l}\t{%1, %0|%0, %1}"
13813   [(set_attr "prefix_0f" "1")])
13814
13815 (define_expand "ffsdi2"
13816   [(parallel
13817      [(set (match_operand:DI 0 "register_operand" "") 
13818            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13819       (clobber (match_scratch:DI 2 ""))
13820       (clobber (reg:CC FLAGS_REG))])]
13821   "TARGET_64BIT && TARGET_CMOVE"
13822   "")
13823
13824 (define_insn_and_split "*ffs_rex64"
13825   [(set (match_operand:DI 0 "register_operand" "=r") 
13826         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13827    (clobber (match_scratch:DI 2 "=&r"))
13828    (clobber (reg:CC FLAGS_REG))]
13829   "TARGET_64BIT && TARGET_CMOVE"
13830   "#"
13831   "&& reload_completed"
13832   [(set (match_dup 2) (const_int -1))
13833    (parallel [(set (reg:CCZ FLAGS_REG)
13834                    (compare:CCZ (match_dup 1) (const_int 0)))
13835               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13836    (set (match_dup 0) (if_then_else:DI
13837                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13838                         (match_dup 2)
13839                         (match_dup 0)))
13840    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13841               (clobber (reg:CC FLAGS_REG))])]
13842   "")
13843
13844 (define_insn "*ffsdi_1"
13845   [(set (reg:CCZ FLAGS_REG)
13846         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13847                      (const_int 0)))
13848    (set (match_operand:DI 0 "register_operand" "=r")
13849         (ctz:DI (match_dup 1)))]
13850   "TARGET_64BIT"
13851   "bsf{q}\t{%1, %0|%0, %1}"
13852   [(set_attr "prefix_0f" "1")])
13853
13854 (define_insn "ctzsi2"
13855   [(set (match_operand:SI 0 "register_operand" "=r")
13856         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13857    (clobber (reg:CC FLAGS_REG))]
13858   ""
13859   "bsf{l}\t{%1, %0|%0, %1}"
13860   [(set_attr "prefix_0f" "1")])
13861
13862 (define_insn "ctzdi2"
13863   [(set (match_operand:DI 0 "register_operand" "=r")
13864         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13865    (clobber (reg:CC FLAGS_REG))]
13866   "TARGET_64BIT"
13867   "bsf{q}\t{%1, %0|%0, %1}"
13868   [(set_attr "prefix_0f" "1")])
13869
13870 (define_expand "clzsi2"
13871   [(parallel
13872      [(set (match_operand:SI 0 "register_operand" "")
13873            (minus:SI (const_int 31)
13874                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13875       (clobber (reg:CC FLAGS_REG))])
13876    (parallel
13877      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13878       (clobber (reg:CC FLAGS_REG))])]
13879   ""
13880   "")
13881
13882 (define_insn "*bsr"
13883   [(set (match_operand:SI 0 "register_operand" "=r")
13884         (minus:SI (const_int 31)
13885                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13886    (clobber (reg:CC FLAGS_REG))]
13887   ""
13888   "bsr{l}\t{%1, %0|%0, %1}"
13889   [(set_attr "prefix_0f" "1")])
13890
13891 (define_expand "clzdi2"
13892   [(parallel
13893      [(set (match_operand:DI 0 "register_operand" "")
13894            (minus:DI (const_int 63)
13895                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13896       (clobber (reg:CC FLAGS_REG))])
13897    (parallel
13898      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13899       (clobber (reg:CC FLAGS_REG))])]
13900   "TARGET_64BIT"
13901   "")
13902
13903 (define_insn "*bsr_rex64"
13904   [(set (match_operand:DI 0 "register_operand" "=r")
13905         (minus:DI (const_int 63)
13906                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13907    (clobber (reg:CC FLAGS_REG))]
13908   "TARGET_64BIT"
13909   "bsr{q}\t{%1, %0|%0, %1}"
13910   [(set_attr "prefix_0f" "1")])
13911 \f
13912 ;; Thread-local storage patterns for ELF.
13913 ;;
13914 ;; Note that these code sequences must appear exactly as shown
13915 ;; in order to allow linker relaxation.
13916
13917 (define_insn "*tls_global_dynamic_32_gnu"
13918   [(set (match_operand:SI 0 "register_operand" "=a")
13919         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13920                     (match_operand:SI 2 "tls_symbolic_operand" "")
13921                     (match_operand:SI 3 "call_insn_operand" "")]
13922                     UNSPEC_TLS_GD))
13923    (clobber (match_scratch:SI 4 "=d"))
13924    (clobber (match_scratch:SI 5 "=c"))
13925    (clobber (reg:CC FLAGS_REG))]
13926   "!TARGET_64BIT && TARGET_GNU_TLS"
13927   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13928   [(set_attr "type" "multi")
13929    (set_attr "length" "12")])
13930
13931 (define_insn "*tls_global_dynamic_32_sun"
13932   [(set (match_operand:SI 0 "register_operand" "=a")
13933         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13934                     (match_operand:SI 2 "tls_symbolic_operand" "")
13935                     (match_operand:SI 3 "call_insn_operand" "")]
13936                     UNSPEC_TLS_GD))
13937    (clobber (match_scratch:SI 4 "=d"))
13938    (clobber (match_scratch:SI 5 "=c"))
13939    (clobber (reg:CC FLAGS_REG))]
13940   "!TARGET_64BIT && TARGET_SUN_TLS"
13941   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13942         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13943   [(set_attr "type" "multi")
13944    (set_attr "length" "14")])
13945
13946 (define_expand "tls_global_dynamic_32"
13947   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13948                    (unspec:SI
13949                     [(match_dup 2)
13950                      (match_operand:SI 1 "tls_symbolic_operand" "")
13951                      (match_dup 3)]
13952                     UNSPEC_TLS_GD))
13953               (clobber (match_scratch:SI 4 ""))
13954               (clobber (match_scratch:SI 5 ""))
13955               (clobber (reg:CC FLAGS_REG))])]
13956   ""
13957 {
13958   if (flag_pic)
13959     operands[2] = pic_offset_table_rtx;
13960   else
13961     {
13962       operands[2] = gen_reg_rtx (Pmode);
13963       emit_insn (gen_set_got (operands[2]));
13964     }
13965   operands[3] = ix86_tls_get_addr ();
13966 })
13967
13968 (define_insn "*tls_global_dynamic_64"
13969   [(set (match_operand:DI 0 "register_operand" "=a")
13970         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13971                       (match_operand:DI 3 "" "")))
13972    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13973               UNSPEC_TLS_GD)]
13974   "TARGET_64BIT"
13975   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13976   [(set_attr "type" "multi")
13977    (set_attr "length" "16")])
13978
13979 (define_expand "tls_global_dynamic_64"
13980   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13981                    (call (mem:QI (match_dup 2)) (const_int 0)))
13982               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13983                          UNSPEC_TLS_GD)])]
13984   ""
13985 {
13986   operands[2] = ix86_tls_get_addr ();
13987 })
13988
13989 (define_insn "*tls_local_dynamic_base_32_gnu"
13990   [(set (match_operand:SI 0 "register_operand" "=a")
13991         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13992                     (match_operand:SI 2 "call_insn_operand" "")]
13993                    UNSPEC_TLS_LD_BASE))
13994    (clobber (match_scratch:SI 3 "=d"))
13995    (clobber (match_scratch:SI 4 "=c"))
13996    (clobber (reg:CC FLAGS_REG))]
13997   "!TARGET_64BIT && TARGET_GNU_TLS"
13998   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13999   [(set_attr "type" "multi")
14000    (set_attr "length" "11")])
14001
14002 (define_insn "*tls_local_dynamic_base_32_sun"
14003   [(set (match_operand:SI 0 "register_operand" "=a")
14004         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14005                     (match_operand:SI 2 "call_insn_operand" "")]
14006                    UNSPEC_TLS_LD_BASE))
14007    (clobber (match_scratch:SI 3 "=d"))
14008    (clobber (match_scratch:SI 4 "=c"))
14009    (clobber (reg:CC FLAGS_REG))]
14010   "!TARGET_64BIT && TARGET_SUN_TLS"
14011   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14012         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14013   [(set_attr "type" "multi")
14014    (set_attr "length" "13")])
14015
14016 (define_expand "tls_local_dynamic_base_32"
14017   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14018                    (unspec:SI [(match_dup 1) (match_dup 2)]
14019                               UNSPEC_TLS_LD_BASE))
14020               (clobber (match_scratch:SI 3 ""))
14021               (clobber (match_scratch:SI 4 ""))
14022               (clobber (reg:CC FLAGS_REG))])]
14023   ""
14024 {
14025   if (flag_pic)
14026     operands[1] = pic_offset_table_rtx;
14027   else
14028     {
14029       operands[1] = gen_reg_rtx (Pmode);
14030       emit_insn (gen_set_got (operands[1]));
14031     }
14032   operands[2] = ix86_tls_get_addr ();
14033 })
14034
14035 (define_insn "*tls_local_dynamic_base_64"
14036   [(set (match_operand:DI 0 "register_operand" "=a")
14037         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14038                       (match_operand:DI 2 "" "")))
14039    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14040   "TARGET_64BIT"
14041   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14042   [(set_attr "type" "multi")
14043    (set_attr "length" "12")])
14044
14045 (define_expand "tls_local_dynamic_base_64"
14046   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14047                    (call (mem:QI (match_dup 1)) (const_int 0)))
14048               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14049   ""
14050 {
14051   operands[1] = ix86_tls_get_addr ();
14052 })
14053
14054 ;; Local dynamic of a single variable is a lose.  Show combine how
14055 ;; to convert that back to global dynamic.
14056
14057 (define_insn_and_split "*tls_local_dynamic_32_once"
14058   [(set (match_operand:SI 0 "register_operand" "=a")
14059         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14060                              (match_operand:SI 2 "call_insn_operand" "")]
14061                             UNSPEC_TLS_LD_BASE)
14062                  (const:SI (unspec:SI
14063                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14064                             UNSPEC_DTPOFF))))
14065    (clobber (match_scratch:SI 4 "=d"))
14066    (clobber (match_scratch:SI 5 "=c"))
14067    (clobber (reg:CC FLAGS_REG))]
14068   ""
14069   "#"
14070   ""
14071   [(parallel [(set (match_dup 0)
14072                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14073                               UNSPEC_TLS_GD))
14074               (clobber (match_dup 4))
14075               (clobber (match_dup 5))
14076               (clobber (reg:CC FLAGS_REG))])]
14077   "")
14078
14079 ;; Load and add the thread base pointer from %gs:0.
14080
14081 (define_insn "*load_tp_si"
14082   [(set (match_operand:SI 0 "register_operand" "=r")
14083         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14084   "!TARGET_64BIT"
14085   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14086   [(set_attr "type" "imov")
14087    (set_attr "modrm" "0")
14088    (set_attr "length" "7")
14089    (set_attr "memory" "load")
14090    (set_attr "imm_disp" "false")])
14091
14092 (define_insn "*add_tp_si"
14093   [(set (match_operand:SI 0 "register_operand" "=r")
14094         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14095                  (match_operand:SI 1 "register_operand" "0")))
14096    (clobber (reg:CC FLAGS_REG))]
14097   "!TARGET_64BIT"
14098   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14099   [(set_attr "type" "alu")
14100    (set_attr "modrm" "0")
14101    (set_attr "length" "7")
14102    (set_attr "memory" "load")
14103    (set_attr "imm_disp" "false")])
14104
14105 (define_insn "*load_tp_di"
14106   [(set (match_operand:DI 0 "register_operand" "=r")
14107         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14108   "TARGET_64BIT"
14109   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14110   [(set_attr "type" "imov")
14111    (set_attr "modrm" "0")
14112    (set_attr "length" "7")
14113    (set_attr "memory" "load")
14114    (set_attr "imm_disp" "false")])
14115
14116 (define_insn "*add_tp_di"
14117   [(set (match_operand:DI 0 "register_operand" "=r")
14118         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14119                  (match_operand:DI 1 "register_operand" "0")))
14120    (clobber (reg:CC FLAGS_REG))]
14121   "TARGET_64BIT"
14122   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14123   [(set_attr "type" "alu")
14124    (set_attr "modrm" "0")
14125    (set_attr "length" "7")
14126    (set_attr "memory" "load")
14127    (set_attr "imm_disp" "false")])
14128 \f
14129 ;; These patterns match the binary 387 instructions for addM3, subM3,
14130 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14131 ;; SFmode.  The first is the normal insn, the second the same insn but
14132 ;; with one operand a conversion, and the third the same insn but with
14133 ;; the other operand a conversion.  The conversion may be SFmode or
14134 ;; SImode if the target mode DFmode, but only SImode if the target mode
14135 ;; is SFmode.
14136
14137 ;; Gcc is slightly more smart about handling normal two address instructions
14138 ;; so use special patterns for add and mull.
14139 (define_insn "*fop_sf_comm_nosse"
14140   [(set (match_operand:SF 0 "register_operand" "=f")
14141         (match_operator:SF 3 "binary_fp_operator"
14142                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14143                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14144   "TARGET_80387 && !TARGET_SSE_MATH
14145    && COMMUTATIVE_ARITH_P (operands[3])
14146    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14147   "* return output_387_binary_op (insn, operands);"
14148   [(set (attr "type") 
14149         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14150            (const_string "fmul")
14151            (const_string "fop")))
14152    (set_attr "mode" "SF")])
14153
14154 (define_insn "*fop_sf_comm"
14155   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14156         (match_operator:SF 3 "binary_fp_operator"
14157                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14158                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14159   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14160    && COMMUTATIVE_ARITH_P (operands[3])
14161    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14162   "* return output_387_binary_op (insn, operands);"
14163   [(set (attr "type") 
14164         (if_then_else (eq_attr "alternative" "1")
14165            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14166               (const_string "ssemul")
14167               (const_string "sseadd"))
14168            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14169               (const_string "fmul")
14170               (const_string "fop"))))
14171    (set_attr "mode" "SF")])
14172
14173 (define_insn "*fop_sf_comm_sse"
14174   [(set (match_operand:SF 0 "register_operand" "=x")
14175         (match_operator:SF 3 "binary_fp_operator"
14176                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14177                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14178   "TARGET_SSE_MATH && COMMUTATIVE_ARITH_P (operands[3])
14179    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14180   "* return output_387_binary_op (insn, operands);"
14181   [(set (attr "type") 
14182         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14183            (const_string "ssemul")
14184            (const_string "sseadd")))
14185    (set_attr "mode" "SF")])
14186
14187 (define_insn "*fop_df_comm_nosse"
14188   [(set (match_operand:DF 0 "register_operand" "=f")
14189         (match_operator:DF 3 "binary_fp_operator"
14190                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14191                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14192   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14193    && COMMUTATIVE_ARITH_P (operands[3])
14194    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14195   "* return output_387_binary_op (insn, operands);"
14196   [(set (attr "type") 
14197         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14198            (const_string "fmul")
14199            (const_string "fop")))
14200    (set_attr "mode" "DF")])
14201
14202 (define_insn "*fop_df_comm"
14203   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14204         (match_operator:DF 3 "binary_fp_operator"
14205                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14206                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14207   "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14208    && COMMUTATIVE_ARITH_P (operands[3])
14209    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14210   "* return output_387_binary_op (insn, operands);"
14211   [(set (attr "type") 
14212         (if_then_else (eq_attr "alternative" "1")
14213            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14214               (const_string "ssemul")
14215               (const_string "sseadd"))
14216            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14217               (const_string "fmul")
14218               (const_string "fop"))))
14219    (set_attr "mode" "DF")])
14220
14221 (define_insn "*fop_df_comm_sse"
14222   [(set (match_operand:DF 0 "register_operand" "=Y")
14223         (match_operator:DF 3 "binary_fp_operator"
14224                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14225                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14226   "TARGET_SSE2 && TARGET_SSE_MATH
14227    && COMMUTATIVE_ARITH_P (operands[3])
14228    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14229   "* return output_387_binary_op (insn, operands);"
14230   [(set (attr "type") 
14231         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14232            (const_string "ssemul")
14233            (const_string "sseadd")))
14234    (set_attr "mode" "DF")])
14235
14236 (define_insn "*fop_xf_comm"
14237   [(set (match_operand:XF 0 "register_operand" "=f")
14238         (match_operator:XF 3 "binary_fp_operator"
14239                         [(match_operand:XF 1 "register_operand" "%0")
14240                          (match_operand:XF 2 "register_operand" "f")]))]
14241   "TARGET_80387
14242    && COMMUTATIVE_ARITH_P (operands[3])"
14243   "* return output_387_binary_op (insn, operands);"
14244   [(set (attr "type") 
14245         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14246            (const_string "fmul")
14247            (const_string "fop")))
14248    (set_attr "mode" "XF")])
14249
14250 (define_insn "*fop_sf_1_nosse"
14251   [(set (match_operand:SF 0 "register_operand" "=f,f")
14252         (match_operator:SF 3 "binary_fp_operator"
14253                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14254                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14255   "TARGET_80387 && !TARGET_SSE_MATH
14256    && !COMMUTATIVE_ARITH_P (operands[3])
14257    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14258   "* return output_387_binary_op (insn, operands);"
14259   [(set (attr "type") 
14260         (cond [(match_operand:SF 3 "mult_operator" "") 
14261                  (const_string "fmul")
14262                (match_operand:SF 3 "div_operator" "") 
14263                  (const_string "fdiv")
14264               ]
14265               (const_string "fop")))
14266    (set_attr "mode" "SF")])
14267
14268 (define_insn "*fop_sf_1"
14269   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14270         (match_operator:SF 3 "binary_fp_operator"
14271                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14272                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14273   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14274    && !COMMUTATIVE_ARITH_P (operands[3])
14275    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14276   "* return output_387_binary_op (insn, operands);"
14277   [(set (attr "type") 
14278         (cond [(and (eq_attr "alternative" "2")
14279                     (match_operand:SF 3 "mult_operator" ""))
14280                  (const_string "ssemul")
14281                (and (eq_attr "alternative" "2")
14282                     (match_operand:SF 3 "div_operator" ""))
14283                  (const_string "ssediv")
14284                (eq_attr "alternative" "2")
14285                  (const_string "sseadd")
14286                (match_operand:SF 3 "mult_operator" "") 
14287                  (const_string "fmul")
14288                (match_operand:SF 3 "div_operator" "") 
14289                  (const_string "fdiv")
14290               ]
14291               (const_string "fop")))
14292    (set_attr "mode" "SF")])
14293
14294 (define_insn "*fop_sf_1_sse"
14295   [(set (match_operand:SF 0 "register_operand" "=x")
14296         (match_operator:SF 3 "binary_fp_operator"
14297                         [(match_operand:SF 1 "register_operand" "0")
14298                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14299   "TARGET_SSE_MATH
14300    && !COMMUTATIVE_ARITH_P (operands[3])"
14301   "* return output_387_binary_op (insn, operands);"
14302   [(set (attr "type") 
14303         (cond [(match_operand:SF 3 "mult_operator" "")
14304                  (const_string "ssemul")
14305                (match_operand:SF 3 "div_operator" "")
14306                  (const_string "ssediv")
14307               ]
14308               (const_string "sseadd")))
14309    (set_attr "mode" "SF")])
14310
14311 ;; ??? Add SSE splitters for these!
14312 (define_insn "*fop_sf_2"
14313   [(set (match_operand:SF 0 "register_operand" "=f,f")
14314         (match_operator:SF 3 "binary_fp_operator"
14315           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14316            (match_operand:SF 2 "register_operand" "0,0")]))]
14317   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14318   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14319   [(set (attr "type") 
14320         (cond [(match_operand:SF 3 "mult_operator" "") 
14321                  (const_string "fmul")
14322                (match_operand:SF 3 "div_operator" "") 
14323                  (const_string "fdiv")
14324               ]
14325               (const_string "fop")))
14326    (set_attr "fp_int_src" "true")
14327    (set_attr "mode" "SI")])
14328
14329 (define_insn "*fop_sf_3"
14330   [(set (match_operand:SF 0 "register_operand" "=f,f")
14331         (match_operator:SF 3 "binary_fp_operator"
14332           [(match_operand:SF 1 "register_operand" "0,0")
14333            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14334   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14335   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14336   [(set (attr "type") 
14337         (cond [(match_operand:SF 3 "mult_operator" "") 
14338                  (const_string "fmul")
14339                (match_operand:SF 3 "div_operator" "") 
14340                  (const_string "fdiv")
14341               ]
14342               (const_string "fop")))
14343    (set_attr "fp_int_src" "true")
14344    (set_attr "mode" "SI")])
14345
14346 (define_insn "*fop_df_1_nosse"
14347   [(set (match_operand:DF 0 "register_operand" "=f,f")
14348         (match_operator:DF 3 "binary_fp_operator"
14349                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14350                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14351   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14352    && !COMMUTATIVE_ARITH_P (operands[3])
14353    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14354   "* return output_387_binary_op (insn, operands);"
14355   [(set (attr "type") 
14356         (cond [(match_operand:DF 3 "mult_operator" "") 
14357                  (const_string "fmul")
14358                (match_operand:DF 3 "div_operator" "")
14359                  (const_string "fdiv")
14360               ]
14361               (const_string "fop")))
14362    (set_attr "mode" "DF")])
14363
14364
14365 (define_insn "*fop_df_1"
14366   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14367         (match_operator:DF 3 "binary_fp_operator"
14368                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14369                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14370   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14371    && !COMMUTATIVE_ARITH_P (operands[3])
14372    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14373   "* return output_387_binary_op (insn, operands);"
14374   [(set (attr "type") 
14375         (cond [(and (eq_attr "alternative" "2")
14376                     (match_operand:SF 3 "mult_operator" ""))
14377                  (const_string "ssemul")
14378                (and (eq_attr "alternative" "2")
14379                     (match_operand:SF 3 "div_operator" ""))
14380                  (const_string "ssediv")
14381                (eq_attr "alternative" "2")
14382                  (const_string "sseadd")
14383                (match_operand:DF 3 "mult_operator" "") 
14384                  (const_string "fmul")
14385                (match_operand:DF 3 "div_operator" "") 
14386                  (const_string "fdiv")
14387               ]
14388               (const_string "fop")))
14389    (set_attr "mode" "DF")])
14390
14391 (define_insn "*fop_df_1_sse"
14392   [(set (match_operand:DF 0 "register_operand" "=Y")
14393         (match_operator:DF 3 "binary_fp_operator"
14394                         [(match_operand:DF 1 "register_operand" "0")
14395                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14396   "TARGET_SSE2 && TARGET_SSE_MATH
14397    && !COMMUTATIVE_ARITH_P (operands[3])"
14398   "* return output_387_binary_op (insn, operands);"
14399   [(set_attr "mode" "DF")
14400    (set (attr "type") 
14401         (cond [(match_operand:SF 3 "mult_operator" "")
14402                  (const_string "ssemul")
14403                (match_operand:SF 3 "div_operator" "")
14404                  (const_string "ssediv")
14405               ]
14406               (const_string "sseadd")))])
14407
14408 ;; ??? Add SSE splitters for these!
14409 (define_insn "*fop_df_2"
14410   [(set (match_operand:DF 0 "register_operand" "=f,f")
14411         (match_operator:DF 3 "binary_fp_operator"
14412            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14413             (match_operand:DF 2 "register_operand" "0,0")]))]
14414   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14415   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14416   [(set (attr "type") 
14417         (cond [(match_operand:DF 3 "mult_operator" "") 
14418                  (const_string "fmul")
14419                (match_operand:DF 3 "div_operator" "") 
14420                  (const_string "fdiv")
14421               ]
14422               (const_string "fop")))
14423    (set_attr "fp_int_src" "true")
14424    (set_attr "mode" "SI")])
14425
14426 (define_insn "*fop_df_3"
14427   [(set (match_operand:DF 0 "register_operand" "=f,f")
14428         (match_operator:DF 3 "binary_fp_operator"
14429            [(match_operand:DF 1 "register_operand" "0,0")
14430             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14431   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14432   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14433   [(set (attr "type") 
14434         (cond [(match_operand:DF 3 "mult_operator" "") 
14435                  (const_string "fmul")
14436                (match_operand:DF 3 "div_operator" "") 
14437                  (const_string "fdiv")
14438               ]
14439               (const_string "fop")))
14440    (set_attr "fp_int_src" "true")
14441    (set_attr "mode" "SI")])
14442
14443 (define_insn "*fop_df_4"
14444   [(set (match_operand:DF 0 "register_operand" "=f,f")
14445         (match_operator:DF 3 "binary_fp_operator"
14446            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14447             (match_operand:DF 2 "register_operand" "0,f")]))]
14448   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14449    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14450   "* return output_387_binary_op (insn, operands);"
14451   [(set (attr "type") 
14452         (cond [(match_operand:DF 3 "mult_operator" "") 
14453                  (const_string "fmul")
14454                (match_operand:DF 3 "div_operator" "") 
14455                  (const_string "fdiv")
14456               ]
14457               (const_string "fop")))
14458    (set_attr "mode" "SF")])
14459
14460 (define_insn "*fop_df_5"
14461   [(set (match_operand:DF 0 "register_operand" "=f,f")
14462         (match_operator:DF 3 "binary_fp_operator"
14463           [(match_operand:DF 1 "register_operand" "0,f")
14464            (float_extend:DF
14465             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14466   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14467   "* return output_387_binary_op (insn, operands);"
14468   [(set (attr "type") 
14469         (cond [(match_operand:DF 3 "mult_operator" "") 
14470                  (const_string "fmul")
14471                (match_operand:DF 3 "div_operator" "") 
14472                  (const_string "fdiv")
14473               ]
14474               (const_string "fop")))
14475    (set_attr "mode" "SF")])
14476
14477 (define_insn "*fop_df_6"
14478   [(set (match_operand:DF 0 "register_operand" "=f,f")
14479         (match_operator:DF 3 "binary_fp_operator"
14480           [(float_extend:DF
14481             (match_operand:SF 1 "register_operand" "0,f"))
14482            (float_extend:DF
14483             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14484   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14485   "* return output_387_binary_op (insn, operands);"
14486   [(set (attr "type") 
14487         (cond [(match_operand:DF 3 "mult_operator" "") 
14488                  (const_string "fmul")
14489                (match_operand:DF 3 "div_operator" "") 
14490                  (const_string "fdiv")
14491               ]
14492               (const_string "fop")))
14493    (set_attr "mode" "SF")])
14494
14495 (define_insn "*fop_xf_1"
14496   [(set (match_operand:XF 0 "register_operand" "=f,f")
14497         (match_operator:XF 3 "binary_fp_operator"
14498                         [(match_operand:XF 1 "register_operand" "0,f")
14499                          (match_operand:XF 2 "register_operand" "f,0")]))]
14500   "TARGET_80387
14501    && !COMMUTATIVE_ARITH_P (operands[3])"
14502   "* return output_387_binary_op (insn, operands);"
14503   [(set (attr "type") 
14504         (cond [(match_operand:XF 3 "mult_operator" "") 
14505                  (const_string "fmul")
14506                (match_operand:XF 3 "div_operator" "") 
14507                  (const_string "fdiv")
14508               ]
14509               (const_string "fop")))
14510    (set_attr "mode" "XF")])
14511
14512 (define_insn "*fop_xf_2"
14513   [(set (match_operand:XF 0 "register_operand" "=f,f")
14514         (match_operator:XF 3 "binary_fp_operator"
14515            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14516             (match_operand:XF 2 "register_operand" "0,0")]))]
14517   "TARGET_80387 && TARGET_USE_FIOP"
14518   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14519   [(set (attr "type") 
14520         (cond [(match_operand:XF 3 "mult_operator" "") 
14521                  (const_string "fmul")
14522                (match_operand:XF 3 "div_operator" "") 
14523                  (const_string "fdiv")
14524               ]
14525               (const_string "fop")))
14526    (set_attr "fp_int_src" "true")
14527    (set_attr "mode" "SI")])
14528
14529 (define_insn "*fop_xf_3"
14530   [(set (match_operand:XF 0 "register_operand" "=f,f")
14531         (match_operator:XF 3 "binary_fp_operator"
14532           [(match_operand:XF 1 "register_operand" "0,0")
14533            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14534   "TARGET_80387 && TARGET_USE_FIOP"
14535   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14536   [(set (attr "type") 
14537         (cond [(match_operand:XF 3 "mult_operator" "") 
14538                  (const_string "fmul")
14539                (match_operand:XF 3 "div_operator" "") 
14540                  (const_string "fdiv")
14541               ]
14542               (const_string "fop")))
14543    (set_attr "fp_int_src" "true")
14544    (set_attr "mode" "SI")])
14545
14546 (define_insn "*fop_xf_4"
14547   [(set (match_operand:XF 0 "register_operand" "=f,f")
14548         (match_operator:XF 3 "binary_fp_operator"
14549            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14550             (match_operand:XF 2 "register_operand" "0,f")]))]
14551   "TARGET_80387"
14552   "* return output_387_binary_op (insn, operands);"
14553   [(set (attr "type") 
14554         (cond [(match_operand:XF 3 "mult_operator" "") 
14555                  (const_string "fmul")
14556                (match_operand:XF 3 "div_operator" "") 
14557                  (const_string "fdiv")
14558               ]
14559               (const_string "fop")))
14560    (set_attr "mode" "SF")])
14561
14562 (define_insn "*fop_xf_5"
14563   [(set (match_operand:XF 0 "register_operand" "=f,f")
14564         (match_operator:XF 3 "binary_fp_operator"
14565           [(match_operand:XF 1 "register_operand" "0,f")
14566            (float_extend:XF
14567             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14568   "TARGET_80387"
14569   "* return output_387_binary_op (insn, operands);"
14570   [(set (attr "type") 
14571         (cond [(match_operand:XF 3 "mult_operator" "") 
14572                  (const_string "fmul")
14573                (match_operand:XF 3 "div_operator" "") 
14574                  (const_string "fdiv")
14575               ]
14576               (const_string "fop")))
14577    (set_attr "mode" "SF")])
14578
14579 (define_insn "*fop_xf_6"
14580   [(set (match_operand:XF 0 "register_operand" "=f,f")
14581         (match_operator:XF 3 "binary_fp_operator"
14582           [(float_extend:XF
14583             (match_operand 1 "register_operand" "0,f"))
14584            (float_extend:XF
14585             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14586   "TARGET_80387"
14587   "* return output_387_binary_op (insn, operands);"
14588   [(set (attr "type") 
14589         (cond [(match_operand:XF 3 "mult_operator" "") 
14590                  (const_string "fmul")
14591                (match_operand:XF 3 "div_operator" "") 
14592                  (const_string "fdiv")
14593               ]
14594               (const_string "fop")))
14595    (set_attr "mode" "SF")])
14596
14597 (define_split
14598   [(set (match_operand 0 "register_operand" "")
14599         (match_operator 3 "binary_fp_operator"
14600            [(float (match_operand:SI 1 "register_operand" ""))
14601             (match_operand 2 "register_operand" "")]))]
14602   "TARGET_80387 && reload_completed
14603    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14604   [(const_int 0)]
14605
14606   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14607   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14608   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14609                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14610                                           GET_MODE (operands[3]),
14611                                           operands[4],
14612                                           operands[2])));
14613   ix86_free_from_memory (GET_MODE (operands[1]));
14614   DONE;
14615 })
14616
14617 (define_split
14618   [(set (match_operand 0 "register_operand" "")
14619         (match_operator 3 "binary_fp_operator"
14620            [(match_operand 1 "register_operand" "")
14621             (float (match_operand:SI 2 "register_operand" ""))]))]
14622   "TARGET_80387 && reload_completed
14623    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14624   [(const_int 0)]
14625 {
14626   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14627   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14628   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14629                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14630                                           GET_MODE (operands[3]),
14631                                           operands[1],
14632                                           operands[4])));
14633   ix86_free_from_memory (GET_MODE (operands[2]));
14634   DONE;
14635 })
14636 \f
14637 ;; FPU special functions.
14638
14639 (define_expand "sqrtsf2"
14640   [(set (match_operand:SF 0 "register_operand" "")
14641         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14642   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14643 {
14644   if (!TARGET_SSE_MATH)
14645     operands[1] = force_reg (SFmode, operands[1]);
14646 })
14647
14648 (define_insn "sqrtsf2_1"
14649   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14650         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14651   "TARGET_USE_FANCY_MATH_387
14652    && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14653   "@
14654    fsqrt
14655    sqrtss\t{%1, %0|%0, %1}"
14656   [(set_attr "type" "fpspc,sse")
14657    (set_attr "mode" "SF,SF")
14658    (set_attr "athlon_decode" "direct,*")])
14659
14660 (define_insn "sqrtsf2_1_sse_only"
14661   [(set (match_operand:SF 0 "register_operand" "=x")
14662         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14663   "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14664   "sqrtss\t{%1, %0|%0, %1}"
14665   [(set_attr "type" "sse")
14666    (set_attr "mode" "SF")
14667    (set_attr "athlon_decode" "*")])
14668
14669 (define_insn "sqrtsf2_i387"
14670   [(set (match_operand:SF 0 "register_operand" "=f")
14671         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14672   "TARGET_USE_FANCY_MATH_387
14673    && !TARGET_SSE_MATH"
14674   "fsqrt"
14675   [(set_attr "type" "fpspc")
14676    (set_attr "mode" "SF")
14677    (set_attr "athlon_decode" "direct")])
14678
14679 (define_expand "sqrtdf2"
14680   [(set (match_operand:DF 0 "register_operand" "")
14681         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14682   "TARGET_USE_FANCY_MATH_387
14683    || (TARGET_SSE2 && TARGET_SSE_MATH)"
14684 {
14685   if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14686     operands[1] = force_reg (DFmode, operands[1]);
14687 })
14688
14689 (define_insn "sqrtdf2_1"
14690   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14691         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14692   "TARGET_USE_FANCY_MATH_387
14693    && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14694   "@
14695    fsqrt
14696    sqrtsd\t{%1, %0|%0, %1}"
14697   [(set_attr "type" "fpspc,sse")
14698    (set_attr "mode" "DF,DF")
14699    (set_attr "athlon_decode" "direct,*")])
14700
14701 (define_insn "sqrtdf2_1_sse_only"
14702   [(set (match_operand:DF 0 "register_operand" "=Y")
14703         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14704   "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14705   "sqrtsd\t{%1, %0|%0, %1}"
14706   [(set_attr "type" "sse")
14707    (set_attr "mode" "DF")
14708    (set_attr "athlon_decode" "*")])
14709
14710 (define_insn "sqrtdf2_i387"
14711   [(set (match_operand:DF 0 "register_operand" "=f")
14712         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14713   "TARGET_USE_FANCY_MATH_387
14714    && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14715   "fsqrt"
14716   [(set_attr "type" "fpspc")
14717    (set_attr "mode" "DF")
14718    (set_attr "athlon_decode" "direct")])
14719
14720 (define_insn "*sqrtextendsfdf2"
14721   [(set (match_operand:DF 0 "register_operand" "=f")
14722         (sqrt:DF (float_extend:DF
14723                   (match_operand:SF 1 "register_operand" "0"))))]
14724   "TARGET_USE_FANCY_MATH_387
14725    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14726   "fsqrt"
14727   [(set_attr "type" "fpspc")
14728    (set_attr "mode" "DF")
14729    (set_attr "athlon_decode" "direct")])
14730
14731 (define_insn "sqrtxf2"
14732   [(set (match_operand:XF 0 "register_operand" "=f")
14733         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14734   "TARGET_USE_FANCY_MATH_387 
14735    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14736   "fsqrt"
14737   [(set_attr "type" "fpspc")
14738    (set_attr "mode" "XF")
14739    (set_attr "athlon_decode" "direct")])
14740
14741 (define_insn "*sqrtextenddfxf2"
14742   [(set (match_operand:XF 0 "register_operand" "=f")
14743         (sqrt:XF (float_extend:XF
14744                   (match_operand:DF 1 "register_operand" "0"))))]
14745   "TARGET_USE_FANCY_MATH_387"
14746   "fsqrt"
14747   [(set_attr "type" "fpspc")
14748    (set_attr "mode" "XF")
14749    (set_attr "athlon_decode" "direct")])
14750
14751 (define_insn "*sqrtextendsfxf2"
14752   [(set (match_operand:XF 0 "register_operand" "=f")
14753         (sqrt:XF (float_extend:XF
14754                   (match_operand:SF 1 "register_operand" "0"))))]
14755   "TARGET_USE_FANCY_MATH_387"
14756   "fsqrt"
14757   [(set_attr "type" "fpspc")
14758    (set_attr "mode" "XF")
14759    (set_attr "athlon_decode" "direct")])
14760
14761 (define_insn "fpremxf4"
14762   [(set (match_operand:XF 0 "register_operand" "=f")
14763         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14764                     (match_operand:XF 3 "register_operand" "1")]
14765                    UNSPEC_FPREM_F))
14766    (set (match_operand:XF 1 "register_operand" "=u")
14767         (unspec:XF [(match_dup 2) (match_dup 3)]
14768                    UNSPEC_FPREM_U))
14769    (set (reg:CCFP FPSR_REG)
14770         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14771   "TARGET_USE_FANCY_MATH_387
14772    && flag_unsafe_math_optimizations"
14773   "fprem"
14774   [(set_attr "type" "fpspc")
14775    (set_attr "mode" "XF")])
14776
14777 (define_expand "fmodsf3"
14778   [(use (match_operand:SF 0 "register_operand" ""))
14779    (use (match_operand:SF 1 "register_operand" ""))
14780    (use (match_operand:SF 2 "register_operand" ""))]
14781   "TARGET_USE_FANCY_MATH_387
14782    && flag_unsafe_math_optimizations"
14783 {
14784   rtx label = gen_label_rtx ();
14785
14786   rtx op1 = gen_reg_rtx (XFmode);
14787   rtx op2 = gen_reg_rtx (XFmode);
14788
14789   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14790   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14791
14792   emit_label (label);
14793
14794   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14795   ix86_emit_fp_unordered_jump (label);
14796
14797   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
14798   DONE;
14799 })
14800
14801 (define_expand "fmoddf3"
14802   [(use (match_operand:DF 0 "register_operand" ""))
14803    (use (match_operand:DF 1 "register_operand" ""))
14804    (use (match_operand:DF 2 "register_operand" ""))]
14805   "TARGET_USE_FANCY_MATH_387
14806    && flag_unsafe_math_optimizations"
14807 {
14808   rtx label = gen_label_rtx ();
14809
14810   rtx op1 = gen_reg_rtx (XFmode);
14811   rtx op2 = gen_reg_rtx (XFmode);
14812
14813   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14814   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14815
14816   emit_label (label);
14817
14818   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14819   ix86_emit_fp_unordered_jump (label);
14820
14821   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
14822   DONE;
14823 })
14824
14825 (define_expand "fmodxf3"
14826   [(use (match_operand:XF 0 "register_operand" ""))
14827    (use (match_operand:XF 1 "register_operand" ""))
14828    (use (match_operand:XF 2 "register_operand" ""))]
14829   "TARGET_USE_FANCY_MATH_387
14830    && flag_unsafe_math_optimizations"
14831 {
14832   rtx label = gen_label_rtx ();
14833
14834   emit_label (label);
14835
14836   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14837                            operands[1], operands[2]));
14838   ix86_emit_fp_unordered_jump (label);
14839
14840   emit_move_insn (operands[0], operands[1]);
14841   DONE;
14842 })
14843
14844 (define_insn "fprem1xf4"
14845   [(set (match_operand:XF 0 "register_operand" "=f")
14846         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14847                     (match_operand:XF 3 "register_operand" "1")]
14848                    UNSPEC_FPREM1_F))
14849    (set (match_operand:XF 1 "register_operand" "=u")
14850         (unspec:XF [(match_dup 2) (match_dup 3)]
14851                    UNSPEC_FPREM1_U))
14852    (set (reg:CCFP FPSR_REG)
14853         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14854   "TARGET_USE_FANCY_MATH_387
14855    && flag_unsafe_math_optimizations"
14856   "fprem1"
14857   [(set_attr "type" "fpspc")
14858    (set_attr "mode" "XF")])
14859
14860 (define_expand "dremsf3"
14861   [(use (match_operand:SF 0 "register_operand" ""))
14862    (use (match_operand:SF 1 "register_operand" ""))
14863    (use (match_operand:SF 2 "register_operand" ""))]
14864   "TARGET_USE_FANCY_MATH_387
14865    && flag_unsafe_math_optimizations"
14866 {
14867   rtx label = gen_label_rtx ();
14868
14869   rtx op1 = gen_reg_rtx (XFmode);
14870   rtx op2 = gen_reg_rtx (XFmode);
14871
14872   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14873   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14874
14875   emit_label (label);
14876
14877   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14878   ix86_emit_fp_unordered_jump (label);
14879
14880   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
14881   DONE;
14882 })
14883
14884 (define_expand "dremdf3"
14885   [(use (match_operand:DF 0 "register_operand" ""))
14886    (use (match_operand:DF 1 "register_operand" ""))
14887    (use (match_operand:DF 2 "register_operand" ""))]
14888   "TARGET_USE_FANCY_MATH_387
14889    && flag_unsafe_math_optimizations"
14890 {
14891   rtx label = gen_label_rtx ();
14892
14893   rtx op1 = gen_reg_rtx (XFmode);
14894   rtx op2 = gen_reg_rtx (XFmode);
14895
14896   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14897   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14898
14899   emit_label (label);
14900
14901   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14902   ix86_emit_fp_unordered_jump (label);
14903
14904   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
14905   DONE;
14906 })
14907
14908 (define_expand "dremxf3"
14909   [(use (match_operand:XF 0 "register_operand" ""))
14910    (use (match_operand:XF 1 "register_operand" ""))
14911    (use (match_operand:XF 2 "register_operand" ""))]
14912   "TARGET_USE_FANCY_MATH_387
14913    && flag_unsafe_math_optimizations"
14914 {
14915   rtx label = gen_label_rtx ();
14916
14917   emit_label (label);
14918
14919   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14920                             operands[1], operands[2]));
14921   ix86_emit_fp_unordered_jump (label);
14922
14923   emit_move_insn (operands[0], operands[1]);
14924   DONE;
14925 })
14926
14927 (define_insn "*sindf2"
14928   [(set (match_operand:DF 0 "register_operand" "=f")
14929         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14930   "TARGET_USE_FANCY_MATH_387
14931    && flag_unsafe_math_optimizations"
14932   "fsin"
14933   [(set_attr "type" "fpspc")
14934    (set_attr "mode" "DF")])
14935
14936 (define_insn "*sinsf2"
14937   [(set (match_operand:SF 0 "register_operand" "=f")
14938         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14939   "TARGET_USE_FANCY_MATH_387
14940    && flag_unsafe_math_optimizations"
14941   "fsin"
14942   [(set_attr "type" "fpspc")
14943    (set_attr "mode" "SF")])
14944
14945 (define_insn "*sinextendsfdf2"
14946   [(set (match_operand:DF 0 "register_operand" "=f")
14947         (unspec:DF [(float_extend:DF
14948                      (match_operand:SF 1 "register_operand" "0"))]
14949                    UNSPEC_SIN))]
14950   "TARGET_USE_FANCY_MATH_387
14951    && flag_unsafe_math_optimizations"
14952   "fsin"
14953   [(set_attr "type" "fpspc")
14954    (set_attr "mode" "DF")])
14955
14956 (define_insn "*sinxf2"
14957   [(set (match_operand:XF 0 "register_operand" "=f")
14958         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14959   "TARGET_USE_FANCY_MATH_387
14960    && flag_unsafe_math_optimizations"
14961   "fsin"
14962   [(set_attr "type" "fpspc")
14963    (set_attr "mode" "XF")])
14964
14965 (define_insn "*cosdf2"
14966   [(set (match_operand:DF 0 "register_operand" "=f")
14967         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14968   "TARGET_USE_FANCY_MATH_387
14969    && flag_unsafe_math_optimizations"
14970   "fcos"
14971   [(set_attr "type" "fpspc")
14972    (set_attr "mode" "DF")])
14973
14974 (define_insn "*cossf2"
14975   [(set (match_operand:SF 0 "register_operand" "=f")
14976         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14977   "TARGET_USE_FANCY_MATH_387
14978    && flag_unsafe_math_optimizations"
14979   "fcos"
14980   [(set_attr "type" "fpspc")
14981    (set_attr "mode" "SF")])
14982
14983 (define_insn "*cosextendsfdf2"
14984   [(set (match_operand:DF 0 "register_operand" "=f")
14985         (unspec:DF [(float_extend:DF
14986                      (match_operand:SF 1 "register_operand" "0"))]
14987                    UNSPEC_COS))]
14988   "TARGET_USE_FANCY_MATH_387
14989    && flag_unsafe_math_optimizations"
14990   "fcos"
14991   [(set_attr "type" "fpspc")
14992    (set_attr "mode" "DF")])
14993
14994 (define_insn "*cosxf2"
14995   [(set (match_operand:XF 0 "register_operand" "=f")
14996         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14997   "TARGET_USE_FANCY_MATH_387
14998    && flag_unsafe_math_optimizations"
14999   "fcos"
15000   [(set_attr "type" "fpspc")
15001    (set_attr "mode" "XF")])
15002
15003 ;; With sincos pattern defined, sin and cos builtin function will be
15004 ;; expanded to sincos pattern with one of its outputs left unused. 
15005 ;; Cse pass  will detected, if two sincos patterns can be combined,
15006 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15007 ;; depending on the unused output.
15008
15009 (define_insn "sincosdf3"
15010   [(set (match_operand:DF 0 "register_operand" "=f")
15011         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15012                    UNSPEC_SINCOS_COS))
15013    (set (match_operand:DF 1 "register_operand" "=u")
15014         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15015   "TARGET_USE_FANCY_MATH_387
15016    && flag_unsafe_math_optimizations"
15017   "fsincos"
15018   [(set_attr "type" "fpspc")
15019    (set_attr "mode" "DF")])
15020
15021 (define_split
15022   [(set (match_operand:DF 0 "register_operand" "")
15023         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15024                    UNSPEC_SINCOS_COS))
15025    (set (match_operand:DF 1 "register_operand" "")
15026         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15027   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15028    && !reload_completed && !reload_in_progress"
15029   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15030   "")
15031
15032 (define_split
15033   [(set (match_operand:DF 0 "register_operand" "")
15034         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15035                    UNSPEC_SINCOS_COS))
15036    (set (match_operand:DF 1 "register_operand" "")
15037         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15038   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15039    && !reload_completed && !reload_in_progress"
15040   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15041   "")
15042
15043 (define_insn "sincossf3"
15044   [(set (match_operand:SF 0 "register_operand" "=f")
15045         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15046                    UNSPEC_SINCOS_COS))
15047    (set (match_operand:SF 1 "register_operand" "=u")
15048         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15049   "TARGET_USE_FANCY_MATH_387
15050    && flag_unsafe_math_optimizations"
15051   "fsincos"
15052   [(set_attr "type" "fpspc")
15053    (set_attr "mode" "SF")])
15054
15055 (define_split
15056   [(set (match_operand:SF 0 "register_operand" "")
15057         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15058                    UNSPEC_SINCOS_COS))
15059    (set (match_operand:SF 1 "register_operand" "")
15060         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15061   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15062    && !reload_completed && !reload_in_progress"
15063   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15064   "")
15065
15066 (define_split
15067   [(set (match_operand:SF 0 "register_operand" "")
15068         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15069                    UNSPEC_SINCOS_COS))
15070    (set (match_operand:SF 1 "register_operand" "")
15071         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15072   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15073    && !reload_completed && !reload_in_progress"
15074   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15075   "")
15076
15077 (define_insn "*sincosextendsfdf3"
15078   [(set (match_operand:DF 0 "register_operand" "=f")
15079         (unspec:DF [(float_extend:DF
15080                      (match_operand:SF 2 "register_operand" "0"))]
15081                    UNSPEC_SINCOS_COS))
15082    (set (match_operand:DF 1 "register_operand" "=u")
15083         (unspec:DF [(float_extend:DF
15084                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15085   "TARGET_USE_FANCY_MATH_387
15086    && flag_unsafe_math_optimizations"
15087   "fsincos"
15088   [(set_attr "type" "fpspc")
15089    (set_attr "mode" "DF")])
15090
15091 (define_split
15092   [(set (match_operand:DF 0 "register_operand" "")
15093         (unspec:DF [(float_extend:DF
15094                      (match_operand:SF 2 "register_operand" ""))]
15095                    UNSPEC_SINCOS_COS))
15096    (set (match_operand:DF 1 "register_operand" "")
15097         (unspec:DF [(float_extend:DF
15098                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15099   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15100    && !reload_completed && !reload_in_progress"
15101   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15102                                    (match_dup 2))] UNSPEC_SIN))]
15103   "")
15104
15105 (define_split
15106   [(set (match_operand:DF 0 "register_operand" "")
15107         (unspec:DF [(float_extend:DF
15108                      (match_operand:SF 2 "register_operand" ""))]
15109                    UNSPEC_SINCOS_COS))
15110    (set (match_operand:DF 1 "register_operand" "")
15111         (unspec:DF [(float_extend:DF
15112                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15113   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15114    && !reload_completed && !reload_in_progress"
15115   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15116                                    (match_dup 2))] UNSPEC_COS))]
15117   "")
15118
15119 (define_insn "sincosxf3"
15120   [(set (match_operand:XF 0 "register_operand" "=f")
15121         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15122                    UNSPEC_SINCOS_COS))
15123    (set (match_operand:XF 1 "register_operand" "=u")
15124         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15125   "TARGET_USE_FANCY_MATH_387
15126    && flag_unsafe_math_optimizations"
15127   "fsincos"
15128   [(set_attr "type" "fpspc")
15129    (set_attr "mode" "XF")])
15130
15131 (define_split
15132   [(set (match_operand:XF 0 "register_operand" "")
15133         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15134                    UNSPEC_SINCOS_COS))
15135    (set (match_operand:XF 1 "register_operand" "")
15136         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15137   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15138    && !reload_completed && !reload_in_progress"
15139   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15140   "")
15141
15142 (define_split
15143   [(set (match_operand:XF 0 "register_operand" "")
15144         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15145                    UNSPEC_SINCOS_COS))
15146    (set (match_operand:XF 1 "register_operand" "")
15147         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15148   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15149    && !reload_completed && !reload_in_progress"
15150   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15151   "")
15152
15153 (define_insn "*tandf3_1"
15154   [(set (match_operand:DF 0 "register_operand" "=f")
15155         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15156                    UNSPEC_TAN_ONE))
15157    (set (match_operand:DF 1 "register_operand" "=u")
15158         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15159   "TARGET_USE_FANCY_MATH_387
15160    && flag_unsafe_math_optimizations"
15161   "fptan"
15162   [(set_attr "type" "fpspc")
15163    (set_attr "mode" "DF")])
15164
15165 ;; optimize sequence: fptan
15166 ;;                    fstp    %st(0)
15167 ;;                    fld1
15168 ;; into fptan insn.
15169
15170 (define_peephole2
15171   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15172                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15173                              UNSPEC_TAN_ONE))
15174              (set (match_operand:DF 1 "register_operand" "")
15175                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15176    (set (match_dup 0)
15177         (match_operand:DF 3 "immediate_operand" ""))]
15178   "standard_80387_constant_p (operands[3]) == 2"
15179   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15180              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15181   "")
15182
15183 (define_expand "tandf2"
15184   [(parallel [(set (match_dup 2)
15185                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15186                               UNSPEC_TAN_ONE))
15187               (set (match_operand:DF 0 "register_operand" "")
15188                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15189   "TARGET_USE_FANCY_MATH_387
15190    && flag_unsafe_math_optimizations"
15191 {
15192   operands[2] = gen_reg_rtx (DFmode);
15193 })
15194
15195 (define_insn "*tansf3_1"
15196   [(set (match_operand:SF 0 "register_operand" "=f")
15197         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15198                    UNSPEC_TAN_ONE))
15199    (set (match_operand:SF 1 "register_operand" "=u")
15200         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15201   "TARGET_USE_FANCY_MATH_387
15202    && flag_unsafe_math_optimizations"
15203   "fptan"
15204   [(set_attr "type" "fpspc")
15205    (set_attr "mode" "SF")])
15206
15207 ;; optimize sequence: fptan
15208 ;;                    fstp    %st(0)
15209 ;;                    fld1
15210 ;; into fptan insn.
15211
15212 (define_peephole2
15213   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15214                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15215                              UNSPEC_TAN_ONE))
15216              (set (match_operand:SF 1 "register_operand" "")
15217                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15218    (set (match_dup 0)
15219         (match_operand:SF 3 "immediate_operand" ""))]
15220   "standard_80387_constant_p (operands[3]) == 2"
15221   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15222              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15223   "")
15224
15225 (define_expand "tansf2"
15226   [(parallel [(set (match_dup 2)
15227                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15228                               UNSPEC_TAN_ONE))
15229               (set (match_operand:SF 0 "register_operand" "")
15230                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15231   "TARGET_USE_FANCY_MATH_387
15232    && flag_unsafe_math_optimizations"
15233 {
15234   operands[2] = gen_reg_rtx (SFmode);
15235 })
15236
15237 (define_insn "*tanxf3_1"
15238   [(set (match_operand:XF 0 "register_operand" "=f")
15239         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15240                    UNSPEC_TAN_ONE))
15241    (set (match_operand:XF 1 "register_operand" "=u")
15242         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15243   "TARGET_USE_FANCY_MATH_387
15244    && flag_unsafe_math_optimizations"
15245   "fptan"
15246   [(set_attr "type" "fpspc")
15247    (set_attr "mode" "XF")])
15248
15249 ;; optimize sequence: fptan
15250 ;;                    fstp    %st(0)
15251 ;;                    fld1
15252 ;; into fptan insn.
15253
15254 (define_peephole2
15255   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15256                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15257                              UNSPEC_TAN_ONE))
15258              (set (match_operand:XF 1 "register_operand" "")
15259                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15260    (set (match_dup 0)
15261         (match_operand:XF 3 "immediate_operand" ""))]
15262   "standard_80387_constant_p (operands[3]) == 2"
15263   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15264              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15265   "")
15266
15267 (define_expand "tanxf2"
15268   [(parallel [(set (match_dup 2)
15269                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15270                               UNSPEC_TAN_ONE))
15271               (set (match_operand:XF 0 "register_operand" "")
15272                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15273   "TARGET_USE_FANCY_MATH_387
15274    && flag_unsafe_math_optimizations"
15275 {
15276   operands[2] = gen_reg_rtx (XFmode);
15277 })
15278
15279 (define_insn "atan2df3_1"
15280   [(set (match_operand:DF 0 "register_operand" "=f")
15281         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15282                     (match_operand:DF 1 "register_operand" "u")]
15283                    UNSPEC_FPATAN))
15284    (clobber (match_scratch:DF 3 "=1"))]
15285   "TARGET_USE_FANCY_MATH_387
15286    && flag_unsafe_math_optimizations"
15287   "fpatan"
15288   [(set_attr "type" "fpspc")
15289    (set_attr "mode" "DF")])
15290
15291 (define_expand "atan2df3"
15292   [(use (match_operand:DF 0 "register_operand" "=f"))
15293    (use (match_operand:DF 2 "register_operand" "0"))
15294    (use (match_operand:DF 1 "register_operand" "u"))]
15295   "TARGET_USE_FANCY_MATH_387
15296    && flag_unsafe_math_optimizations"
15297 {
15298   rtx copy = gen_reg_rtx (DFmode);
15299   emit_move_insn (copy, operands[1]);
15300   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15301   DONE;
15302 })
15303
15304 (define_expand "atandf2"
15305   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15306                    (unspec:DF [(match_dup 2)
15307                                (match_operand:DF 1 "register_operand" "")]
15308                     UNSPEC_FPATAN))
15309               (clobber (match_scratch:DF 3 ""))])]
15310   "TARGET_USE_FANCY_MATH_387
15311    && flag_unsafe_math_optimizations"
15312 {
15313   operands[2] = gen_reg_rtx (DFmode);
15314   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15315 })
15316
15317 (define_insn "atan2sf3_1"
15318   [(set (match_operand:SF 0 "register_operand" "=f")
15319         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15320                     (match_operand:SF 1 "register_operand" "u")]
15321                    UNSPEC_FPATAN))
15322    (clobber (match_scratch:SF 3 "=1"))]
15323   "TARGET_USE_FANCY_MATH_387
15324    && flag_unsafe_math_optimizations"
15325   "fpatan"
15326   [(set_attr "type" "fpspc")
15327    (set_attr "mode" "SF")])
15328
15329 (define_expand "atan2sf3"
15330   [(use (match_operand:SF 0 "register_operand" "=f"))
15331    (use (match_operand:SF 2 "register_operand" "0"))
15332    (use (match_operand:SF 1 "register_operand" "u"))]
15333   "TARGET_USE_FANCY_MATH_387
15334    && flag_unsafe_math_optimizations"
15335 {
15336   rtx copy = gen_reg_rtx (SFmode);
15337   emit_move_insn (copy, operands[1]);
15338   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15339   DONE;
15340 })
15341
15342 (define_expand "atansf2"
15343   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15344                    (unspec:SF [(match_dup 2)
15345                                (match_operand:SF 1 "register_operand" "")]
15346                     UNSPEC_FPATAN))
15347               (clobber (match_scratch:SF 3 ""))])]
15348   "TARGET_USE_FANCY_MATH_387
15349    && flag_unsafe_math_optimizations"
15350 {
15351   operands[2] = gen_reg_rtx (SFmode);
15352   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15353 })
15354
15355 (define_insn "atan2xf3_1"
15356   [(set (match_operand:XF 0 "register_operand" "=f")
15357         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15358                     (match_operand:XF 1 "register_operand" "u")]
15359                    UNSPEC_FPATAN))
15360    (clobber (match_scratch:XF 3 "=1"))]
15361   "TARGET_USE_FANCY_MATH_387
15362    && flag_unsafe_math_optimizations"
15363   "fpatan"
15364   [(set_attr "type" "fpspc")
15365    (set_attr "mode" "XF")])
15366
15367 (define_expand "atan2xf3"
15368   [(use (match_operand:XF 0 "register_operand" "=f"))
15369    (use (match_operand:XF 2 "register_operand" "0"))
15370    (use (match_operand:XF 1 "register_operand" "u"))]
15371   "TARGET_USE_FANCY_MATH_387
15372    && flag_unsafe_math_optimizations"
15373 {
15374   rtx copy = gen_reg_rtx (XFmode);
15375   emit_move_insn (copy, operands[1]);
15376   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15377   DONE;
15378 })
15379
15380 (define_expand "atanxf2"
15381   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15382                    (unspec:XF [(match_dup 2)
15383                                (match_operand:XF 1 "register_operand" "")]
15384                     UNSPEC_FPATAN))
15385               (clobber (match_scratch:XF 3 ""))])]
15386   "TARGET_USE_FANCY_MATH_387
15387    && flag_unsafe_math_optimizations"
15388 {
15389   operands[2] = gen_reg_rtx (XFmode);
15390   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15391 })
15392
15393 (define_expand "asindf2"
15394   [(set (match_dup 2)
15395         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15396    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15397    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15398    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15399    (parallel [(set (match_dup 7)
15400                    (unspec:XF [(match_dup 6) (match_dup 2)]
15401                               UNSPEC_FPATAN))
15402               (clobber (match_scratch:XF 8 ""))])
15403    (set (match_operand:DF 0 "register_operand" "")
15404         (float_truncate:DF (match_dup 7)))]
15405   "TARGET_USE_FANCY_MATH_387
15406    && flag_unsafe_math_optimizations"
15407 {
15408   int i;
15409
15410   for (i=2; i<8; i++)
15411     operands[i] = gen_reg_rtx (XFmode);
15412
15413   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15414 })
15415
15416 (define_expand "asinsf2"
15417   [(set (match_dup 2)
15418         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15419    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15420    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15421    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15422    (parallel [(set (match_dup 7)
15423                    (unspec:XF [(match_dup 6) (match_dup 2)]
15424                               UNSPEC_FPATAN))
15425               (clobber (match_scratch:XF 8 ""))])
15426    (set (match_operand:SF 0 "register_operand" "")
15427         (float_truncate:SF (match_dup 7)))]
15428   "TARGET_USE_FANCY_MATH_387
15429    && flag_unsafe_math_optimizations"
15430 {
15431   int i;
15432
15433   for (i=2; i<8; i++)
15434     operands[i] = gen_reg_rtx (XFmode);
15435
15436   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15437 })
15438
15439 (define_expand "asinxf2"
15440   [(set (match_dup 2)
15441         (mult:XF (match_operand:XF 1 "register_operand" "")
15442                  (match_dup 1)))
15443    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15444    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15445    (parallel [(set (match_operand:XF 0 "register_operand" "")
15446                    (unspec:XF [(match_dup 5) (match_dup 1)]
15447                               UNSPEC_FPATAN))
15448               (clobber (match_scratch:XF 6 ""))])]
15449   "TARGET_USE_FANCY_MATH_387
15450    && flag_unsafe_math_optimizations"
15451 {
15452   int i;
15453
15454   for (i=2; i<6; i++)
15455     operands[i] = gen_reg_rtx (XFmode);
15456
15457   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15458 })
15459
15460 (define_expand "acosdf2"
15461   [(set (match_dup 2)
15462         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15463    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15464    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15465    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15466    (parallel [(set (match_dup 7)
15467                    (unspec:XF [(match_dup 2) (match_dup 6)]
15468                               UNSPEC_FPATAN))
15469               (clobber (match_scratch:XF 8 ""))])
15470    (set (match_operand:DF 0 "register_operand" "")
15471         (float_truncate:DF (match_dup 7)))]
15472   "TARGET_USE_FANCY_MATH_387
15473    && flag_unsafe_math_optimizations"
15474 {
15475   int i;
15476
15477   for (i=2; i<8; i++)
15478     operands[i] = gen_reg_rtx (XFmode);
15479
15480   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15481 })
15482
15483 (define_expand "acossf2"
15484   [(set (match_dup 2)
15485         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15486    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15487    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15488    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15489    (parallel [(set (match_dup 7)
15490                    (unspec:XF [(match_dup 2) (match_dup 6)]
15491                               UNSPEC_FPATAN))
15492               (clobber (match_scratch:XF 8 ""))])
15493    (set (match_operand:SF 0 "register_operand" "")
15494         (float_truncate:SF (match_dup 7)))]
15495   "TARGET_USE_FANCY_MATH_387
15496    && flag_unsafe_math_optimizations"
15497 {
15498   int i;
15499
15500   for (i=2; i<8; i++)
15501     operands[i] = gen_reg_rtx (XFmode);
15502
15503   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15504 })
15505
15506 (define_expand "acosxf2"
15507   [(set (match_dup 2)
15508         (mult:XF (match_operand:XF 1 "register_operand" "")
15509                  (match_dup 1)))
15510    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15511    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15512    (parallel [(set (match_operand:XF 0 "register_operand" "")
15513                    (unspec:XF [(match_dup 1) (match_dup 5)]
15514                               UNSPEC_FPATAN))
15515               (clobber (match_scratch:XF 6 ""))])]
15516   "TARGET_USE_FANCY_MATH_387
15517    && flag_unsafe_math_optimizations"
15518 {
15519   int i;
15520
15521   for (i=2; i<6; i++)
15522     operands[i] = gen_reg_rtx (XFmode);
15523
15524   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15525 })
15526
15527 (define_insn "fyl2x_xf3"
15528   [(set (match_operand:XF 0 "register_operand" "=f")
15529         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15530                     (match_operand:XF 1 "register_operand" "u")]
15531                    UNSPEC_FYL2X))
15532    (clobber (match_scratch:XF 3 "=1"))]
15533   "TARGET_USE_FANCY_MATH_387
15534    && flag_unsafe_math_optimizations"
15535   "fyl2x"
15536   [(set_attr "type" "fpspc")
15537    (set_attr "mode" "XF")])
15538
15539 (define_expand "logsf2"
15540   [(set (match_dup 2)
15541         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15542    (parallel [(set (match_dup 4)
15543                    (unspec:XF [(match_dup 2)
15544                                (match_dup 3)] UNSPEC_FYL2X))
15545               (clobber (match_scratch:XF 5 ""))])
15546    (set (match_operand:SF 0 "register_operand" "")
15547         (float_truncate:SF (match_dup 4)))]
15548   "TARGET_USE_FANCY_MATH_387
15549    && flag_unsafe_math_optimizations"
15550 {
15551   rtx temp;
15552
15553   operands[2] = gen_reg_rtx (XFmode);
15554   operands[3] = gen_reg_rtx (XFmode);
15555   operands[4] = gen_reg_rtx (XFmode);
15556
15557   temp = standard_80387_constant_rtx (4); /* fldln2 */
15558   emit_move_insn (operands[3], temp);
15559 })
15560
15561 (define_expand "logdf2"
15562   [(set (match_dup 2)
15563         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15564    (parallel [(set (match_dup 4)
15565                    (unspec:XF [(match_dup 2)
15566                                (match_dup 3)] UNSPEC_FYL2X))
15567               (clobber (match_scratch:XF 5 ""))])
15568    (set (match_operand:DF 0 "register_operand" "")
15569         (float_truncate:DF (match_dup 4)))]
15570   "TARGET_USE_FANCY_MATH_387
15571    && flag_unsafe_math_optimizations"
15572 {
15573   rtx temp;
15574
15575   operands[2] = gen_reg_rtx (XFmode);
15576   operands[3] = gen_reg_rtx (XFmode);
15577   operands[4] = gen_reg_rtx (XFmode);
15578
15579   temp = standard_80387_constant_rtx (4); /* fldln2 */
15580   emit_move_insn (operands[3], temp);
15581 })
15582
15583 (define_expand "logxf2"
15584   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15585                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15586                                (match_dup 2)] UNSPEC_FYL2X))
15587               (clobber (match_scratch:XF 3 ""))])]
15588   "TARGET_USE_FANCY_MATH_387
15589    && flag_unsafe_math_optimizations"
15590 {
15591   rtx temp;
15592
15593   operands[2] = gen_reg_rtx (XFmode);
15594   temp = standard_80387_constant_rtx (4); /* fldln2 */
15595   emit_move_insn (operands[2], temp);
15596 })
15597
15598 (define_expand "log10sf2"
15599   [(set (match_dup 2)
15600         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15601    (parallel [(set (match_dup 4)
15602                    (unspec:XF [(match_dup 2)
15603                                (match_dup 3)] UNSPEC_FYL2X))
15604               (clobber (match_scratch:XF 5 ""))])
15605    (set (match_operand:SF 0 "register_operand" "")
15606         (float_truncate:SF (match_dup 4)))]
15607   "TARGET_USE_FANCY_MATH_387
15608    && flag_unsafe_math_optimizations"
15609 {
15610   rtx temp;
15611
15612   operands[2] = gen_reg_rtx (XFmode);
15613   operands[3] = gen_reg_rtx (XFmode);
15614   operands[4] = gen_reg_rtx (XFmode);
15615
15616   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15617   emit_move_insn (operands[3], temp);
15618 })
15619
15620 (define_expand "log10df2"
15621   [(set (match_dup 2)
15622         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15623    (parallel [(set (match_dup 4)
15624                    (unspec:XF [(match_dup 2)
15625                                (match_dup 3)] UNSPEC_FYL2X))
15626               (clobber (match_scratch:XF 5 ""))])
15627    (set (match_operand:DF 0 "register_operand" "")
15628         (float_truncate:DF (match_dup 4)))]
15629   "TARGET_USE_FANCY_MATH_387
15630    && flag_unsafe_math_optimizations"
15631 {
15632   rtx temp;
15633
15634   operands[2] = gen_reg_rtx (XFmode);
15635   operands[3] = gen_reg_rtx (XFmode);
15636   operands[4] = gen_reg_rtx (XFmode);
15637
15638   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15639   emit_move_insn (operands[3], temp);
15640 })
15641
15642 (define_expand "log10xf2"
15643   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15644                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15645                                (match_dup 2)] UNSPEC_FYL2X))
15646               (clobber (match_scratch:XF 3 ""))])]
15647   "TARGET_USE_FANCY_MATH_387
15648    && flag_unsafe_math_optimizations"
15649 {
15650   rtx temp;
15651
15652   operands[2] = gen_reg_rtx (XFmode);
15653   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15654   emit_move_insn (operands[2], temp);
15655 })
15656
15657 (define_expand "log2sf2"
15658   [(set (match_dup 2)
15659         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15660    (parallel [(set (match_dup 4)
15661                    (unspec:XF [(match_dup 2)
15662                                (match_dup 3)] UNSPEC_FYL2X))
15663               (clobber (match_scratch:XF 5 ""))])
15664    (set (match_operand:SF 0 "register_operand" "")
15665         (float_truncate:SF (match_dup 4)))]
15666   "TARGET_USE_FANCY_MATH_387
15667    && flag_unsafe_math_optimizations"
15668 {
15669   operands[2] = gen_reg_rtx (XFmode);
15670   operands[3] = gen_reg_rtx (XFmode);
15671   operands[4] = gen_reg_rtx (XFmode);
15672
15673   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15674 })
15675
15676 (define_expand "log2df2"
15677   [(set (match_dup 2)
15678         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15679    (parallel [(set (match_dup 4)
15680                    (unspec:XF [(match_dup 2)
15681                                (match_dup 3)] UNSPEC_FYL2X))
15682               (clobber (match_scratch:XF 5 ""))])
15683    (set (match_operand:DF 0 "register_operand" "")
15684         (float_truncate:DF (match_dup 4)))]
15685   "TARGET_USE_FANCY_MATH_387
15686    && flag_unsafe_math_optimizations"
15687 {
15688   operands[2] = gen_reg_rtx (XFmode);
15689   operands[3] = gen_reg_rtx (XFmode);
15690   operands[4] = gen_reg_rtx (XFmode);
15691
15692   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15693 })
15694
15695 (define_expand "log2xf2"
15696   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15697                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15698                                (match_dup 2)] UNSPEC_FYL2X))
15699               (clobber (match_scratch:XF 3 ""))])]
15700   "TARGET_USE_FANCY_MATH_387
15701    && flag_unsafe_math_optimizations"
15702 {
15703   operands[2] = gen_reg_rtx (XFmode);
15704   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15705 })
15706
15707 (define_insn "fyl2xp1_xf3"
15708   [(set (match_operand:XF 0 "register_operand" "=f")
15709         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15710                     (match_operand:XF 1 "register_operand" "u")]
15711                    UNSPEC_FYL2XP1))
15712    (clobber (match_scratch:XF 3 "=1"))]
15713   "TARGET_USE_FANCY_MATH_387
15714    && flag_unsafe_math_optimizations"
15715   "fyl2xp1"
15716   [(set_attr "type" "fpspc")
15717    (set_attr "mode" "XF")])
15718
15719 (define_expand "log1psf2"
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   rtx op0 = gen_reg_rtx (XFmode);
15726   rtx op1 = gen_reg_rtx (XFmode);
15727
15728   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15729   ix86_emit_i387_log1p (op0, op1);
15730   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
15731   DONE;
15732 })
15733
15734 (define_expand "log1pdf2"
15735   [(use (match_operand:XF 0 "register_operand" ""))
15736    (use (match_operand:XF 1 "register_operand" ""))]
15737   "TARGET_USE_FANCY_MATH_387
15738    && flag_unsafe_math_optimizations"
15739 {
15740   rtx op0 = gen_reg_rtx (XFmode);
15741   rtx op1 = gen_reg_rtx (XFmode);
15742
15743   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15744   ix86_emit_i387_log1p (op0, op1);
15745   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
15746   DONE;
15747 })
15748
15749 (define_expand "log1pxf2"
15750   [(use (match_operand:XF 0 "register_operand" ""))
15751    (use (match_operand:XF 1 "register_operand" ""))]
15752   "TARGET_USE_FANCY_MATH_387
15753    && flag_unsafe_math_optimizations"
15754 {
15755   ix86_emit_i387_log1p (operands[0], operands[1]);
15756   DONE;
15757 })
15758
15759 (define_insn "*fxtractxf3"
15760   [(set (match_operand:XF 0 "register_operand" "=f")
15761         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15762                    UNSPEC_XTRACT_FRACT))
15763    (set (match_operand:XF 1 "register_operand" "=u")
15764         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15765   "TARGET_USE_FANCY_MATH_387
15766    && flag_unsafe_math_optimizations"
15767   "fxtract"
15768   [(set_attr "type" "fpspc")
15769    (set_attr "mode" "XF")])
15770
15771 (define_expand "logbsf2"
15772   [(set (match_dup 2)
15773         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15774    (parallel [(set (match_dup 3)
15775                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15776               (set (match_dup 4)
15777                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15778    (set (match_operand:SF 0 "register_operand" "")
15779         (float_truncate:SF (match_dup 4)))]
15780   "TARGET_USE_FANCY_MATH_387
15781    && flag_unsafe_math_optimizations"
15782 {
15783   operands[2] = gen_reg_rtx (XFmode);
15784   operands[3] = gen_reg_rtx (XFmode);
15785   operands[4] = gen_reg_rtx (XFmode);
15786 })
15787
15788 (define_expand "logbdf2"
15789   [(set (match_dup 2)
15790         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15791    (parallel [(set (match_dup 3)
15792                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15793               (set (match_dup 4)
15794                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15795    (set (match_operand:DF 0 "register_operand" "")
15796         (float_truncate:DF (match_dup 4)))]
15797   "TARGET_USE_FANCY_MATH_387
15798    && flag_unsafe_math_optimizations"
15799 {
15800   operands[2] = gen_reg_rtx (XFmode);
15801   operands[3] = gen_reg_rtx (XFmode);
15802   operands[4] = gen_reg_rtx (XFmode);
15803 })
15804
15805 (define_expand "logbxf2"
15806   [(parallel [(set (match_dup 2)
15807                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15808                               UNSPEC_XTRACT_FRACT))
15809               (set (match_operand:XF 0 "register_operand" "")
15810                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15811   "TARGET_USE_FANCY_MATH_387
15812    && flag_unsafe_math_optimizations"
15813 {
15814   operands[2] = gen_reg_rtx (XFmode);
15815 })
15816
15817 (define_expand "ilogbsi2"
15818   [(parallel [(set (match_dup 2)
15819                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15820                               UNSPEC_XTRACT_FRACT))
15821               (set (match_operand:XF 3 "register_operand" "")
15822                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15823    (parallel [(set (match_operand:SI 0 "register_operand" "")
15824                    (fix:SI (match_dup 3)))
15825               (clobber (reg:CC FLAGS_REG))])]
15826   "TARGET_USE_FANCY_MATH_387
15827    && flag_unsafe_math_optimizations"
15828 {
15829   operands[2] = gen_reg_rtx (XFmode);
15830   operands[3] = gen_reg_rtx (XFmode);
15831 })
15832
15833 (define_insn "*f2xm1xf2"
15834   [(set (match_operand:XF 0 "register_operand" "=f")
15835         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15836          UNSPEC_F2XM1))]
15837   "TARGET_USE_FANCY_MATH_387
15838    && flag_unsafe_math_optimizations"
15839   "f2xm1"
15840   [(set_attr "type" "fpspc")
15841    (set_attr "mode" "XF")])
15842
15843 (define_insn "*fscalexf4"
15844   [(set (match_operand:XF 0 "register_operand" "=f")
15845         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15846                     (match_operand:XF 3 "register_operand" "1")]
15847                    UNSPEC_FSCALE_FRACT))
15848    (set (match_operand:XF 1 "register_operand" "=u")
15849         (unspec:XF [(match_dup 2) (match_dup 3)]
15850                    UNSPEC_FSCALE_EXP))]
15851   "TARGET_USE_FANCY_MATH_387
15852    && flag_unsafe_math_optimizations"
15853   "fscale"
15854   [(set_attr "type" "fpspc")
15855    (set_attr "mode" "XF")])
15856
15857 (define_expand "expsf2"
15858   [(set (match_dup 2)
15859         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15860    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15861    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15862    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15863    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15864    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15865    (parallel [(set (match_dup 10)
15866                    (unspec:XF [(match_dup 9) (match_dup 5)]
15867                               UNSPEC_FSCALE_FRACT))
15868               (set (match_dup 11)
15869                    (unspec:XF [(match_dup 9) (match_dup 5)]
15870                               UNSPEC_FSCALE_EXP))])
15871    (set (match_operand:SF 0 "register_operand" "")
15872         (float_truncate:SF (match_dup 10)))]
15873   "TARGET_USE_FANCY_MATH_387
15874    && flag_unsafe_math_optimizations"
15875 {
15876   rtx temp;
15877   int i;
15878
15879   for (i=2; i<12; i++)
15880     operands[i] = gen_reg_rtx (XFmode);
15881   temp = standard_80387_constant_rtx (5); /* fldl2e */
15882   emit_move_insn (operands[3], temp);
15883   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15884 })
15885
15886 (define_expand "expdf2"
15887   [(set (match_dup 2)
15888         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15889    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15890    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15891    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15892    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15893    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15894    (parallel [(set (match_dup 10)
15895                    (unspec:XF [(match_dup 9) (match_dup 5)]
15896                               UNSPEC_FSCALE_FRACT))
15897               (set (match_dup 11)
15898                    (unspec:XF [(match_dup 9) (match_dup 5)]
15899                               UNSPEC_FSCALE_EXP))])
15900    (set (match_operand:DF 0 "register_operand" "")
15901         (float_truncate:DF (match_dup 10)))]
15902   "TARGET_USE_FANCY_MATH_387
15903    && flag_unsafe_math_optimizations"
15904 {
15905   rtx temp;
15906   int i;
15907
15908   for (i=2; i<12; i++)
15909     operands[i] = gen_reg_rtx (XFmode);
15910   temp = standard_80387_constant_rtx (5); /* fldl2e */
15911   emit_move_insn (operands[3], temp);
15912   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15913 })
15914
15915 (define_expand "expxf2"
15916   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15917                                (match_dup 2)))
15918    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15919    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15920    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15921    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15922    (parallel [(set (match_operand:XF 0 "register_operand" "")
15923                    (unspec:XF [(match_dup 8) (match_dup 4)]
15924                               UNSPEC_FSCALE_FRACT))
15925               (set (match_dup 9)
15926                    (unspec:XF [(match_dup 8) (match_dup 4)]
15927                               UNSPEC_FSCALE_EXP))])]
15928   "TARGET_USE_FANCY_MATH_387
15929    && flag_unsafe_math_optimizations"
15930 {
15931   rtx temp;
15932   int i;
15933
15934   for (i=2; i<10; i++)
15935     operands[i] = gen_reg_rtx (XFmode);
15936   temp = standard_80387_constant_rtx (5); /* fldl2e */
15937   emit_move_insn (operands[2], temp);
15938   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15939 })
15940
15941 (define_expand "exp10sf2"
15942   [(set (match_dup 2)
15943         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15944    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15945    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15946    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15947    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15948    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15949    (parallel [(set (match_dup 10)
15950                    (unspec:XF [(match_dup 9) (match_dup 5)]
15951                               UNSPEC_FSCALE_FRACT))
15952               (set (match_dup 11)
15953                    (unspec:XF [(match_dup 9) (match_dup 5)]
15954                               UNSPEC_FSCALE_EXP))])
15955    (set (match_operand:SF 0 "register_operand" "")
15956         (float_truncate:SF (match_dup 10)))]
15957   "TARGET_USE_FANCY_MATH_387
15958    && flag_unsafe_math_optimizations"
15959 {
15960   rtx temp;
15961   int i;
15962
15963   for (i=2; i<12; i++)
15964     operands[i] = gen_reg_rtx (XFmode);
15965   temp = standard_80387_constant_rtx (6); /* fldl2t */
15966   emit_move_insn (operands[3], temp);
15967   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15968 })
15969
15970 (define_expand "exp10df2"
15971   [(set (match_dup 2)
15972         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15973    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15974    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15975    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15976    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15977    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15978    (parallel [(set (match_dup 10)
15979                    (unspec:XF [(match_dup 9) (match_dup 5)]
15980                               UNSPEC_FSCALE_FRACT))
15981               (set (match_dup 11)
15982                    (unspec:XF [(match_dup 9) (match_dup 5)]
15983                               UNSPEC_FSCALE_EXP))])
15984    (set (match_operand:DF 0 "register_operand" "")
15985         (float_truncate:DF (match_dup 10)))]
15986   "TARGET_USE_FANCY_MATH_387
15987    && flag_unsafe_math_optimizations"
15988 {
15989   rtx temp;
15990   int i;
15991
15992   for (i=2; i<12; i++)
15993     operands[i] = gen_reg_rtx (XFmode);
15994   temp = standard_80387_constant_rtx (6); /* fldl2t */
15995   emit_move_insn (operands[3], temp);
15996   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15997 })
15998
15999 (define_expand "exp10xf2"
16000   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16001                                (match_dup 2)))
16002    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16003    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16004    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16005    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16006    (parallel [(set (match_operand:XF 0 "register_operand" "")
16007                    (unspec:XF [(match_dup 8) (match_dup 4)]
16008                               UNSPEC_FSCALE_FRACT))
16009               (set (match_dup 9)
16010                    (unspec:XF [(match_dup 8) (match_dup 4)]
16011                               UNSPEC_FSCALE_EXP))])]
16012   "TARGET_USE_FANCY_MATH_387
16013    && flag_unsafe_math_optimizations"
16014 {
16015   rtx temp;
16016   int i;
16017
16018   for (i=2; i<10; i++)
16019     operands[i] = gen_reg_rtx (XFmode);
16020   temp = standard_80387_constant_rtx (6); /* fldl2t */
16021   emit_move_insn (operands[2], temp);
16022   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16023 })
16024
16025 (define_expand "exp2sf2"
16026   [(set (match_dup 2)
16027         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16028    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16029    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16030    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16031    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16032    (parallel [(set (match_dup 8)
16033                    (unspec:XF [(match_dup 7) (match_dup 3)]
16034                               UNSPEC_FSCALE_FRACT))
16035               (set (match_dup 9)
16036                    (unspec:XF [(match_dup 7) (match_dup 3)]
16037                               UNSPEC_FSCALE_EXP))])
16038    (set (match_operand:SF 0 "register_operand" "")
16039         (float_truncate:SF (match_dup 8)))]
16040   "TARGET_USE_FANCY_MATH_387
16041    && flag_unsafe_math_optimizations"
16042 {
16043   int i;
16044
16045   for (i=2; i<10; i++)
16046     operands[i] = gen_reg_rtx (XFmode);
16047   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16048 })
16049
16050 (define_expand "exp2df2"
16051   [(set (match_dup 2)
16052         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16053    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16054    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16055    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16056    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16057    (parallel [(set (match_dup 8)
16058                    (unspec:XF [(match_dup 7) (match_dup 3)]
16059                               UNSPEC_FSCALE_FRACT))
16060               (set (match_dup 9)
16061                    (unspec:XF [(match_dup 7) (match_dup 3)]
16062                               UNSPEC_FSCALE_EXP))])
16063    (set (match_operand:DF 0 "register_operand" "")
16064         (float_truncate:DF (match_dup 8)))]
16065   "TARGET_USE_FANCY_MATH_387
16066    && flag_unsafe_math_optimizations"
16067 {
16068   int i;
16069
16070   for (i=2; i<10; i++)
16071     operands[i] = gen_reg_rtx (XFmode);
16072   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16073 })
16074
16075 (define_expand "exp2xf2"
16076   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16077    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16078    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16079    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16080    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16081    (parallel [(set (match_operand:XF 0 "register_operand" "")
16082                    (unspec:XF [(match_dup 7) (match_dup 3)]
16083                               UNSPEC_FSCALE_FRACT))
16084               (set (match_dup 8)
16085                    (unspec:XF [(match_dup 7) (match_dup 3)]
16086                               UNSPEC_FSCALE_EXP))])]
16087   "TARGET_USE_FANCY_MATH_387
16088    && flag_unsafe_math_optimizations"
16089 {
16090   int i;
16091
16092   for (i=2; i<9; i++)
16093     operands[i] = gen_reg_rtx (XFmode);
16094   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16095 })
16096
16097 (define_expand "expm1df2"
16098   [(set (match_dup 2)
16099         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16100    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16101    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16102    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16103    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16104    (parallel [(set (match_dup 8)
16105                    (unspec:XF [(match_dup 7) (match_dup 5)]
16106                               UNSPEC_FSCALE_FRACT))
16107                    (set (match_dup 9)
16108                    (unspec:XF [(match_dup 7) (match_dup 5)]
16109                               UNSPEC_FSCALE_EXP))])
16110    (parallel [(set (match_dup 11)
16111                    (unspec:XF [(match_dup 10) (match_dup 9)]
16112                               UNSPEC_FSCALE_FRACT))
16113               (set (match_dup 12)
16114                    (unspec:XF [(match_dup 10) (match_dup 9)]
16115                               UNSPEC_FSCALE_EXP))])
16116    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16117    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16118    (set (match_operand:DF 0 "register_operand" "")
16119         (float_truncate:DF (match_dup 14)))]
16120   "TARGET_USE_FANCY_MATH_387
16121    && flag_unsafe_math_optimizations"
16122 {
16123   rtx temp;
16124   int i;
16125
16126   for (i=2; i<15; i++)
16127     operands[i] = gen_reg_rtx (XFmode);
16128   temp = standard_80387_constant_rtx (5); /* fldl2e */
16129   emit_move_insn (operands[3], temp);
16130   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16131 })
16132
16133 (define_expand "expm1sf2"
16134   [(set (match_dup 2)
16135         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16136    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16137    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16138    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16139    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16140    (parallel [(set (match_dup 8)
16141                    (unspec:XF [(match_dup 7) (match_dup 5)]
16142                               UNSPEC_FSCALE_FRACT))
16143                    (set (match_dup 9)
16144                    (unspec:XF [(match_dup 7) (match_dup 5)]
16145                               UNSPEC_FSCALE_EXP))])
16146    (parallel [(set (match_dup 11)
16147                    (unspec:XF [(match_dup 10) (match_dup 9)]
16148                               UNSPEC_FSCALE_FRACT))
16149               (set (match_dup 12)
16150                    (unspec:XF [(match_dup 10) (match_dup 9)]
16151                               UNSPEC_FSCALE_EXP))])
16152    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16153    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16154    (set (match_operand:SF 0 "register_operand" "")
16155         (float_truncate:SF (match_dup 14)))]
16156   "TARGET_USE_FANCY_MATH_387
16157    && flag_unsafe_math_optimizations"
16158 {
16159   rtx temp;
16160   int i;
16161
16162   for (i=2; i<15; i++)
16163     operands[i] = gen_reg_rtx (XFmode);
16164   temp = standard_80387_constant_rtx (5); /* fldl2e */
16165   emit_move_insn (operands[3], temp);
16166   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16167 })
16168
16169 (define_expand "expm1xf2"
16170   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16171                                (match_dup 2)))
16172    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16173    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16174    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16175    (parallel [(set (match_dup 7)
16176                    (unspec:XF [(match_dup 6) (match_dup 4)]
16177                               UNSPEC_FSCALE_FRACT))
16178                    (set (match_dup 8)
16179                    (unspec:XF [(match_dup 6) (match_dup 4)]
16180                               UNSPEC_FSCALE_EXP))])
16181    (parallel [(set (match_dup 10)
16182                    (unspec:XF [(match_dup 9) (match_dup 8)]
16183                               UNSPEC_FSCALE_FRACT))
16184               (set (match_dup 11)
16185                    (unspec:XF [(match_dup 9) (match_dup 8)]
16186                               UNSPEC_FSCALE_EXP))])
16187    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16188    (set (match_operand:XF 0 "register_operand" "")
16189         (plus:XF (match_dup 12) (match_dup 7)))]
16190   "TARGET_USE_FANCY_MATH_387
16191    && flag_unsafe_math_optimizations"
16192 {
16193   rtx temp;
16194   int i;
16195
16196   for (i=2; i<13; i++)
16197     operands[i] = gen_reg_rtx (XFmode);
16198   temp = standard_80387_constant_rtx (5); /* fldl2e */
16199   emit_move_insn (operands[2], temp);
16200   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16201 })
16202 \f
16203
16204 (define_insn "frndintxf2"
16205   [(set (match_operand:XF 0 "register_operand" "=f")
16206         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16207          UNSPEC_FRNDINT))]
16208   "TARGET_USE_FANCY_MATH_387
16209    && flag_unsafe_math_optimizations"
16210   "frndint"
16211   [(set_attr "type" "fpspc")
16212    (set_attr "mode" "XF")])
16213
16214 (define_expand "rintdf2"
16215   [(use (match_operand:DF 0 "register_operand" ""))
16216    (use (match_operand:DF 1 "register_operand" ""))]
16217   "TARGET_USE_FANCY_MATH_387
16218    && flag_unsafe_math_optimizations"
16219 {
16220   rtx op0 = gen_reg_rtx (XFmode);
16221   rtx op1 = gen_reg_rtx (XFmode);
16222
16223   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16224   emit_insn (gen_frndintxf2 (op0, op1));
16225
16226   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16227   DONE;
16228 })
16229
16230 (define_expand "rintsf2"
16231   [(use (match_operand:SF 0 "register_operand" ""))
16232    (use (match_operand:SF 1 "register_operand" ""))]
16233   "TARGET_USE_FANCY_MATH_387
16234    && flag_unsafe_math_optimizations"
16235 {
16236   rtx op0 = gen_reg_rtx (XFmode);
16237   rtx op1 = gen_reg_rtx (XFmode);
16238
16239   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16240   emit_insn (gen_frndintxf2 (op0, op1));
16241
16242   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16243   DONE;
16244 })
16245
16246 (define_expand "rintxf2"
16247   [(use (match_operand:XF 0 "register_operand" ""))
16248    (use (match_operand:XF 1 "register_operand" ""))]
16249   "TARGET_USE_FANCY_MATH_387
16250    && flag_unsafe_math_optimizations"
16251 {
16252   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16253   DONE;
16254 })
16255
16256 (define_insn "frndintxf2_floor"
16257   [(set (match_operand:XF 0 "register_operand" "=f")
16258         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16259          UNSPEC_FRNDINT_FLOOR))
16260    (use (match_operand:HI 2 "memory_operand" "m"))
16261    (use (match_operand:HI 3 "memory_operand" "m"))]
16262   "TARGET_USE_FANCY_MATH_387
16263    && flag_unsafe_math_optimizations"
16264   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16265   [(set_attr "type" "frndint")
16266    (set_attr "i387_cw" "floor")
16267    (set_attr "mode" "XF")])
16268
16269 (define_expand "floordf2"
16270   [(use (match_operand:DF 0 "register_operand" ""))
16271    (use (match_operand:DF 1 "register_operand" ""))]
16272   "TARGET_USE_FANCY_MATH_387
16273    && flag_unsafe_math_optimizations"
16274 {
16275   rtx op0 = gen_reg_rtx (XFmode);
16276   rtx op1 = gen_reg_rtx (XFmode);
16277   rtx op2 = assign_386_stack_local (HImode, 1);
16278   rtx op3 = assign_386_stack_local (HImode, 2);
16279         
16280   ix86_optimize_mode_switching = 1;
16281
16282   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16283   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16284
16285   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16286   DONE;
16287 })
16288
16289 (define_expand "floorsf2"
16290   [(use (match_operand:SF 0 "register_operand" ""))
16291    (use (match_operand:SF 1 "register_operand" ""))]
16292   "TARGET_USE_FANCY_MATH_387
16293    && flag_unsafe_math_optimizations"
16294 {
16295   rtx op0 = gen_reg_rtx (XFmode);
16296   rtx op1 = gen_reg_rtx (XFmode);
16297   rtx op2 = assign_386_stack_local (HImode, 1);
16298   rtx op3 = assign_386_stack_local (HImode, 2);
16299         
16300   ix86_optimize_mode_switching = 1;
16301
16302   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16303   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16304
16305   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16306   DONE;
16307 })
16308
16309 (define_expand "floorxf2"
16310   [(use (match_operand:XF 0 "register_operand" ""))
16311    (use (match_operand:XF 1 "register_operand" ""))]
16312   "TARGET_USE_FANCY_MATH_387
16313    && flag_unsafe_math_optimizations"
16314 {
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_frndintxf2_floor (operands[0], operands[1], op2, op3));
16321   DONE;
16322 })
16323
16324 (define_insn "frndintxf2_ceil"
16325   [(set (match_operand:XF 0 "register_operand" "=f")
16326         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16327          UNSPEC_FRNDINT_CEIL))
16328    (use (match_operand:HI 2 "memory_operand" "m"))
16329    (use (match_operand:HI 3 "memory_operand" "m"))]
16330   "TARGET_USE_FANCY_MATH_387
16331    && flag_unsafe_math_optimizations"
16332   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16333   [(set_attr "type" "frndint")
16334    (set_attr "i387_cw" "ceil")
16335    (set_attr "mode" "XF")])
16336
16337 (define_expand "ceildf2"
16338   [(use (match_operand:DF 0 "register_operand" ""))
16339    (use (match_operand:DF 1 "register_operand" ""))]
16340   "TARGET_USE_FANCY_MATH_387
16341    && flag_unsafe_math_optimizations"
16342 {
16343   rtx op0 = gen_reg_rtx (XFmode);
16344   rtx op1 = gen_reg_rtx (XFmode);
16345   rtx op2 = assign_386_stack_local (HImode, 1);
16346   rtx op3 = assign_386_stack_local (HImode, 2);
16347         
16348   ix86_optimize_mode_switching = 1;
16349
16350   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16351   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16352
16353   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16354   DONE;
16355 })
16356
16357 (define_expand "ceilsf2"
16358   [(use (match_operand:SF 0 "register_operand" ""))
16359    (use (match_operand:SF 1 "register_operand" ""))]
16360   "TARGET_USE_FANCY_MATH_387
16361    && flag_unsafe_math_optimizations"
16362 {
16363   rtx op0 = gen_reg_rtx (XFmode);
16364   rtx op1 = gen_reg_rtx (XFmode);
16365   rtx op2 = assign_386_stack_local (HImode, 1);
16366   rtx op3 = assign_386_stack_local (HImode, 2);
16367         
16368   ix86_optimize_mode_switching = 1;
16369
16370   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16371   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16372
16373   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16374   DONE;
16375 })
16376
16377 (define_expand "ceilxf2"
16378   [(use (match_operand:XF 0 "register_operand" ""))
16379    (use (match_operand:XF 1 "register_operand" ""))]
16380   "TARGET_USE_FANCY_MATH_387
16381    && flag_unsafe_math_optimizations"
16382 {
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_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16389   DONE;
16390 })
16391
16392 (define_insn "frndintxf2_trunc"
16393   [(set (match_operand:XF 0 "register_operand" "=f")
16394         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16395          UNSPEC_FRNDINT_TRUNC))
16396    (use (match_operand:HI 2 "memory_operand" "m"))
16397    (use (match_operand:HI 3 "memory_operand" "m"))]
16398   "TARGET_USE_FANCY_MATH_387
16399    && flag_unsafe_math_optimizations"
16400   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16401   [(set_attr "type" "frndint")
16402    (set_attr "i387_cw" "trunc")
16403    (set_attr "mode" "XF")])
16404
16405 (define_expand "btruncdf2"
16406   [(use (match_operand:DF 0 "register_operand" ""))
16407    (use (match_operand:DF 1 "register_operand" ""))]
16408   "TARGET_USE_FANCY_MATH_387
16409    && flag_unsafe_math_optimizations"
16410 {
16411   rtx op0 = gen_reg_rtx (XFmode);
16412   rtx op1 = gen_reg_rtx (XFmode);
16413   rtx op2 = assign_386_stack_local (HImode, 1);
16414   rtx op3 = assign_386_stack_local (HImode, 2);
16415         
16416   ix86_optimize_mode_switching = 1;
16417
16418   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16419   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16420
16421   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16422   DONE;
16423 })
16424
16425 (define_expand "btruncsf2"
16426   [(use (match_operand:SF 0 "register_operand" ""))
16427    (use (match_operand:SF 1 "register_operand" ""))]
16428   "TARGET_USE_FANCY_MATH_387
16429    && flag_unsafe_math_optimizations"
16430 {
16431   rtx op0 = gen_reg_rtx (XFmode);
16432   rtx op1 = gen_reg_rtx (XFmode);
16433   rtx op2 = assign_386_stack_local (HImode, 1);
16434   rtx op3 = assign_386_stack_local (HImode, 2);
16435         
16436   ix86_optimize_mode_switching = 1;
16437
16438   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16439   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16440
16441   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16442   DONE;
16443 })
16444
16445 (define_expand "btruncxf2"
16446   [(use (match_operand:XF 0 "register_operand" ""))
16447    (use (match_operand:XF 1 "register_operand" ""))]
16448   "TARGET_USE_FANCY_MATH_387
16449    && flag_unsafe_math_optimizations"
16450 {
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_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16457   DONE;
16458 })
16459
16460 (define_insn "frndintxf2_mask_pm"
16461   [(set (match_operand:XF 0 "register_operand" "=f")
16462         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16463          UNSPEC_FRNDINT_MASK_PM))
16464    (use (match_operand:HI 2 "memory_operand" "m"))
16465    (use (match_operand:HI 3 "memory_operand" "m"))]
16466   "TARGET_USE_FANCY_MATH_387
16467    && flag_unsafe_math_optimizations"
16468   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16469   [(set_attr "type" "frndint")
16470    (set_attr "i387_cw" "mask_pm")
16471    (set_attr "mode" "XF")])
16472
16473 (define_expand "nearbyintdf2"
16474   [(use (match_operand:DF 0 "register_operand" ""))
16475    (use (match_operand:DF 1 "register_operand" ""))]
16476   "TARGET_USE_FANCY_MATH_387
16477    && flag_unsafe_math_optimizations"
16478 {
16479   rtx op0 = gen_reg_rtx (XFmode);
16480   rtx op1 = gen_reg_rtx (XFmode);
16481   rtx op2 = assign_386_stack_local (HImode, 1);
16482   rtx op3 = assign_386_stack_local (HImode, 2);
16483         
16484   ix86_optimize_mode_switching = 1;
16485
16486   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16487   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16488
16489   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16490   DONE;
16491 })
16492
16493 (define_expand "nearbyintsf2"
16494   [(use (match_operand:SF 0 "register_operand" ""))
16495    (use (match_operand:SF 1 "register_operand" ""))]
16496   "TARGET_USE_FANCY_MATH_387
16497    && flag_unsafe_math_optimizations"
16498 {
16499   rtx op0 = gen_reg_rtx (XFmode);
16500   rtx op1 = gen_reg_rtx (XFmode);
16501   rtx op2 = assign_386_stack_local (HImode, 1);
16502   rtx op3 = assign_386_stack_local (HImode, 2);
16503         
16504   ix86_optimize_mode_switching = 1;
16505
16506   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16507   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16508
16509   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16510   DONE;
16511 })
16512
16513 (define_expand "nearbyintxf2"
16514   [(use (match_operand:XF 0 "register_operand" ""))
16515    (use (match_operand:XF 1 "register_operand" ""))]
16516   "TARGET_USE_FANCY_MATH_387
16517    && flag_unsafe_math_optimizations"
16518 {
16519   rtx op2 = assign_386_stack_local (HImode, 1);
16520   rtx op3 = assign_386_stack_local (HImode, 2);
16521         
16522   ix86_optimize_mode_switching = 1;
16523
16524   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16525                                      op2, op3));
16526   DONE;
16527 })
16528
16529 \f
16530 ;; Block operation instructions
16531
16532 (define_insn "cld"
16533  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16534  ""
16535  "cld"
16536   [(set_attr "type" "cld")])
16537
16538 (define_expand "movmemsi"
16539   [(use (match_operand:BLK 0 "memory_operand" ""))
16540    (use (match_operand:BLK 1 "memory_operand" ""))
16541    (use (match_operand:SI 2 "nonmemory_operand" ""))
16542    (use (match_operand:SI 3 "const_int_operand" ""))]
16543   "! optimize_size"
16544 {
16545  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16546    DONE;
16547  else
16548    FAIL;
16549 })
16550
16551 (define_expand "movmemdi"
16552   [(use (match_operand:BLK 0 "memory_operand" ""))
16553    (use (match_operand:BLK 1 "memory_operand" ""))
16554    (use (match_operand:DI 2 "nonmemory_operand" ""))
16555    (use (match_operand:DI 3 "const_int_operand" ""))]
16556   "TARGET_64BIT"
16557 {
16558  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16559    DONE;
16560  else
16561    FAIL;
16562 })
16563
16564 ;; Most CPUs don't like single string operations
16565 ;; Handle this case here to simplify previous expander.
16566
16567 (define_expand "strmov"
16568   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16569    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16570    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16571               (clobber (reg:CC FLAGS_REG))])
16572    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16573               (clobber (reg:CC FLAGS_REG))])]
16574   ""
16575 {
16576   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16577
16578   /* If .md ever supports :P for Pmode, these can be directly
16579      in the pattern above.  */
16580   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16581   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16582
16583   if (TARGET_SINGLE_STRINGOP || optimize_size)
16584     {
16585       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16586                                       operands[2], operands[3],
16587                                       operands[5], operands[6]));
16588       DONE;
16589     }
16590
16591   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16592 })
16593
16594 (define_expand "strmov_singleop"
16595   [(parallel [(set (match_operand 1 "memory_operand" "")
16596                    (match_operand 3 "memory_operand" ""))
16597               (set (match_operand 0 "register_operand" "")
16598                    (match_operand 4 "" ""))
16599               (set (match_operand 2 "register_operand" "")
16600                    (match_operand 5 "" ""))
16601               (use (reg:SI DIRFLAG_REG))])]
16602   "TARGET_SINGLE_STRINGOP || optimize_size"
16603   "")
16604
16605 (define_insn "*strmovdi_rex_1"
16606   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16607         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16608    (set (match_operand:DI 0 "register_operand" "=D")
16609         (plus:DI (match_dup 2)
16610                  (const_int 8)))
16611    (set (match_operand:DI 1 "register_operand" "=S")
16612         (plus:DI (match_dup 3)
16613                  (const_int 8)))
16614    (use (reg:SI DIRFLAG_REG))]
16615   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16616   "movsq"
16617   [(set_attr "type" "str")
16618    (set_attr "mode" "DI")
16619    (set_attr "memory" "both")])
16620
16621 (define_insn "*strmovsi_1"
16622   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16623         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16624    (set (match_operand:SI 0 "register_operand" "=D")
16625         (plus:SI (match_dup 2)
16626                  (const_int 4)))
16627    (set (match_operand:SI 1 "register_operand" "=S")
16628         (plus:SI (match_dup 3)
16629                  (const_int 4)))
16630    (use (reg:SI DIRFLAG_REG))]
16631   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16632   "{movsl|movsd}"
16633   [(set_attr "type" "str")
16634    (set_attr "mode" "SI")
16635    (set_attr "memory" "both")])
16636
16637 (define_insn "*strmovsi_rex_1"
16638   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16639         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16640    (set (match_operand:DI 0 "register_operand" "=D")
16641         (plus:DI (match_dup 2)
16642                  (const_int 4)))
16643    (set (match_operand:DI 1 "register_operand" "=S")
16644         (plus:DI (match_dup 3)
16645                  (const_int 4)))
16646    (use (reg:SI DIRFLAG_REG))]
16647   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16648   "{movsl|movsd}"
16649   [(set_attr "type" "str")
16650    (set_attr "mode" "SI")
16651    (set_attr "memory" "both")])
16652
16653 (define_insn "*strmovhi_1"
16654   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16655         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16656    (set (match_operand:SI 0 "register_operand" "=D")
16657         (plus:SI (match_dup 2)
16658                  (const_int 2)))
16659    (set (match_operand:SI 1 "register_operand" "=S")
16660         (plus:SI (match_dup 3)
16661                  (const_int 2)))
16662    (use (reg:SI DIRFLAG_REG))]
16663   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16664   "movsw"
16665   [(set_attr "type" "str")
16666    (set_attr "memory" "both")
16667    (set_attr "mode" "HI")])
16668
16669 (define_insn "*strmovhi_rex_1"
16670   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16671         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16672    (set (match_operand:DI 0 "register_operand" "=D")
16673         (plus:DI (match_dup 2)
16674                  (const_int 2)))
16675    (set (match_operand:DI 1 "register_operand" "=S")
16676         (plus:DI (match_dup 3)
16677                  (const_int 2)))
16678    (use (reg:SI DIRFLAG_REG))]
16679   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16680   "movsw"
16681   [(set_attr "type" "str")
16682    (set_attr "memory" "both")
16683    (set_attr "mode" "HI")])
16684
16685 (define_insn "*strmovqi_1"
16686   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16687         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16688    (set (match_operand:SI 0 "register_operand" "=D")
16689         (plus:SI (match_dup 2)
16690                  (const_int 1)))
16691    (set (match_operand:SI 1 "register_operand" "=S")
16692         (plus:SI (match_dup 3)
16693                  (const_int 1)))
16694    (use (reg:SI DIRFLAG_REG))]
16695   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16696   "movsb"
16697   [(set_attr "type" "str")
16698    (set_attr "memory" "both")
16699    (set_attr "mode" "QI")])
16700
16701 (define_insn "*strmovqi_rex_1"
16702   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16703         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16704    (set (match_operand:DI 0 "register_operand" "=D")
16705         (plus:DI (match_dup 2)
16706                  (const_int 1)))
16707    (set (match_operand:DI 1 "register_operand" "=S")
16708         (plus:DI (match_dup 3)
16709                  (const_int 1)))
16710    (use (reg:SI DIRFLAG_REG))]
16711   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16712   "movsb"
16713   [(set_attr "type" "str")
16714    (set_attr "memory" "both")
16715    (set_attr "mode" "QI")])
16716
16717 (define_expand "rep_mov"
16718   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16719               (set (match_operand 0 "register_operand" "")
16720                    (match_operand 5 "" ""))
16721               (set (match_operand 2 "register_operand" "")
16722                    (match_operand 6 "" ""))
16723               (set (match_operand 1 "memory_operand" "")
16724                    (match_operand 3 "memory_operand" ""))
16725               (use (match_dup 4))
16726               (use (reg:SI DIRFLAG_REG))])]
16727   ""
16728   "")
16729
16730 (define_insn "*rep_movdi_rex64"
16731   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16732    (set (match_operand:DI 0 "register_operand" "=D") 
16733         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16734                             (const_int 3))
16735                  (match_operand:DI 3 "register_operand" "0")))
16736    (set (match_operand:DI 1 "register_operand" "=S") 
16737         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16738                  (match_operand:DI 4 "register_operand" "1")))
16739    (set (mem:BLK (match_dup 3))
16740         (mem:BLK (match_dup 4)))
16741    (use (match_dup 5))
16742    (use (reg:SI DIRFLAG_REG))]
16743   "TARGET_64BIT"
16744   "{rep\;movsq|rep movsq}"
16745   [(set_attr "type" "str")
16746    (set_attr "prefix_rep" "1")
16747    (set_attr "memory" "both")
16748    (set_attr "mode" "DI")])
16749
16750 (define_insn "*rep_movsi"
16751   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16752    (set (match_operand:SI 0 "register_operand" "=D") 
16753         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16754                             (const_int 2))
16755                  (match_operand:SI 3 "register_operand" "0")))
16756    (set (match_operand:SI 1 "register_operand" "=S") 
16757         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16758                  (match_operand:SI 4 "register_operand" "1")))
16759    (set (mem:BLK (match_dup 3))
16760         (mem:BLK (match_dup 4)))
16761    (use (match_dup 5))
16762    (use (reg:SI DIRFLAG_REG))]
16763   "!TARGET_64BIT"
16764   "{rep\;movsl|rep movsd}"
16765   [(set_attr "type" "str")
16766    (set_attr "prefix_rep" "1")
16767    (set_attr "memory" "both")
16768    (set_attr "mode" "SI")])
16769
16770 (define_insn "*rep_movsi_rex64"
16771   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16772    (set (match_operand:DI 0 "register_operand" "=D") 
16773         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16774                             (const_int 2))
16775                  (match_operand:DI 3 "register_operand" "0")))
16776    (set (match_operand:DI 1 "register_operand" "=S") 
16777         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16778                  (match_operand:DI 4 "register_operand" "1")))
16779    (set (mem:BLK (match_dup 3))
16780         (mem:BLK (match_dup 4)))
16781    (use (match_dup 5))
16782    (use (reg:SI DIRFLAG_REG))]
16783   "TARGET_64BIT"
16784   "{rep\;movsl|rep movsd}"
16785   [(set_attr "type" "str")
16786    (set_attr "prefix_rep" "1")
16787    (set_attr "memory" "both")
16788    (set_attr "mode" "SI")])
16789
16790 (define_insn "*rep_movqi"
16791   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16792    (set (match_operand:SI 0 "register_operand" "=D") 
16793         (plus:SI (match_operand:SI 3 "register_operand" "0")
16794                  (match_operand:SI 5 "register_operand" "2")))
16795    (set (match_operand:SI 1 "register_operand" "=S") 
16796         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16797    (set (mem:BLK (match_dup 3))
16798         (mem:BLK (match_dup 4)))
16799    (use (match_dup 5))
16800    (use (reg:SI DIRFLAG_REG))]
16801   "!TARGET_64BIT"
16802   "{rep\;movsb|rep movsb}"
16803   [(set_attr "type" "str")
16804    (set_attr "prefix_rep" "1")
16805    (set_attr "memory" "both")
16806    (set_attr "mode" "SI")])
16807
16808 (define_insn "*rep_movqi_rex64"
16809   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16810    (set (match_operand:DI 0 "register_operand" "=D") 
16811         (plus:DI (match_operand:DI 3 "register_operand" "0")
16812                  (match_operand:DI 5 "register_operand" "2")))
16813    (set (match_operand:DI 1 "register_operand" "=S") 
16814         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16815    (set (mem:BLK (match_dup 3))
16816         (mem:BLK (match_dup 4)))
16817    (use (match_dup 5))
16818    (use (reg:SI DIRFLAG_REG))]
16819   "TARGET_64BIT"
16820   "{rep\;movsb|rep movsb}"
16821   [(set_attr "type" "str")
16822    (set_attr "prefix_rep" "1")
16823    (set_attr "memory" "both")
16824    (set_attr "mode" "SI")])
16825
16826 (define_expand "clrmemsi"
16827    [(use (match_operand:BLK 0 "memory_operand" ""))
16828     (use (match_operand:SI 1 "nonmemory_operand" ""))
16829     (use (match_operand 2 "const_int_operand" ""))]
16830   ""
16831 {
16832  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16833    DONE;
16834  else
16835    FAIL;
16836 })
16837
16838 (define_expand "clrmemdi"
16839    [(use (match_operand:BLK 0 "memory_operand" ""))
16840     (use (match_operand:DI 1 "nonmemory_operand" ""))
16841     (use (match_operand 2 "const_int_operand" ""))]
16842   "TARGET_64BIT"
16843 {
16844  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16845    DONE;
16846  else
16847    FAIL;
16848 })
16849
16850 ;; Most CPUs don't like single string operations
16851 ;; Handle this case here to simplify previous expander.
16852
16853 (define_expand "strset"
16854   [(set (match_operand 1 "memory_operand" "")
16855         (match_operand 2 "register_operand" ""))
16856    (parallel [(set (match_operand 0 "register_operand" "")
16857                    (match_dup 3))
16858               (clobber (reg:CC FLAGS_REG))])]
16859   ""
16860 {
16861   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16862     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16863
16864   /* If .md ever supports :P for Pmode, this can be directly
16865      in the pattern above.  */
16866   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16867                               GEN_INT (GET_MODE_SIZE (GET_MODE
16868                                                       (operands[2]))));
16869   if (TARGET_SINGLE_STRINGOP || optimize_size)
16870     {
16871       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16872                                       operands[3]));
16873       DONE;
16874     }
16875 })
16876
16877 (define_expand "strset_singleop"
16878   [(parallel [(set (match_operand 1 "memory_operand" "")
16879                    (match_operand 2 "register_operand" ""))
16880               (set (match_operand 0 "register_operand" "")
16881                    (match_operand 3 "" ""))
16882               (use (reg:SI DIRFLAG_REG))])]
16883   "TARGET_SINGLE_STRINGOP || optimize_size"
16884   "")
16885
16886 (define_insn "*strsetdi_rex_1"
16887   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16888         (match_operand:DI 2 "register_operand" "a"))
16889    (set (match_operand:DI 0 "register_operand" "=D")
16890         (plus:DI (match_dup 1)
16891                  (const_int 8)))
16892    (use (reg:SI DIRFLAG_REG))]
16893   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16894   "stosq"
16895   [(set_attr "type" "str")
16896    (set_attr "memory" "store")
16897    (set_attr "mode" "DI")])
16898
16899 (define_insn "*strsetsi_1"
16900   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16901         (match_operand:SI 2 "register_operand" "a"))
16902    (set (match_operand:SI 0 "register_operand" "=D")
16903         (plus:SI (match_dup 1)
16904                  (const_int 4)))
16905    (use (reg:SI DIRFLAG_REG))]
16906   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16907   "{stosl|stosd}"
16908   [(set_attr "type" "str")
16909    (set_attr "memory" "store")
16910    (set_attr "mode" "SI")])
16911
16912 (define_insn "*strsetsi_rex_1"
16913   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16914         (match_operand:SI 2 "register_operand" "a"))
16915    (set (match_operand:DI 0 "register_operand" "=D")
16916         (plus:DI (match_dup 1)
16917                  (const_int 4)))
16918    (use (reg:SI DIRFLAG_REG))]
16919   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16920   "{stosl|stosd}"
16921   [(set_attr "type" "str")
16922    (set_attr "memory" "store")
16923    (set_attr "mode" "SI")])
16924
16925 (define_insn "*strsethi_1"
16926   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16927         (match_operand:HI 2 "register_operand" "a"))
16928    (set (match_operand:SI 0 "register_operand" "=D")
16929         (plus:SI (match_dup 1)
16930                  (const_int 2)))
16931    (use (reg:SI DIRFLAG_REG))]
16932   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16933   "stosw"
16934   [(set_attr "type" "str")
16935    (set_attr "memory" "store")
16936    (set_attr "mode" "HI")])
16937
16938 (define_insn "*strsethi_rex_1"
16939   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16940         (match_operand:HI 2 "register_operand" "a"))
16941    (set (match_operand:DI 0 "register_operand" "=D")
16942         (plus:DI (match_dup 1)
16943                  (const_int 2)))
16944    (use (reg:SI DIRFLAG_REG))]
16945   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16946   "stosw"
16947   [(set_attr "type" "str")
16948    (set_attr "memory" "store")
16949    (set_attr "mode" "HI")])
16950
16951 (define_insn "*strsetqi_1"
16952   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16953         (match_operand:QI 2 "register_operand" "a"))
16954    (set (match_operand:SI 0 "register_operand" "=D")
16955         (plus:SI (match_dup 1)
16956                  (const_int 1)))
16957    (use (reg:SI DIRFLAG_REG))]
16958   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16959   "stosb"
16960   [(set_attr "type" "str")
16961    (set_attr "memory" "store")
16962    (set_attr "mode" "QI")])
16963
16964 (define_insn "*strsetqi_rex_1"
16965   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16966         (match_operand:QI 2 "register_operand" "a"))
16967    (set (match_operand:DI 0 "register_operand" "=D")
16968         (plus:DI (match_dup 1)
16969                  (const_int 1)))
16970    (use (reg:SI DIRFLAG_REG))]
16971   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16972   "stosb"
16973   [(set_attr "type" "str")
16974    (set_attr "memory" "store")
16975    (set_attr "mode" "QI")])
16976
16977 (define_expand "rep_stos"
16978   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16979               (set (match_operand 0 "register_operand" "")
16980                    (match_operand 4 "" ""))
16981               (set (match_operand 2 "memory_operand" "") (const_int 0))
16982               (use (match_operand 3 "register_operand" ""))
16983               (use (match_dup 1))
16984               (use (reg:SI DIRFLAG_REG))])]
16985   ""
16986   "")
16987
16988 (define_insn "*rep_stosdi_rex64"
16989   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16990    (set (match_operand:DI 0 "register_operand" "=D") 
16991         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16992                             (const_int 3))
16993                  (match_operand:DI 3 "register_operand" "0")))
16994    (set (mem:BLK (match_dup 3))
16995         (const_int 0))
16996    (use (match_operand:DI 2 "register_operand" "a"))
16997    (use (match_dup 4))
16998    (use (reg:SI DIRFLAG_REG))]
16999   "TARGET_64BIT"
17000   "{rep\;stosq|rep stosq}"
17001   [(set_attr "type" "str")
17002    (set_attr "prefix_rep" "1")
17003    (set_attr "memory" "store")
17004    (set_attr "mode" "DI")])
17005
17006 (define_insn "*rep_stossi"
17007   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17008    (set (match_operand:SI 0 "register_operand" "=D") 
17009         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17010                             (const_int 2))
17011                  (match_operand:SI 3 "register_operand" "0")))
17012    (set (mem:BLK (match_dup 3))
17013         (const_int 0))
17014    (use (match_operand:SI 2 "register_operand" "a"))
17015    (use (match_dup 4))
17016    (use (reg:SI DIRFLAG_REG))]
17017   "!TARGET_64BIT"
17018   "{rep\;stosl|rep stosd}"
17019   [(set_attr "type" "str")
17020    (set_attr "prefix_rep" "1")
17021    (set_attr "memory" "store")
17022    (set_attr "mode" "SI")])
17023
17024 (define_insn "*rep_stossi_rex64"
17025   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17026    (set (match_operand:DI 0 "register_operand" "=D") 
17027         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17028                             (const_int 2))
17029                  (match_operand:DI 3 "register_operand" "0")))
17030    (set (mem:BLK (match_dup 3))
17031         (const_int 0))
17032    (use (match_operand:SI 2 "register_operand" "a"))
17033    (use (match_dup 4))
17034    (use (reg:SI DIRFLAG_REG))]
17035   "TARGET_64BIT"
17036   "{rep\;stosl|rep stosd}"
17037   [(set_attr "type" "str")
17038    (set_attr "prefix_rep" "1")
17039    (set_attr "memory" "store")
17040    (set_attr "mode" "SI")])
17041
17042 (define_insn "*rep_stosqi"
17043   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17044    (set (match_operand:SI 0 "register_operand" "=D") 
17045         (plus:SI (match_operand:SI 3 "register_operand" "0")
17046                  (match_operand:SI 4 "register_operand" "1")))
17047    (set (mem:BLK (match_dup 3))
17048         (const_int 0))
17049    (use (match_operand:QI 2 "register_operand" "a"))
17050    (use (match_dup 4))
17051    (use (reg:SI DIRFLAG_REG))]
17052   "!TARGET_64BIT"
17053   "{rep\;stosb|rep stosb}"
17054   [(set_attr "type" "str")
17055    (set_attr "prefix_rep" "1")
17056    (set_attr "memory" "store")
17057    (set_attr "mode" "QI")])
17058
17059 (define_insn "*rep_stosqi_rex64"
17060   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17061    (set (match_operand:DI 0 "register_operand" "=D") 
17062         (plus:DI (match_operand:DI 3 "register_operand" "0")
17063                  (match_operand:DI 4 "register_operand" "1")))
17064    (set (mem:BLK (match_dup 3))
17065         (const_int 0))
17066    (use (match_operand:QI 2 "register_operand" "a"))
17067    (use (match_dup 4))
17068    (use (reg:SI DIRFLAG_REG))]
17069   "TARGET_64BIT"
17070   "{rep\;stosb|rep stosb}"
17071   [(set_attr "type" "str")
17072    (set_attr "prefix_rep" "1")
17073    (set_attr "memory" "store")
17074    (set_attr "mode" "QI")])
17075
17076 (define_expand "cmpstrsi"
17077   [(set (match_operand:SI 0 "register_operand" "")
17078         (compare:SI (match_operand:BLK 1 "general_operand" "")
17079                     (match_operand:BLK 2 "general_operand" "")))
17080    (use (match_operand 3 "general_operand" ""))
17081    (use (match_operand 4 "immediate_operand" ""))]
17082   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17083 {
17084   rtx addr1, addr2, out, outlow, count, countreg, align;
17085
17086   /* Can't use this if the user has appropriated esi or edi.  */
17087   if (global_regs[4] || global_regs[5])
17088     FAIL;
17089
17090   out = operands[0];
17091   if (GET_CODE (out) != REG)
17092     out = gen_reg_rtx (SImode);
17093
17094   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17095   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17096   if (addr1 != XEXP (operands[1], 0))
17097     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17098   if (addr2 != XEXP (operands[2], 0))
17099     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17100
17101   count = operands[3];
17102   countreg = ix86_zero_extend_to_Pmode (count);
17103
17104   /* %%% Iff we are testing strict equality, we can use known alignment
17105      to good advantage.  This may be possible with combine, particularly
17106      once cc0 is dead.  */
17107   align = operands[4];
17108
17109   emit_insn (gen_cld ());
17110   if (GET_CODE (count) == CONST_INT)
17111     {
17112       if (INTVAL (count) == 0)
17113         {
17114           emit_move_insn (operands[0], const0_rtx);
17115           DONE;
17116         }
17117       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17118                                     operands[1], operands[2]));
17119     }
17120   else
17121     {
17122       if (TARGET_64BIT)
17123         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17124       else
17125         emit_insn (gen_cmpsi_1 (countreg, countreg));
17126       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17127                                  operands[1], operands[2]));
17128     }
17129
17130   outlow = gen_lowpart (QImode, out);
17131   emit_insn (gen_cmpintqi (outlow));
17132   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17133
17134   if (operands[0] != out)
17135     emit_move_insn (operands[0], out);
17136
17137   DONE;
17138 })
17139
17140 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17141
17142 (define_expand "cmpintqi"
17143   [(set (match_dup 1)
17144         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17145    (set (match_dup 2)
17146         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17147    (parallel [(set (match_operand:QI 0 "register_operand" "")
17148                    (minus:QI (match_dup 1)
17149                              (match_dup 2)))
17150               (clobber (reg:CC FLAGS_REG))])]
17151   ""
17152   "operands[1] = gen_reg_rtx (QImode);
17153    operands[2] = gen_reg_rtx (QImode);")
17154
17155 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17156 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17157
17158 (define_expand "cmpstrqi_nz_1"
17159   [(parallel [(set (reg:CC FLAGS_REG)
17160                    (compare:CC (match_operand 4 "memory_operand" "")
17161                                (match_operand 5 "memory_operand" "")))
17162               (use (match_operand 2 "register_operand" ""))
17163               (use (match_operand:SI 3 "immediate_operand" ""))
17164               (use (reg:SI DIRFLAG_REG))
17165               (clobber (match_operand 0 "register_operand" ""))
17166               (clobber (match_operand 1 "register_operand" ""))
17167               (clobber (match_dup 2))])]
17168   ""
17169   "")
17170
17171 (define_insn "*cmpstrqi_nz_1"
17172   [(set (reg:CC FLAGS_REG)
17173         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17174                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17175    (use (match_operand:SI 6 "register_operand" "2"))
17176    (use (match_operand:SI 3 "immediate_operand" "i"))
17177    (use (reg:SI DIRFLAG_REG))
17178    (clobber (match_operand:SI 0 "register_operand" "=S"))
17179    (clobber (match_operand:SI 1 "register_operand" "=D"))
17180    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17181   "!TARGET_64BIT"
17182   "repz{\;| }cmpsb"
17183   [(set_attr "type" "str")
17184    (set_attr "mode" "QI")
17185    (set_attr "prefix_rep" "1")])
17186
17187 (define_insn "*cmpstrqi_nz_rex_1"
17188   [(set (reg:CC FLAGS_REG)
17189         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17190                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17191    (use (match_operand:DI 6 "register_operand" "2"))
17192    (use (match_operand:SI 3 "immediate_operand" "i"))
17193    (use (reg:SI DIRFLAG_REG))
17194    (clobber (match_operand:DI 0 "register_operand" "=S"))
17195    (clobber (match_operand:DI 1 "register_operand" "=D"))
17196    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17197   "TARGET_64BIT"
17198   "repz{\;| }cmpsb"
17199   [(set_attr "type" "str")
17200    (set_attr "mode" "QI")
17201    (set_attr "prefix_rep" "1")])
17202
17203 ;; The same, but the count is not known to not be zero.
17204
17205 (define_expand "cmpstrqi_1"
17206   [(parallel [(set (reg:CC FLAGS_REG)
17207                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17208                                      (const_int 0))
17209                   (compare:CC (match_operand 4 "memory_operand" "")
17210                               (match_operand 5 "memory_operand" ""))
17211                   (const_int 0)))
17212               (use (match_operand:SI 3 "immediate_operand" ""))
17213               (use (reg:CC FLAGS_REG))
17214               (use (reg:SI DIRFLAG_REG))
17215               (clobber (match_operand 0 "register_operand" ""))
17216               (clobber (match_operand 1 "register_operand" ""))
17217               (clobber (match_dup 2))])]
17218   ""
17219   "")
17220
17221 (define_insn "*cmpstrqi_1"
17222   [(set (reg:CC FLAGS_REG)
17223         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17224                              (const_int 0))
17225           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17226                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17227           (const_int 0)))
17228    (use (match_operand:SI 3 "immediate_operand" "i"))
17229    (use (reg:CC FLAGS_REG))
17230    (use (reg:SI DIRFLAG_REG))
17231    (clobber (match_operand:SI 0 "register_operand" "=S"))
17232    (clobber (match_operand:SI 1 "register_operand" "=D"))
17233    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17234   "!TARGET_64BIT"
17235   "repz{\;| }cmpsb"
17236   [(set_attr "type" "str")
17237    (set_attr "mode" "QI")
17238    (set_attr "prefix_rep" "1")])
17239
17240 (define_insn "*cmpstrqi_rex_1"
17241   [(set (reg:CC FLAGS_REG)
17242         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17243                              (const_int 0))
17244           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17245                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17246           (const_int 0)))
17247    (use (match_operand:SI 3 "immediate_operand" "i"))
17248    (use (reg:CC FLAGS_REG))
17249    (use (reg:SI DIRFLAG_REG))
17250    (clobber (match_operand:DI 0 "register_operand" "=S"))
17251    (clobber (match_operand:DI 1 "register_operand" "=D"))
17252    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17253   "TARGET_64BIT"
17254   "repz{\;| }cmpsb"
17255   [(set_attr "type" "str")
17256    (set_attr "mode" "QI")
17257    (set_attr "prefix_rep" "1")])
17258
17259 (define_expand "strlensi"
17260   [(set (match_operand:SI 0 "register_operand" "")
17261         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17262                     (match_operand:QI 2 "immediate_operand" "")
17263                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17264   ""
17265 {
17266  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17267    DONE;
17268  else
17269    FAIL;
17270 })
17271
17272 (define_expand "strlendi"
17273   [(set (match_operand:DI 0 "register_operand" "")
17274         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17275                     (match_operand:QI 2 "immediate_operand" "")
17276                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17277   ""
17278 {
17279  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17280    DONE;
17281  else
17282    FAIL;
17283 })
17284
17285 (define_expand "strlenqi_1"
17286   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17287               (use (reg:SI DIRFLAG_REG))
17288               (clobber (match_operand 1 "register_operand" ""))
17289               (clobber (reg:CC FLAGS_REG))])]
17290   ""
17291   "")
17292
17293 (define_insn "*strlenqi_1"
17294   [(set (match_operand:SI 0 "register_operand" "=&c")
17295         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17296                     (match_operand:QI 2 "register_operand" "a")
17297                     (match_operand:SI 3 "immediate_operand" "i")
17298                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17299    (use (reg:SI DIRFLAG_REG))
17300    (clobber (match_operand:SI 1 "register_operand" "=D"))
17301    (clobber (reg:CC FLAGS_REG))]
17302   "!TARGET_64BIT"
17303   "repnz{\;| }scasb"
17304   [(set_attr "type" "str")
17305    (set_attr "mode" "QI")
17306    (set_attr "prefix_rep" "1")])
17307
17308 (define_insn "*strlenqi_rex_1"
17309   [(set (match_operand:DI 0 "register_operand" "=&c")
17310         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17311                     (match_operand:QI 2 "register_operand" "a")
17312                     (match_operand:DI 3 "immediate_operand" "i")
17313                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17314    (use (reg:SI DIRFLAG_REG))
17315    (clobber (match_operand:DI 1 "register_operand" "=D"))
17316    (clobber (reg:CC FLAGS_REG))]
17317   "TARGET_64BIT"
17318   "repnz{\;| }scasb"
17319   [(set_attr "type" "str")
17320    (set_attr "mode" "QI")
17321    (set_attr "prefix_rep" "1")])
17322
17323 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17324 ;; handled in combine, but it is not currently up to the task.
17325 ;; When used for their truth value, the cmpstr* expanders generate
17326 ;; code like this:
17327 ;;
17328 ;;   repz cmpsb
17329 ;;   seta       %al
17330 ;;   setb       %dl
17331 ;;   cmpb       %al, %dl
17332 ;;   jcc        label
17333 ;;
17334 ;; The intermediate three instructions are unnecessary.
17335
17336 ;; This one handles cmpstr*_nz_1...
17337 (define_peephole2
17338   [(parallel[
17339      (set (reg:CC FLAGS_REG)
17340           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17341                       (mem:BLK (match_operand 5 "register_operand" ""))))
17342      (use (match_operand 6 "register_operand" ""))
17343      (use (match_operand:SI 3 "immediate_operand" ""))
17344      (use (reg:SI DIRFLAG_REG))
17345      (clobber (match_operand 0 "register_operand" ""))
17346      (clobber (match_operand 1 "register_operand" ""))
17347      (clobber (match_operand 2 "register_operand" ""))])
17348    (set (match_operand:QI 7 "register_operand" "")
17349         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17350    (set (match_operand:QI 8 "register_operand" "")
17351         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17352    (set (reg FLAGS_REG)
17353         (compare (match_dup 7) (match_dup 8)))
17354   ]
17355   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17356   [(parallel[
17357      (set (reg:CC FLAGS_REG)
17358           (compare:CC (mem:BLK (match_dup 4))
17359                       (mem:BLK (match_dup 5))))
17360      (use (match_dup 6))
17361      (use (match_dup 3))
17362      (use (reg:SI DIRFLAG_REG))
17363      (clobber (match_dup 0))
17364      (clobber (match_dup 1))
17365      (clobber (match_dup 2))])]
17366   "")
17367
17368 ;; ...and this one handles cmpstr*_1.
17369 (define_peephole2
17370   [(parallel[
17371      (set (reg:CC FLAGS_REG)
17372           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17373                                (const_int 0))
17374             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17375                         (mem:BLK (match_operand 5 "register_operand" "")))
17376             (const_int 0)))
17377      (use (match_operand:SI 3 "immediate_operand" ""))
17378      (use (reg:CC FLAGS_REG))
17379      (use (reg:SI DIRFLAG_REG))
17380      (clobber (match_operand 0 "register_operand" ""))
17381      (clobber (match_operand 1 "register_operand" ""))
17382      (clobber (match_operand 2 "register_operand" ""))])
17383    (set (match_operand:QI 7 "register_operand" "")
17384         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17385    (set (match_operand:QI 8 "register_operand" "")
17386         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17387    (set (reg FLAGS_REG)
17388         (compare (match_dup 7) (match_dup 8)))
17389   ]
17390   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17391   [(parallel[
17392      (set (reg:CC FLAGS_REG)
17393           (if_then_else:CC (ne (match_dup 6)
17394                                (const_int 0))
17395             (compare:CC (mem:BLK (match_dup 4))
17396                         (mem:BLK (match_dup 5)))
17397             (const_int 0)))
17398      (use (match_dup 3))
17399      (use (reg:CC FLAGS_REG))
17400      (use (reg:SI DIRFLAG_REG))
17401      (clobber (match_dup 0))
17402      (clobber (match_dup 1))
17403      (clobber (match_dup 2))])]
17404   "")
17405
17406
17407 \f
17408 ;; Conditional move instructions.
17409
17410 (define_expand "movdicc"
17411   [(set (match_operand:DI 0 "register_operand" "")
17412         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17413                          (match_operand:DI 2 "general_operand" "")
17414                          (match_operand:DI 3 "general_operand" "")))]
17415   "TARGET_64BIT"
17416   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17417
17418 (define_insn "x86_movdicc_0_m1_rex64"
17419   [(set (match_operand:DI 0 "register_operand" "=r")
17420         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17421           (const_int -1)
17422           (const_int 0)))
17423    (clobber (reg:CC FLAGS_REG))]
17424   "TARGET_64BIT"
17425   "sbb{q}\t%0, %0"
17426   ; Since we don't have the proper number of operands for an alu insn,
17427   ; fill in all the blanks.
17428   [(set_attr "type" "alu")
17429    (set_attr "pent_pair" "pu")
17430    (set_attr "memory" "none")
17431    (set_attr "imm_disp" "false")
17432    (set_attr "mode" "DI")
17433    (set_attr "length_immediate" "0")])
17434
17435 (define_insn "movdicc_c_rex64"
17436   [(set (match_operand:DI 0 "register_operand" "=r,r")
17437         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17438                                 [(reg FLAGS_REG) (const_int 0)])
17439                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17440                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17441   "TARGET_64BIT && TARGET_CMOVE
17442    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17443   "@
17444    cmov%O2%C1\t{%2, %0|%0, %2}
17445    cmov%O2%c1\t{%3, %0|%0, %3}"
17446   [(set_attr "type" "icmov")
17447    (set_attr "mode" "DI")])
17448
17449 (define_expand "movsicc"
17450   [(set (match_operand:SI 0 "register_operand" "")
17451         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17452                          (match_operand:SI 2 "general_operand" "")
17453                          (match_operand:SI 3 "general_operand" "")))]
17454   ""
17455   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17456
17457 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17458 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17459 ;; So just document what we're doing explicitly.
17460
17461 (define_insn "x86_movsicc_0_m1"
17462   [(set (match_operand:SI 0 "register_operand" "=r")
17463         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17464           (const_int -1)
17465           (const_int 0)))
17466    (clobber (reg:CC FLAGS_REG))]
17467   ""
17468   "sbb{l}\t%0, %0"
17469   ; Since we don't have the proper number of operands for an alu insn,
17470   ; fill in all the blanks.
17471   [(set_attr "type" "alu")
17472    (set_attr "pent_pair" "pu")
17473    (set_attr "memory" "none")
17474    (set_attr "imm_disp" "false")
17475    (set_attr "mode" "SI")
17476    (set_attr "length_immediate" "0")])
17477
17478 (define_insn "*movsicc_noc"
17479   [(set (match_operand:SI 0 "register_operand" "=r,r")
17480         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17481                                 [(reg FLAGS_REG) (const_int 0)])
17482                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17483                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17484   "TARGET_CMOVE
17485    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17486   "@
17487    cmov%O2%C1\t{%2, %0|%0, %2}
17488    cmov%O2%c1\t{%3, %0|%0, %3}"
17489   [(set_attr "type" "icmov")
17490    (set_attr "mode" "SI")])
17491
17492 (define_expand "movhicc"
17493   [(set (match_operand:HI 0 "register_operand" "")
17494         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17495                          (match_operand:HI 2 "general_operand" "")
17496                          (match_operand:HI 3 "general_operand" "")))]
17497   "TARGET_HIMODE_MATH"
17498   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17499
17500 (define_insn "*movhicc_noc"
17501   [(set (match_operand:HI 0 "register_operand" "=r,r")
17502         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17503                                 [(reg FLAGS_REG) (const_int 0)])
17504                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17505                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17506   "TARGET_CMOVE
17507    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17508   "@
17509    cmov%O2%C1\t{%2, %0|%0, %2}
17510    cmov%O2%c1\t{%3, %0|%0, %3}"
17511   [(set_attr "type" "icmov")
17512    (set_attr "mode" "HI")])
17513
17514 (define_expand "movqicc"
17515   [(set (match_operand:QI 0 "register_operand" "")
17516         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17517                          (match_operand:QI 2 "general_operand" "")
17518                          (match_operand:QI 3 "general_operand" "")))]
17519   "TARGET_QIMODE_MATH"
17520   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17521
17522 (define_insn_and_split "*movqicc_noc"
17523   [(set (match_operand:QI 0 "register_operand" "=r,r")
17524         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17525                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17526                       (match_operand:QI 2 "register_operand" "r,0")
17527                       (match_operand:QI 3 "register_operand" "0,r")))]
17528   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17529   "#"
17530   "&& reload_completed"
17531   [(set (match_dup 0)
17532         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17533                       (match_dup 2)
17534                       (match_dup 3)))]
17535   "operands[0] = gen_lowpart (SImode, operands[0]);
17536    operands[2] = gen_lowpart (SImode, operands[2]);
17537    operands[3] = gen_lowpart (SImode, operands[3]);"
17538   [(set_attr "type" "icmov")
17539    (set_attr "mode" "SI")])
17540
17541 (define_expand "movsfcc"
17542   [(set (match_operand:SF 0 "register_operand" "")
17543         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17544                          (match_operand:SF 2 "register_operand" "")
17545                          (match_operand:SF 3 "register_operand" "")))]
17546   "TARGET_CMOVE"
17547   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17548
17549 (define_insn "*movsfcc_1"
17550   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17551         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17552                                 [(reg FLAGS_REG) (const_int 0)])
17553                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17554                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17555   "TARGET_CMOVE
17556    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17557   "@
17558    fcmov%F1\t{%2, %0|%0, %2}
17559    fcmov%f1\t{%3, %0|%0, %3}
17560    cmov%O2%C1\t{%2, %0|%0, %2}
17561    cmov%O2%c1\t{%3, %0|%0, %3}"
17562   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17563    (set_attr "mode" "SF,SF,SI,SI")])
17564
17565 (define_expand "movdfcc"
17566   [(set (match_operand:DF 0 "register_operand" "")
17567         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17568                          (match_operand:DF 2 "register_operand" "")
17569                          (match_operand:DF 3 "register_operand" "")))]
17570   "TARGET_CMOVE"
17571   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17572
17573 (define_insn "*movdfcc_1"
17574   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17575         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17576                                 [(reg FLAGS_REG) (const_int 0)])
17577                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17578                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17579   "!TARGET_64BIT && TARGET_CMOVE
17580    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17581   "@
17582    fcmov%F1\t{%2, %0|%0, %2}
17583    fcmov%f1\t{%3, %0|%0, %3}
17584    #
17585    #"
17586   [(set_attr "type" "fcmov,fcmov,multi,multi")
17587    (set_attr "mode" "DF")])
17588
17589 (define_insn "*movdfcc_1_rex64"
17590   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17591         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17592                                 [(reg FLAGS_REG) (const_int 0)])
17593                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17594                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17595   "TARGET_64BIT && TARGET_CMOVE
17596    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17597   "@
17598    fcmov%F1\t{%2, %0|%0, %2}
17599    fcmov%f1\t{%3, %0|%0, %3}
17600    cmov%O2%C1\t{%2, %0|%0, %2}
17601    cmov%O2%c1\t{%3, %0|%0, %3}"
17602   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17603    (set_attr "mode" "DF")])
17604
17605 (define_split
17606   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17607         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17608                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17609                       (match_operand:DF 2 "nonimmediate_operand" "")
17610                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17611   "!TARGET_64BIT && reload_completed"
17612   [(set (match_dup 2)
17613         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17614                       (match_dup 5)
17615                       (match_dup 7)))
17616    (set (match_dup 3)
17617         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17618                       (match_dup 6)
17619                       (match_dup 8)))]
17620   "split_di (operands+2, 1, operands+5, operands+6);
17621    split_di (operands+3, 1, operands+7, operands+8);
17622    split_di (operands, 1, operands+2, operands+3);")
17623
17624 (define_expand "movxfcc"
17625   [(set (match_operand:XF 0 "register_operand" "")
17626         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17627                          (match_operand:XF 2 "register_operand" "")
17628                          (match_operand:XF 3 "register_operand" "")))]
17629   "TARGET_CMOVE"
17630   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17631
17632 (define_insn "*movxfcc_1"
17633   [(set (match_operand:XF 0 "register_operand" "=f,f")
17634         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17635                                 [(reg FLAGS_REG) (const_int 0)])
17636                       (match_operand:XF 2 "register_operand" "f,0")
17637                       (match_operand:XF 3 "register_operand" "0,f")))]
17638   "TARGET_CMOVE"
17639   "@
17640    fcmov%F1\t{%2, %0|%0, %2}
17641    fcmov%f1\t{%3, %0|%0, %3}"
17642   [(set_attr "type" "fcmov")
17643    (set_attr "mode" "XF")])
17644
17645 (define_expand "minsf3"
17646   [(parallel [
17647      (set (match_operand:SF 0 "register_operand" "")
17648           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17649                                (match_operand:SF 2 "nonimmediate_operand" ""))
17650                            (match_dup 1)
17651                            (match_dup 2)))
17652      (clobber (reg:CC FLAGS_REG))])]
17653   "TARGET_SSE"
17654   "")
17655
17656 (define_insn "*minsf"
17657   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17658         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17659                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17660                          (match_dup 1)
17661                          (match_dup 2)))
17662    (clobber (reg:CC FLAGS_REG))]
17663   "TARGET_SSE && TARGET_IEEE_FP"
17664   "#")
17665
17666 (define_insn "*minsf_nonieee"
17667   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17668         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17669                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17670                          (match_dup 1)
17671                          (match_dup 2)))
17672    (clobber (reg:CC FLAGS_REG))]
17673   "TARGET_SSE && !TARGET_IEEE_FP
17674    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17675   "#")
17676
17677 (define_split
17678   [(set (match_operand:SF 0 "register_operand" "")
17679         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17680                              (match_operand:SF 2 "nonimmediate_operand" ""))
17681                          (match_operand:SF 3 "register_operand" "")
17682                          (match_operand:SF 4 "nonimmediate_operand" "")))
17683    (clobber (reg:CC FLAGS_REG))]
17684   "SSE_REG_P (operands[0]) && reload_completed
17685    && ((operands_match_p (operands[1], operands[3])
17686         && operands_match_p (operands[2], operands[4]))
17687        || (operands_match_p (operands[1], operands[4])
17688            && operands_match_p (operands[2], operands[3])))"
17689   [(set (match_dup 0)
17690         (if_then_else:SF (lt (match_dup 1)
17691                              (match_dup 2))
17692                          (match_dup 1)
17693                          (match_dup 2)))])
17694
17695 ;; Conditional addition patterns
17696 (define_expand "addqicc"
17697   [(match_operand:QI 0 "register_operand" "")
17698    (match_operand 1 "comparison_operator" "")
17699    (match_operand:QI 2 "register_operand" "")
17700    (match_operand:QI 3 "const_int_operand" "")]
17701   ""
17702   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17703
17704 (define_expand "addhicc"
17705   [(match_operand:HI 0 "register_operand" "")
17706    (match_operand 1 "comparison_operator" "")
17707    (match_operand:HI 2 "register_operand" "")
17708    (match_operand:HI 3 "const_int_operand" "")]
17709   ""
17710   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17711
17712 (define_expand "addsicc"
17713   [(match_operand:SI 0 "register_operand" "")
17714    (match_operand 1 "comparison_operator" "")
17715    (match_operand:SI 2 "register_operand" "")
17716    (match_operand:SI 3 "const_int_operand" "")]
17717   ""
17718   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17719
17720 (define_expand "adddicc"
17721   [(match_operand:DI 0 "register_operand" "")
17722    (match_operand 1 "comparison_operator" "")
17723    (match_operand:DI 2 "register_operand" "")
17724    (match_operand:DI 3 "const_int_operand" "")]
17725   "TARGET_64BIT"
17726   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17727
17728 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17729
17730 (define_split
17731   [(set (match_operand:SF 0 "fp_register_operand" "")
17732         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17733                              (match_operand:SF 2 "register_operand" ""))
17734                          (match_operand:SF 3 "register_operand" "")
17735                          (match_operand:SF 4 "register_operand" "")))
17736    (clobber (reg:CC FLAGS_REG))]
17737   "reload_completed
17738    && ((operands_match_p (operands[1], operands[3])
17739         && operands_match_p (operands[2], operands[4]))
17740        || (operands_match_p (operands[1], operands[4])
17741            && operands_match_p (operands[2], operands[3])))"
17742   [(set (reg:CCFP FLAGS_REG)
17743         (compare:CCFP (match_dup 2)
17744                       (match_dup 1)))
17745    (set (match_dup 0)
17746         (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17747                          (match_dup 1)
17748                          (match_dup 2)))])
17749
17750 (define_insn "*minsf_sse"
17751   [(set (match_operand:SF 0 "register_operand" "=x")
17752         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17753                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17754                          (match_dup 1)
17755                          (match_dup 2)))]
17756   "TARGET_SSE && reload_completed"
17757   "minss\t{%2, %0|%0, %2}"
17758   [(set_attr "type" "sse")
17759    (set_attr "mode" "SF")])
17760
17761 (define_expand "mindf3"
17762   [(parallel [
17763      (set (match_operand:DF 0 "register_operand" "")
17764           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17765                                (match_operand:DF 2 "nonimmediate_operand" ""))
17766                            (match_dup 1)
17767                            (match_dup 2)))
17768      (clobber (reg:CC FLAGS_REG))])]
17769   "TARGET_SSE2 && TARGET_SSE_MATH"
17770   "#")
17771
17772 (define_insn "*mindf"
17773   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17774         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17775                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17776                          (match_dup 1)
17777                          (match_dup 2)))
17778    (clobber (reg:CC FLAGS_REG))]
17779   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17780   "#")
17781
17782 (define_insn "*mindf_nonieee"
17783   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17784         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17785                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17786                          (match_dup 1)
17787                          (match_dup 2)))
17788    (clobber (reg:CC FLAGS_REG))]
17789   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17790    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17791   "#")
17792
17793 (define_split
17794   [(set (match_operand:DF 0 "register_operand" "")
17795         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17796                              (match_operand:DF 2 "nonimmediate_operand" ""))
17797                          (match_operand:DF 3 "register_operand" "")
17798                          (match_operand:DF 4 "nonimmediate_operand" "")))
17799    (clobber (reg:CC FLAGS_REG))]
17800   "SSE_REG_P (operands[0]) && reload_completed
17801    && ((operands_match_p (operands[1], operands[3])
17802         && operands_match_p (operands[2], operands[4]))
17803        || (operands_match_p (operands[1], operands[4])
17804            && operands_match_p (operands[2], operands[3])))"
17805   [(set (match_dup 0)
17806         (if_then_else:DF (lt (match_dup 1)
17807                              (match_dup 2))
17808                          (match_dup 1)
17809                          (match_dup 2)))])
17810
17811 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17812 (define_split
17813   [(set (match_operand:DF 0 "fp_register_operand" "")
17814         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17815                              (match_operand:DF 2 "register_operand" ""))
17816                          (match_operand:DF 3 "register_operand" "")
17817                          (match_operand:DF 4 "register_operand" "")))
17818    (clobber (reg:CC FLAGS_REG))]
17819   "reload_completed
17820    && ((operands_match_p (operands[1], operands[3])
17821         && operands_match_p (operands[2], operands[4]))
17822        || (operands_match_p (operands[1], operands[4])
17823            && operands_match_p (operands[2], operands[3])))"
17824   [(set (reg:CCFP FLAGS_REG)
17825         (compare:CCFP (match_dup 2)
17826                       (match_dup 1)))
17827    (set (match_dup 0)
17828         (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17829                          (match_dup 1)
17830                          (match_dup 2)))])
17831
17832 (define_insn "*mindf_sse"
17833   [(set (match_operand:DF 0 "register_operand" "=Y")
17834         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17835                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17836                          (match_dup 1)
17837                          (match_dup 2)))]
17838   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17839   "minsd\t{%2, %0|%0, %2}"
17840   [(set_attr "type" "sse")
17841    (set_attr "mode" "DF")])
17842
17843 (define_expand "maxsf3"
17844   [(parallel [
17845      (set (match_operand:SF 0 "register_operand" "")
17846           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17847                                (match_operand:SF 2 "nonimmediate_operand" ""))
17848                            (match_dup 1)
17849                            (match_dup 2)))
17850      (clobber (reg:CC FLAGS_REG))])]
17851   "TARGET_SSE"
17852   "#")
17853
17854 (define_insn "*maxsf"
17855   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17856         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17857                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17858                          (match_dup 1)
17859                          (match_dup 2)))
17860    (clobber (reg:CC FLAGS_REG))]
17861   "TARGET_SSE && TARGET_IEEE_FP"
17862   "#")
17863
17864 (define_insn "*maxsf_nonieee"
17865   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17866         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17867                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17868                          (match_dup 1)
17869                          (match_dup 2)))
17870    (clobber (reg:CC FLAGS_REG))]
17871   "TARGET_SSE && !TARGET_IEEE_FP
17872    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17873   "#")
17874
17875 (define_split
17876   [(set (match_operand:SF 0 "register_operand" "")
17877         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17878                              (match_operand:SF 2 "nonimmediate_operand" ""))
17879                          (match_operand:SF 3 "register_operand" "")
17880                          (match_operand:SF 4 "nonimmediate_operand" "")))
17881    (clobber (reg:CC FLAGS_REG))]
17882   "SSE_REG_P (operands[0]) && reload_completed
17883    && ((operands_match_p (operands[1], operands[3])
17884         && operands_match_p (operands[2], operands[4]))
17885        || (operands_match_p (operands[1], operands[4])
17886            && operands_match_p (operands[2], operands[3])))"
17887   [(set (match_dup 0)
17888         (if_then_else:SF (gt (match_dup 1)
17889                              (match_dup 2))
17890                          (match_dup 1)
17891                          (match_dup 2)))])
17892
17893 (define_split
17894   [(set (match_operand:SF 0 "fp_register_operand" "")
17895         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17896                              (match_operand:SF 2 "register_operand" ""))
17897                          (match_operand:SF 3 "register_operand" "")
17898                          (match_operand:SF 4 "register_operand" "")))
17899    (clobber (reg:CC FLAGS_REG))]
17900   "reload_completed
17901    && ((operands_match_p (operands[1], operands[3])
17902         && operands_match_p (operands[2], operands[4]))
17903        || (operands_match_p (operands[1], operands[4])
17904            && operands_match_p (operands[2], operands[3])))"
17905   [(set (reg:CCFP FLAGS_REG)
17906         (compare:CCFP (match_dup 1)
17907                       (match_dup 2)))
17908    (set (match_dup 0)
17909         (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17910                          (match_dup 1)
17911                          (match_dup 2)))])
17912
17913 (define_insn "*maxsf_sse"
17914   [(set (match_operand:SF 0 "register_operand" "=x")
17915         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17916                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17917                          (match_dup 1)
17918                          (match_dup 2)))]
17919   "TARGET_SSE && reload_completed"
17920   "maxss\t{%2, %0|%0, %2}"
17921   [(set_attr "type" "sse")
17922    (set_attr "mode" "SF")])
17923
17924 (define_expand "maxdf3"
17925   [(parallel [
17926      (set (match_operand:DF 0 "register_operand" "")
17927           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17928                                (match_operand:DF 2 "nonimmediate_operand" ""))
17929                            (match_dup 1)
17930                            (match_dup 2)))
17931      (clobber (reg:CC FLAGS_REG))])]
17932   "TARGET_SSE2 && TARGET_SSE_MATH"
17933   "#")
17934
17935 (define_insn "*maxdf"
17936   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17937         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17938                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17939                          (match_dup 1)
17940                          (match_dup 2)))
17941    (clobber (reg:CC FLAGS_REG))]
17942   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17943   "#")
17944
17945 (define_insn "*maxdf_nonieee"
17946   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17947         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17948                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17949                          (match_dup 1)
17950                          (match_dup 2)))
17951    (clobber (reg:CC FLAGS_REG))]
17952   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17953    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17954   "#")
17955
17956 (define_split
17957   [(set (match_operand:DF 0 "register_operand" "")
17958         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17959                              (match_operand:DF 2 "nonimmediate_operand" ""))
17960                          (match_operand:DF 3 "register_operand" "")
17961                          (match_operand:DF 4 "nonimmediate_operand" "")))
17962    (clobber (reg:CC FLAGS_REG))]
17963   "SSE_REG_P (operands[0]) && reload_completed
17964    && ((operands_match_p (operands[1], operands[3])
17965         && operands_match_p (operands[2], operands[4]))
17966        || (operands_match_p (operands[1], operands[4])
17967            && operands_match_p (operands[2], operands[3])))"
17968   [(set (match_dup 0)
17969         (if_then_else:DF (gt (match_dup 1)
17970                              (match_dup 2))
17971                          (match_dup 1)
17972                          (match_dup 2)))])
17973
17974 (define_split
17975   [(set (match_operand:DF 0 "fp_register_operand" "")
17976         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17977                              (match_operand:DF 2 "register_operand" ""))
17978                          (match_operand:DF 3 "register_operand" "")
17979                          (match_operand:DF 4 "register_operand" "")))
17980    (clobber (reg:CC FLAGS_REG))]
17981   "reload_completed
17982    && ((operands_match_p (operands[1], operands[3])
17983         && operands_match_p (operands[2], operands[4]))
17984        || (operands_match_p (operands[1], operands[4])
17985            && operands_match_p (operands[2], operands[3])))"
17986   [(set (reg:CCFP FLAGS_REG)
17987         (compare:CCFP (match_dup 1)
17988                       (match_dup 2)))
17989    (set (match_dup 0)
17990         (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17991                          (match_dup 1)
17992                          (match_dup 2)))])
17993
17994 (define_insn "*maxdf_sse"
17995   [(set (match_operand:DF 0 "register_operand" "=Y")
17996         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17997                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17998                          (match_dup 1)
17999                          (match_dup 2)))]
18000   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
18001   "maxsd\t{%2, %0|%0, %2}"
18002   [(set_attr "type" "sse")
18003    (set_attr "mode" "DF")])
18004 \f
18005 ;; Misc patterns (?)
18006
18007 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18008 ;; Otherwise there will be nothing to keep
18009 ;; 
18010 ;; [(set (reg ebp) (reg esp))]
18011 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18012 ;;  (clobber (eflags)]
18013 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18014 ;;
18015 ;; in proper program order.
18016 (define_insn "pro_epilogue_adjust_stack_1"
18017   [(set (match_operand:SI 0 "register_operand" "=r,r")
18018         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18019                  (match_operand:SI 2 "immediate_operand" "i,i")))
18020    (clobber (reg:CC FLAGS_REG))
18021    (clobber (mem:BLK (scratch)))]
18022   "!TARGET_64BIT"
18023 {
18024   switch (get_attr_type (insn))
18025     {
18026     case TYPE_IMOV:
18027       return "mov{l}\t{%1, %0|%0, %1}";
18028
18029     case TYPE_ALU:
18030       if (GET_CODE (operands[2]) == CONST_INT
18031           && (INTVAL (operands[2]) == 128
18032               || (INTVAL (operands[2]) < 0
18033                   && INTVAL (operands[2]) != -128)))
18034         {
18035           operands[2] = GEN_INT (-INTVAL (operands[2]));
18036           return "sub{l}\t{%2, %0|%0, %2}";
18037         }
18038       return "add{l}\t{%2, %0|%0, %2}";
18039
18040     case TYPE_LEA:
18041       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18042       return "lea{l}\t{%a2, %0|%0, %a2}";
18043
18044     default:
18045       abort ();
18046     }
18047 }
18048   [(set (attr "type")
18049         (cond [(eq_attr "alternative" "0")
18050                  (const_string "alu")
18051                (match_operand:SI 2 "const0_operand" "")
18052                  (const_string "imov")
18053               ]
18054               (const_string "lea")))
18055    (set_attr "mode" "SI")])
18056
18057 (define_insn "pro_epilogue_adjust_stack_rex64"
18058   [(set (match_operand:DI 0 "register_operand" "=r,r")
18059         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18060                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18061    (clobber (reg:CC FLAGS_REG))
18062    (clobber (mem:BLK (scratch)))]
18063   "TARGET_64BIT"
18064 {
18065   switch (get_attr_type (insn))
18066     {
18067     case TYPE_IMOV:
18068       return "mov{q}\t{%1, %0|%0, %1}";
18069
18070     case TYPE_ALU:
18071       if (GET_CODE (operands[2]) == CONST_INT
18072           /* Avoid overflows.  */
18073           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18074           && (INTVAL (operands[2]) == 128
18075               || (INTVAL (operands[2]) < 0
18076                   && INTVAL (operands[2]) != -128)))
18077         {
18078           operands[2] = GEN_INT (-INTVAL (operands[2]));
18079           return "sub{q}\t{%2, %0|%0, %2}";
18080         }
18081       return "add{q}\t{%2, %0|%0, %2}";
18082
18083     case TYPE_LEA:
18084       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18085       return "lea{q}\t{%a2, %0|%0, %a2}";
18086
18087     default:
18088       abort ();
18089     }
18090 }
18091   [(set (attr "type")
18092         (cond [(eq_attr "alternative" "0")
18093                  (const_string "alu")
18094                (match_operand:DI 2 "const0_operand" "")
18095                  (const_string "imov")
18096               ]
18097               (const_string "lea")))
18098    (set_attr "mode" "DI")])
18099
18100 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18101   [(set (match_operand:DI 0 "register_operand" "=r,r")
18102         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18103                  (match_operand:DI 3 "immediate_operand" "i,i")))
18104    (use (match_operand:DI 2 "register_operand" "r,r"))
18105    (clobber (reg:CC FLAGS_REG))
18106    (clobber (mem:BLK (scratch)))]
18107   "TARGET_64BIT"
18108 {
18109   switch (get_attr_type (insn))
18110     {
18111     case TYPE_ALU:
18112       return "add{q}\t{%2, %0|%0, %2}";
18113
18114     case TYPE_LEA:
18115       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18116       return "lea{q}\t{%a2, %0|%0, %a2}";
18117
18118     default:
18119       abort ();
18120     }
18121 }
18122   [(set_attr "type" "alu,lea")
18123    (set_attr "mode" "DI")])
18124
18125 ;; Placeholder for the conditional moves.  This one is split either to SSE
18126 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
18127 ;; fact is that compares supported by the cmp??ss instructions are exactly
18128 ;; swapped of those supported by cmove sequence.
18129 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18130 ;; supported by i387 comparisons and we do need to emit two conditional moves
18131 ;; in tandem.
18132
18133 (define_insn "sse_movsfcc"
18134   [(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")
18135         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18136                         [(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")
18137                          (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")])
18138                       (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")
18139                       (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")))
18140    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18141    (clobber (reg:CC FLAGS_REG))]
18142   "TARGET_SSE
18143    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18144    /* Avoid combine from being smart and converting min/max
18145       instruction patterns into conditional moves.  */
18146    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18147         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18148        || !rtx_equal_p (operands[4], operands[2])
18149        || !rtx_equal_p (operands[5], operands[3]))
18150    && (!TARGET_IEEE_FP
18151        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18152   "#")
18153
18154 (define_insn "sse_movsfcc_eq"
18155   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18156         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18157                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18158                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18159                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18160    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18161    (clobber (reg:CC FLAGS_REG))]
18162   "TARGET_SSE
18163    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18164   "#")
18165
18166 (define_insn "sse_movdfcc"
18167   [(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")
18168         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18169                         [(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")
18170                          (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")])
18171                       (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")
18172                       (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")))
18173    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18174    (clobber (reg:CC FLAGS_REG))]
18175   "TARGET_SSE2
18176    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18177    /* Avoid combine from being smart and converting min/max
18178       instruction patterns into conditional moves.  */
18179    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18180         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18181        || !rtx_equal_p (operands[4], operands[2])
18182        || !rtx_equal_p (operands[5], operands[3]))
18183    && (!TARGET_IEEE_FP
18184        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18185   "#")
18186
18187 (define_insn "sse_movdfcc_eq"
18188   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18189         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18190                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18191                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18192                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18193    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18194    (clobber (reg:CC FLAGS_REG))]
18195   "TARGET_SSE
18196    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18197   "#")
18198
18199 ;; For non-sse moves just expand the usual cmove sequence.
18200 (define_split
18201   [(set (match_operand 0 "register_operand" "")
18202         (if_then_else (match_operator 1 "comparison_operator"
18203                         [(match_operand 4 "nonimmediate_operand" "")
18204                          (match_operand 5 "register_operand" "")])
18205                       (match_operand 2 "nonimmediate_operand" "")
18206                       (match_operand 3 "nonimmediate_operand" "")))
18207    (clobber (match_operand 6 "" ""))
18208    (clobber (reg:CC FLAGS_REG))]
18209   "!SSE_REG_P (operands[0]) && reload_completed
18210    && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
18211   [(const_int 0)]
18212 {
18213    ix86_compare_op0 = operands[5];
18214    ix86_compare_op1 = operands[4];
18215    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18216                                  VOIDmode, operands[5], operands[4]);
18217    ix86_expand_fp_movcc (operands);
18218    DONE;
18219 })
18220
18221 ;; Split SSE based conditional move into sequence:
18222 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
18223 ;; and   op2, op0   -  zero op2 if comparison was false
18224 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
18225 ;; or    op2, op0   -  get the nonzero one into the result.
18226 (define_split
18227   [(set (match_operand:SF 0 "register_operand" "")
18228         (if_then_else (match_operator:SF 1 "sse_comparison_operator"
18229                         [(match_operand:SF 4 "register_operand" "")
18230                          (match_operand:SF 5 "nonimmediate_operand" "")])
18231                       (match_operand:SF 2 "register_operand" "")
18232                       (match_operand:SF 3 "register_operand" "")))
18233    (clobber (match_operand 6 "" ""))
18234    (clobber (reg:CC FLAGS_REG))]
18235   "SSE_REG_P (operands[0]) && reload_completed"
18236   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18237    (set (match_dup 2) (and:V4SF (match_dup 2)
18238                                 (match_dup 8)))
18239    (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18240                                           (match_dup 3)))
18241    (set (match_dup 0) (ior:V4SF (match_dup 6)
18242                                 (match_dup 7)))]
18243 {
18244   /* If op2 == op3, op3 would be clobbered before it is used.  */
18245   if (operands_match_p (operands[2], operands[3]))
18246     {
18247       emit_move_insn (operands[0], operands[2]);
18248       DONE;
18249     }
18250
18251   PUT_MODE (operands[1], GET_MODE (operands[0]));
18252   if (operands_match_p (operands[0], operands[4]))
18253     operands[6] = operands[4], operands[7] = operands[2];
18254   else
18255     operands[6] = operands[2], operands[7] = operands[4];
18256   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18257   operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18258   operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18259   operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18260   operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18261   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18262 })
18263
18264 (define_split
18265   [(set (match_operand:DF 0 "register_operand" "")
18266         (if_then_else (match_operator:DF 1 "sse_comparison_operator"
18267                         [(match_operand:DF 4 "register_operand" "")
18268                          (match_operand:DF 5 "nonimmediate_operand" "")])
18269                       (match_operand:DF 2 "register_operand" "")
18270                       (match_operand:DF 3 "register_operand" "")))
18271    (clobber (match_operand 6 "" ""))
18272    (clobber (reg:CC FLAGS_REG))]
18273   "SSE_REG_P (operands[0]) && reload_completed"
18274   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18275    (set (match_dup 2) (and:V2DF (match_dup 2)
18276                                 (match_dup 8)))
18277    (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18278                                           (match_dup 3)))
18279    (set (match_dup 0) (ior:V2DF (match_dup 6)
18280                                 (match_dup 7)))]
18281 {
18282   if (GET_MODE (operands[2]) == DFmode
18283       && TARGET_SSE_PARTIAL_REGS && !optimize_size)
18284     {
18285       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18286       emit_insn (gen_sse2_unpcklpd (op, op, op));
18287       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18288       emit_insn (gen_sse2_unpcklpd (op, op, op));
18289     }
18290
18291   /* If op2 == op3, op3 would be clobbered before it is used.  */
18292   if (operands_match_p (operands[2], operands[3]))
18293     {
18294       emit_move_insn (operands[0], operands[2]);
18295       DONE;
18296     }
18297
18298   PUT_MODE (operands[1], GET_MODE (operands[0]));
18299   if (operands_match_p (operands[0], operands[4]))
18300     operands[6] = operands[4], operands[7] = operands[2];
18301   else
18302     operands[6] = operands[2], operands[7] = operands[4];
18303   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18304   operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18305   operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18306   operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18307   operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18308   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18309 })
18310
18311 ;; Special case of conditional move we can handle effectively.
18312 ;; Do not brother with the integer/floating point case, since these are
18313 ;; bot considerably slower, unlike in the generic case.
18314 (define_insn "*sse_movsfcc_const0_1"
18315   [(set (match_operand:SF 0 "register_operand" "=&x")
18316         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18317                         [(match_operand:SF 4 "register_operand" "0")
18318                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18319                       (match_operand:SF 2 "register_operand" "x")
18320                       (match_operand:SF 3 "const0_operand" "X")))]
18321   "TARGET_SSE"
18322   "#")
18323
18324 (define_insn "*sse_movsfcc_const0_2"
18325   [(set (match_operand:SF 0 "register_operand" "=&x")
18326         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18327                         [(match_operand:SF 4 "register_operand" "0")
18328                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18329                       (match_operand:SF 2 "const0_operand" "X")
18330                       (match_operand:SF 3 "register_operand" "x")))]
18331   "TARGET_SSE"
18332   "#")
18333
18334 (define_insn "*sse_movsfcc_const0_3"
18335   [(set (match_operand:SF 0 "register_operand" "=&x")
18336         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18337                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18338                          (match_operand:SF 5 "register_operand" "0")])
18339                       (match_operand:SF 2 "register_operand" "x")
18340                       (match_operand:SF 3 "const0_operand" "X")))]
18341   "TARGET_SSE"
18342   "#")
18343
18344 (define_insn "*sse_movsfcc_const0_4"
18345   [(set (match_operand:SF 0 "register_operand" "=&x")
18346         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18347                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18348                          (match_operand:SF 5 "register_operand" "0")])
18349                       (match_operand:SF 2 "const0_operand" "X")
18350                       (match_operand:SF 3 "register_operand" "x")))]
18351   "TARGET_SSE"
18352   "#")
18353
18354 (define_insn "*sse_movdfcc_const0_1"
18355   [(set (match_operand:DF 0 "register_operand" "=&Y")
18356         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18357                         [(match_operand:DF 4 "register_operand" "0")
18358                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18359                       (match_operand:DF 2 "register_operand" "Y")
18360                       (match_operand:DF 3 "const0_operand" "X")))]
18361   "TARGET_SSE2"
18362   "#")
18363
18364 (define_insn "*sse_movdfcc_const0_2"
18365   [(set (match_operand:DF 0 "register_operand" "=&Y")
18366         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18367                         [(match_operand:DF 4 "register_operand" "0")
18368                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18369                       (match_operand:DF 2 "const0_operand" "X")
18370                       (match_operand:DF 3 "register_operand" "Y")))]
18371   "TARGET_SSE2"
18372   "#")
18373
18374 (define_insn "*sse_movdfcc_const0_3"
18375   [(set (match_operand:DF 0 "register_operand" "=&Y")
18376         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18377                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18378                          (match_operand:DF 5 "register_operand" "0")])
18379                       (match_operand:DF 2 "register_operand" "Y")
18380                       (match_operand:DF 3 "const0_operand" "X")))]
18381   "TARGET_SSE2"
18382   "#")
18383
18384 (define_insn "*sse_movdfcc_const0_4"
18385   [(set (match_operand:DF 0 "register_operand" "=&Y")
18386         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18387                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18388                          (match_operand:DF 5 "register_operand" "0")])
18389                       (match_operand:DF 2 "const0_operand" "X")
18390                       (match_operand:DF 3 "register_operand" "Y")))]
18391   "TARGET_SSE2"
18392   "#")
18393
18394 (define_split
18395   [(set (match_operand:SF 0 "register_operand" "")
18396         (if_then_else (match_operator 1 "comparison_operator"
18397                         [(match_operand:SF 4 "nonimmediate_operand" "")
18398                          (match_operand:SF 5 "nonimmediate_operand" "")])
18399                       (match_operand:SF 2 "nonmemory_operand" "")
18400                       (match_operand:SF 3 "nonmemory_operand" "")))]
18401   "SSE_REG_P (operands[0]) && reload_completed
18402    && (const0_operand (operands[2], GET_MODE (operands[0]))
18403        || const0_operand (operands[3], GET_MODE (operands[0])))"
18404   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18405    (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18406 {
18407   PUT_MODE (operands[1], GET_MODE (operands[0]));
18408   if (!sse_comparison_operator (operands[1], VOIDmode)
18409       || !rtx_equal_p (operands[0], operands[4]))
18410     {
18411       rtx tmp = operands[5];
18412       operands[5] = operands[4];
18413       operands[4] = tmp;
18414       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18415     }
18416   if (!rtx_equal_p (operands[0], operands[4]))
18417     abort ();
18418   operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18419   if (const0_operand (operands[2], GET_MODE (operands[2])))
18420     {
18421       operands[7] = operands[3];
18422       operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18423     }
18424   else
18425     {
18426       operands[7] = operands[2];
18427       operands[6] = operands[8];
18428     }
18429   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18430 })
18431
18432 (define_split
18433   [(set (match_operand:DF 0 "register_operand" "")
18434         (if_then_else (match_operator 1 "comparison_operator"
18435                         [(match_operand:DF 4 "nonimmediate_operand" "")
18436                          (match_operand:DF 5 "nonimmediate_operand" "")])
18437                       (match_operand:DF 2 "nonmemory_operand" "")
18438                       (match_operand:DF 3 "nonmemory_operand" "")))]
18439   "SSE_REG_P (operands[0]) && reload_completed
18440    && (const0_operand (operands[2], GET_MODE (operands[0]))
18441        || const0_operand (operands[3], GET_MODE (operands[0])))"
18442   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18443    (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18444 {
18445   if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18446       && GET_MODE (operands[2]) == DFmode)
18447     {
18448       if (REG_P (operands[2]))
18449         {
18450           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18451           emit_insn (gen_sse2_unpcklpd (op, op, op));
18452         }
18453       if (REG_P (operands[3]))
18454         {
18455           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18456           emit_insn (gen_sse2_unpcklpd (op, op, op));
18457         }
18458     }
18459   PUT_MODE (operands[1], GET_MODE (operands[0]));
18460   if (!sse_comparison_operator (operands[1], VOIDmode)
18461       || !rtx_equal_p (operands[0], operands[4]))
18462     {
18463       rtx tmp = operands[5];
18464       operands[5] = operands[4];
18465       operands[4] = tmp;
18466       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18467     }
18468   if (!rtx_equal_p (operands[0], operands[4]))
18469     abort ();
18470   operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18471   if (const0_operand (operands[2], GET_MODE (operands[2])))
18472     {
18473       operands[7] = operands[3];
18474       operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18475     }
18476   else
18477     {
18478       operands[7] = operands[2];
18479       operands[6] = operands[8];
18480     }
18481   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18482 })
18483
18484 (define_expand "allocate_stack_worker"
18485   [(match_operand:SI 0 "register_operand" "")]
18486   "TARGET_STACK_PROBE"
18487 {
18488   if (reload_completed)
18489     {
18490       if (TARGET_64BIT)
18491         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18492       else
18493         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18494     }
18495   else
18496     {
18497       if (TARGET_64BIT)
18498         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18499       else
18500         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18501     }
18502   DONE;
18503 })
18504
18505 (define_insn "allocate_stack_worker_1"
18506   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18507     UNSPECV_STACK_PROBE)
18508    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18509    (clobber (match_scratch:SI 1 "=0"))
18510    (clobber (reg:CC FLAGS_REG))]
18511   "!TARGET_64BIT && TARGET_STACK_PROBE"
18512   "call\t__alloca"
18513   [(set_attr "type" "multi")
18514    (set_attr "length" "5")])
18515
18516 (define_expand "allocate_stack_worker_postreload"
18517   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18518                                     UNSPECV_STACK_PROBE)
18519               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18520               (clobber (match_dup 0))
18521               (clobber (reg:CC FLAGS_REG))])]
18522   ""
18523   "")
18524
18525 (define_insn "allocate_stack_worker_rex64"
18526   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18527     UNSPECV_STACK_PROBE)
18528    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18529    (clobber (match_scratch:DI 1 "=0"))
18530    (clobber (reg:CC FLAGS_REG))]
18531   "TARGET_64BIT && TARGET_STACK_PROBE"
18532   "call\t__alloca"
18533   [(set_attr "type" "multi")
18534    (set_attr "length" "5")])
18535
18536 (define_expand "allocate_stack_worker_rex64_postreload"
18537   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18538                                     UNSPECV_STACK_PROBE)
18539               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18540               (clobber (match_dup 0))
18541               (clobber (reg:CC FLAGS_REG))])]
18542   ""
18543   "")
18544
18545 (define_expand "allocate_stack"
18546   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18547                    (minus:SI (reg:SI SP_REG)
18548                              (match_operand:SI 1 "general_operand" "")))
18549               (clobber (reg:CC FLAGS_REG))])
18550    (parallel [(set (reg:SI SP_REG)
18551                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18552               (clobber (reg:CC FLAGS_REG))])]
18553   "TARGET_STACK_PROBE"
18554 {
18555 #ifdef CHECK_STACK_LIMIT
18556   if (GET_CODE (operands[1]) == CONST_INT
18557       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18558     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18559                            operands[1]));
18560   else 
18561 #endif
18562     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18563                                                             operands[1])));
18564
18565   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18566   DONE;
18567 })
18568
18569 (define_expand "builtin_setjmp_receiver"
18570   [(label_ref (match_operand 0 "" ""))]
18571   "!TARGET_64BIT && flag_pic"
18572 {
18573   emit_insn (gen_set_got (pic_offset_table_rtx));
18574   DONE;
18575 })
18576 \f
18577 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18578
18579 (define_split
18580   [(set (match_operand 0 "register_operand" "")
18581         (match_operator 3 "promotable_binary_operator"
18582            [(match_operand 1 "register_operand" "")
18583             (match_operand 2 "aligned_operand" "")]))
18584    (clobber (reg:CC FLAGS_REG))]
18585   "! TARGET_PARTIAL_REG_STALL && reload_completed
18586    && ((GET_MODE (operands[0]) == HImode 
18587         && ((!optimize_size && !TARGET_FAST_PREFIX)
18588             || GET_CODE (operands[2]) != CONST_INT
18589             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18590        || (GET_MODE (operands[0]) == QImode 
18591            && (TARGET_PROMOTE_QImode || optimize_size)))"
18592   [(parallel [(set (match_dup 0)
18593                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18594               (clobber (reg:CC FLAGS_REG))])]
18595   "operands[0] = gen_lowpart (SImode, operands[0]);
18596    operands[1] = gen_lowpart (SImode, operands[1]);
18597    if (GET_CODE (operands[3]) != ASHIFT)
18598      operands[2] = gen_lowpart (SImode, operands[2]);
18599    PUT_MODE (operands[3], SImode);")
18600
18601 ; Promote the QImode tests, as i386 has encoding of the AND
18602 ; instruction with 32-bit sign-extended immediate and thus the
18603 ; instruction size is unchanged, except in the %eax case for
18604 ; which it is increased by one byte, hence the ! optimize_size.
18605 (define_split
18606   [(set (match_operand 0 "flags_reg_operand" "")
18607         (match_operator 2 "compare_operator"
18608           [(and (match_operand 3 "aligned_operand" "")
18609                 (match_operand 4 "const_int_operand" ""))
18610            (const_int 0)]))
18611    (set (match_operand 1 "register_operand" "")
18612         (and (match_dup 3) (match_dup 4)))]
18613   "! TARGET_PARTIAL_REG_STALL && reload_completed
18614    /* Ensure that the operand will remain sign-extended immediate.  */
18615    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18616    && ! optimize_size
18617    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18618        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18619   [(parallel [(set (match_dup 0)
18620                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18621                                     (const_int 0)]))
18622               (set (match_dup 1)
18623                    (and:SI (match_dup 3) (match_dup 4)))])]
18624 {
18625   operands[4]
18626     = gen_int_mode (INTVAL (operands[4])
18627                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18628   operands[1] = gen_lowpart (SImode, operands[1]);
18629   operands[3] = gen_lowpart (SImode, operands[3]);
18630 })
18631
18632 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18633 ; the TEST instruction with 32-bit sign-extended immediate and thus
18634 ; the instruction size would at least double, which is not what we
18635 ; want even with ! optimize_size.
18636 (define_split
18637   [(set (match_operand 0 "flags_reg_operand" "")
18638         (match_operator 1 "compare_operator"
18639           [(and (match_operand:HI 2 "aligned_operand" "")
18640                 (match_operand:HI 3 "const_int_operand" ""))
18641            (const_int 0)]))]
18642   "! TARGET_PARTIAL_REG_STALL && reload_completed
18643    /* Ensure that the operand will remain sign-extended immediate.  */
18644    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18645    && ! TARGET_FAST_PREFIX
18646    && ! optimize_size"
18647   [(set (match_dup 0)
18648         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18649                          (const_int 0)]))]
18650 {
18651   operands[3]
18652     = gen_int_mode (INTVAL (operands[3])
18653                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18654   operands[2] = gen_lowpart (SImode, operands[2]);
18655 })
18656
18657 (define_split
18658   [(set (match_operand 0 "register_operand" "")
18659         (neg (match_operand 1 "register_operand" "")))
18660    (clobber (reg:CC FLAGS_REG))]
18661   "! TARGET_PARTIAL_REG_STALL && reload_completed
18662    && (GET_MODE (operands[0]) == HImode
18663        || (GET_MODE (operands[0]) == QImode 
18664            && (TARGET_PROMOTE_QImode || optimize_size)))"
18665   [(parallel [(set (match_dup 0)
18666                    (neg:SI (match_dup 1)))
18667               (clobber (reg:CC FLAGS_REG))])]
18668   "operands[0] = gen_lowpart (SImode, operands[0]);
18669    operands[1] = gen_lowpart (SImode, operands[1]);")
18670
18671 (define_split
18672   [(set (match_operand 0 "register_operand" "")
18673         (not (match_operand 1 "register_operand" "")))]
18674   "! TARGET_PARTIAL_REG_STALL && reload_completed
18675    && (GET_MODE (operands[0]) == HImode
18676        || (GET_MODE (operands[0]) == QImode 
18677            && (TARGET_PROMOTE_QImode || optimize_size)))"
18678   [(set (match_dup 0)
18679         (not:SI (match_dup 1)))]
18680   "operands[0] = gen_lowpart (SImode, operands[0]);
18681    operands[1] = gen_lowpart (SImode, operands[1]);")
18682
18683 (define_split 
18684   [(set (match_operand 0 "register_operand" "")
18685         (if_then_else (match_operator 1 "comparison_operator" 
18686                                 [(reg FLAGS_REG) (const_int 0)])
18687                       (match_operand 2 "register_operand" "")
18688                       (match_operand 3 "register_operand" "")))]
18689   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18690    && (GET_MODE (operands[0]) == HImode
18691        || (GET_MODE (operands[0]) == QImode 
18692            && (TARGET_PROMOTE_QImode || optimize_size)))"
18693   [(set (match_dup 0)
18694         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18695   "operands[0] = gen_lowpart (SImode, operands[0]);
18696    operands[2] = gen_lowpart (SImode, operands[2]);
18697    operands[3] = gen_lowpart (SImode, operands[3]);")
18698                         
18699 \f
18700 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18701 ;; transform a complex memory operation into two memory to register operations.
18702
18703 ;; Don't push memory operands
18704 (define_peephole2
18705   [(set (match_operand:SI 0 "push_operand" "")
18706         (match_operand:SI 1 "memory_operand" ""))
18707    (match_scratch:SI 2 "r")]
18708   "! optimize_size && ! TARGET_PUSH_MEMORY"
18709   [(set (match_dup 2) (match_dup 1))
18710    (set (match_dup 0) (match_dup 2))]
18711   "")
18712
18713 (define_peephole2
18714   [(set (match_operand:DI 0 "push_operand" "")
18715         (match_operand:DI 1 "memory_operand" ""))
18716    (match_scratch:DI 2 "r")]
18717   "! optimize_size && ! TARGET_PUSH_MEMORY"
18718   [(set (match_dup 2) (match_dup 1))
18719    (set (match_dup 0) (match_dup 2))]
18720   "")
18721
18722 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18723 ;; SImode pushes.
18724 (define_peephole2
18725   [(set (match_operand:SF 0 "push_operand" "")
18726         (match_operand:SF 1 "memory_operand" ""))
18727    (match_scratch:SF 2 "r")]
18728   "! optimize_size && ! TARGET_PUSH_MEMORY"
18729   [(set (match_dup 2) (match_dup 1))
18730    (set (match_dup 0) (match_dup 2))]
18731   "")
18732
18733 (define_peephole2
18734   [(set (match_operand:HI 0 "push_operand" "")
18735         (match_operand:HI 1 "memory_operand" ""))
18736    (match_scratch:HI 2 "r")]
18737   "! optimize_size && ! TARGET_PUSH_MEMORY"
18738   [(set (match_dup 2) (match_dup 1))
18739    (set (match_dup 0) (match_dup 2))]
18740   "")
18741
18742 (define_peephole2
18743   [(set (match_operand:QI 0 "push_operand" "")
18744         (match_operand:QI 1 "memory_operand" ""))
18745    (match_scratch:QI 2 "q")]
18746   "! optimize_size && ! TARGET_PUSH_MEMORY"
18747   [(set (match_dup 2) (match_dup 1))
18748    (set (match_dup 0) (match_dup 2))]
18749   "")
18750
18751 ;; Don't move an immediate directly to memory when the instruction
18752 ;; gets too big.
18753 (define_peephole2
18754   [(match_scratch:SI 1 "r")
18755    (set (match_operand:SI 0 "memory_operand" "")
18756         (const_int 0))]
18757   "! optimize_size
18758    && ! TARGET_USE_MOV0
18759    && TARGET_SPLIT_LONG_MOVES
18760    && get_attr_length (insn) >= ix86_cost->large_insn
18761    && peep2_regno_dead_p (0, FLAGS_REG)"
18762   [(parallel [(set (match_dup 1) (const_int 0))
18763               (clobber (reg:CC FLAGS_REG))])
18764    (set (match_dup 0) (match_dup 1))]
18765   "")
18766
18767 (define_peephole2
18768   [(match_scratch:HI 1 "r")
18769    (set (match_operand:HI 0 "memory_operand" "")
18770         (const_int 0))]
18771   "! optimize_size
18772    && ! TARGET_USE_MOV0
18773    && TARGET_SPLIT_LONG_MOVES
18774    && get_attr_length (insn) >= ix86_cost->large_insn
18775    && peep2_regno_dead_p (0, FLAGS_REG)"
18776   [(parallel [(set (match_dup 2) (const_int 0))
18777               (clobber (reg:CC FLAGS_REG))])
18778    (set (match_dup 0) (match_dup 1))]
18779   "operands[2] = gen_lowpart (SImode, operands[1]);")
18780
18781 (define_peephole2
18782   [(match_scratch:QI 1 "q")
18783    (set (match_operand:QI 0 "memory_operand" "")
18784         (const_int 0))]
18785   "! optimize_size
18786    && ! TARGET_USE_MOV0
18787    && TARGET_SPLIT_LONG_MOVES
18788    && get_attr_length (insn) >= ix86_cost->large_insn
18789    && peep2_regno_dead_p (0, FLAGS_REG)"
18790   [(parallel [(set (match_dup 2) (const_int 0))
18791               (clobber (reg:CC FLAGS_REG))])
18792    (set (match_dup 0) (match_dup 1))]
18793   "operands[2] = gen_lowpart (SImode, operands[1]);")
18794
18795 (define_peephole2
18796   [(match_scratch:SI 2 "r")
18797    (set (match_operand:SI 0 "memory_operand" "")
18798         (match_operand:SI 1 "immediate_operand" ""))]
18799   "! optimize_size
18800    && get_attr_length (insn) >= ix86_cost->large_insn
18801    && TARGET_SPLIT_LONG_MOVES"
18802   [(set (match_dup 2) (match_dup 1))
18803    (set (match_dup 0) (match_dup 2))]
18804   "")
18805
18806 (define_peephole2
18807   [(match_scratch:HI 2 "r")
18808    (set (match_operand:HI 0 "memory_operand" "")
18809         (match_operand:HI 1 "immediate_operand" ""))]
18810   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18811   && TARGET_SPLIT_LONG_MOVES"
18812   [(set (match_dup 2) (match_dup 1))
18813    (set (match_dup 0) (match_dup 2))]
18814   "")
18815
18816 (define_peephole2
18817   [(match_scratch:QI 2 "q")
18818    (set (match_operand:QI 0 "memory_operand" "")
18819         (match_operand:QI 1 "immediate_operand" ""))]
18820   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18821   && TARGET_SPLIT_LONG_MOVES"
18822   [(set (match_dup 2) (match_dup 1))
18823    (set (match_dup 0) (match_dup 2))]
18824   "")
18825
18826 ;; Don't compare memory with zero, load and use a test instead.
18827 (define_peephole2
18828   [(set (match_operand 0 "flags_reg_operand" "")
18829         (match_operator 1 "compare_operator"
18830           [(match_operand:SI 2 "memory_operand" "")
18831            (const_int 0)]))
18832    (match_scratch:SI 3 "r")]
18833   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18834   [(set (match_dup 3) (match_dup 2))
18835    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18836   "")
18837
18838 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18839 ;; Don't split NOTs with a displacement operand, because resulting XOR
18840 ;; will not be pairable anyway.
18841 ;;
18842 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18843 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18844 ;; so this split helps here as well.
18845 ;;
18846 ;; Note: Can't do this as a regular split because we can't get proper
18847 ;; lifetime information then.
18848
18849 (define_peephole2
18850   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18851         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18852   "!optimize_size
18853    && peep2_regno_dead_p (0, FLAGS_REG)
18854    && ((TARGET_PENTIUM 
18855         && (GET_CODE (operands[0]) != MEM
18856             || !memory_displacement_operand (operands[0], SImode)))
18857        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18858   [(parallel [(set (match_dup 0)
18859                    (xor:SI (match_dup 1) (const_int -1)))
18860               (clobber (reg:CC FLAGS_REG))])]
18861   "")
18862
18863 (define_peephole2
18864   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18865         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18866   "!optimize_size
18867    && peep2_regno_dead_p (0, FLAGS_REG)
18868    && ((TARGET_PENTIUM 
18869         && (GET_CODE (operands[0]) != MEM
18870             || !memory_displacement_operand (operands[0], HImode)))
18871        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18872   [(parallel [(set (match_dup 0)
18873                    (xor:HI (match_dup 1) (const_int -1)))
18874               (clobber (reg:CC FLAGS_REG))])]
18875   "")
18876
18877 (define_peephole2
18878   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18879         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18880   "!optimize_size
18881    && peep2_regno_dead_p (0, FLAGS_REG)
18882    && ((TARGET_PENTIUM 
18883         && (GET_CODE (operands[0]) != MEM
18884             || !memory_displacement_operand (operands[0], QImode)))
18885        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18886   [(parallel [(set (match_dup 0)
18887                    (xor:QI (match_dup 1) (const_int -1)))
18888               (clobber (reg:CC FLAGS_REG))])]
18889   "")
18890
18891 ;; Non pairable "test imm, reg" instructions can be translated to
18892 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18893 ;; byte opcode instead of two, have a short form for byte operands),
18894 ;; so do it for other CPUs as well.  Given that the value was dead,
18895 ;; this should not create any new dependencies.  Pass on the sub-word
18896 ;; versions if we're concerned about partial register stalls.
18897
18898 (define_peephole2
18899   [(set (match_operand 0 "flags_reg_operand" "")
18900         (match_operator 1 "compare_operator"
18901           [(and:SI (match_operand:SI 2 "register_operand" "")
18902                    (match_operand:SI 3 "immediate_operand" ""))
18903            (const_int 0)]))]
18904   "ix86_match_ccmode (insn, CCNOmode)
18905    && (true_regnum (operands[2]) != 0
18906        || (GET_CODE (operands[3]) == CONST_INT
18907            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18908    && peep2_reg_dead_p (1, operands[2])"
18909   [(parallel
18910      [(set (match_dup 0)
18911            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18912                             (const_int 0)]))
18913       (set (match_dup 2)
18914            (and:SI (match_dup 2) (match_dup 3)))])]
18915   "")
18916
18917 ;; We don't need to handle HImode case, because it will be promoted to SImode
18918 ;; on ! TARGET_PARTIAL_REG_STALL
18919
18920 (define_peephole2
18921   [(set (match_operand 0 "flags_reg_operand" "")
18922         (match_operator 1 "compare_operator"
18923           [(and:QI (match_operand:QI 2 "register_operand" "")
18924                    (match_operand:QI 3 "immediate_operand" ""))
18925            (const_int 0)]))]
18926   "! TARGET_PARTIAL_REG_STALL
18927    && ix86_match_ccmode (insn, CCNOmode)
18928    && true_regnum (operands[2]) != 0
18929    && peep2_reg_dead_p (1, operands[2])"
18930   [(parallel
18931      [(set (match_dup 0)
18932            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18933                             (const_int 0)]))
18934       (set (match_dup 2)
18935            (and:QI (match_dup 2) (match_dup 3)))])]
18936   "")
18937
18938 (define_peephole2
18939   [(set (match_operand 0 "flags_reg_operand" "")
18940         (match_operator 1 "compare_operator"
18941           [(and:SI
18942              (zero_extract:SI
18943                (match_operand 2 "ext_register_operand" "")
18944                (const_int 8)
18945                (const_int 8))
18946              (match_operand 3 "const_int_operand" ""))
18947            (const_int 0)]))]
18948   "! TARGET_PARTIAL_REG_STALL
18949    && ix86_match_ccmode (insn, CCNOmode)
18950    && true_regnum (operands[2]) != 0
18951    && peep2_reg_dead_p (1, operands[2])"
18952   [(parallel [(set (match_dup 0)
18953                    (match_op_dup 1
18954                      [(and:SI
18955                         (zero_extract:SI
18956                           (match_dup 2)
18957                           (const_int 8)
18958                           (const_int 8))
18959                         (match_dup 3))
18960                       (const_int 0)]))
18961               (set (zero_extract:SI (match_dup 2)
18962                                     (const_int 8)
18963                                     (const_int 8))
18964                    (and:SI 
18965                      (zero_extract:SI
18966                        (match_dup 2)
18967                        (const_int 8)
18968                        (const_int 8))
18969                      (match_dup 3)))])]
18970   "")
18971
18972 ;; Don't do logical operations with memory inputs.
18973 (define_peephole2
18974   [(match_scratch:SI 2 "r")
18975    (parallel [(set (match_operand:SI 0 "register_operand" "")
18976                    (match_operator:SI 3 "arith_or_logical_operator"
18977                      [(match_dup 0)
18978                       (match_operand:SI 1 "memory_operand" "")]))
18979               (clobber (reg:CC FLAGS_REG))])]
18980   "! optimize_size && ! TARGET_READ_MODIFY"
18981   [(set (match_dup 2) (match_dup 1))
18982    (parallel [(set (match_dup 0)
18983                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18984               (clobber (reg:CC FLAGS_REG))])]
18985   "")
18986
18987 (define_peephole2
18988   [(match_scratch:SI 2 "r")
18989    (parallel [(set (match_operand:SI 0 "register_operand" "")
18990                    (match_operator:SI 3 "arith_or_logical_operator"
18991                      [(match_operand:SI 1 "memory_operand" "")
18992                       (match_dup 0)]))
18993               (clobber (reg:CC FLAGS_REG))])]
18994   "! optimize_size && ! TARGET_READ_MODIFY"
18995   [(set (match_dup 2) (match_dup 1))
18996    (parallel [(set (match_dup 0)
18997                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18998               (clobber (reg:CC FLAGS_REG))])]
18999   "")
19000
19001 ; Don't do logical operations with memory outputs
19002 ;
19003 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19004 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19005 ; the same decoder scheduling characteristics as the original.
19006
19007 (define_peephole2
19008   [(match_scratch:SI 2 "r")
19009    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19010                    (match_operator:SI 3 "arith_or_logical_operator"
19011                      [(match_dup 0)
19012                       (match_operand:SI 1 "nonmemory_operand" "")]))
19013               (clobber (reg:CC FLAGS_REG))])]
19014   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19015   [(set (match_dup 2) (match_dup 0))
19016    (parallel [(set (match_dup 2)
19017                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19018               (clobber (reg:CC FLAGS_REG))])
19019    (set (match_dup 0) (match_dup 2))]
19020   "")
19021
19022 (define_peephole2
19023   [(match_scratch:SI 2 "r")
19024    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19025                    (match_operator:SI 3 "arith_or_logical_operator"
19026                      [(match_operand:SI 1 "nonmemory_operand" "")
19027                       (match_dup 0)]))
19028               (clobber (reg:CC FLAGS_REG))])]
19029   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19030   [(set (match_dup 2) (match_dup 0))
19031    (parallel [(set (match_dup 2)
19032                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19033               (clobber (reg:CC FLAGS_REG))])
19034    (set (match_dup 0) (match_dup 2))]
19035   "")
19036
19037 ;; Attempt to always use XOR for zeroing registers.
19038 (define_peephole2
19039   [(set (match_operand 0 "register_operand" "")
19040         (const_int 0))]
19041   "(GET_MODE (operands[0]) == QImode
19042     || GET_MODE (operands[0]) == HImode
19043     || GET_MODE (operands[0]) == SImode
19044     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19045    && (! TARGET_USE_MOV0 || optimize_size)
19046    && peep2_regno_dead_p (0, FLAGS_REG)"
19047   [(parallel [(set (match_dup 0) (const_int 0))
19048               (clobber (reg:CC FLAGS_REG))])]
19049   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19050                               operands[0]);")
19051
19052 (define_peephole2
19053   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19054         (const_int 0))]
19055   "(GET_MODE (operands[0]) == QImode
19056     || GET_MODE (operands[0]) == HImode)
19057    && (! TARGET_USE_MOV0 || optimize_size)
19058    && peep2_regno_dead_p (0, FLAGS_REG)"
19059   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19060               (clobber (reg:CC FLAGS_REG))])])
19061
19062 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19063 (define_peephole2
19064   [(set (match_operand 0 "register_operand" "")
19065         (const_int -1))]
19066   "(GET_MODE (operands[0]) == HImode
19067     || GET_MODE (operands[0]) == SImode 
19068     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19069    && (optimize_size || TARGET_PENTIUM)
19070    && peep2_regno_dead_p (0, FLAGS_REG)"
19071   [(parallel [(set (match_dup 0) (const_int -1))
19072               (clobber (reg:CC FLAGS_REG))])]
19073   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19074                               operands[0]);")
19075
19076 ;; Attempt to convert simple leas to adds. These can be created by
19077 ;; move expanders.
19078 (define_peephole2
19079   [(set (match_operand:SI 0 "register_operand" "")
19080         (plus:SI (match_dup 0)
19081                  (match_operand:SI 1 "nonmemory_operand" "")))]
19082   "peep2_regno_dead_p (0, FLAGS_REG)"
19083   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19084               (clobber (reg:CC FLAGS_REG))])]
19085   "")
19086
19087 (define_peephole2
19088   [(set (match_operand:SI 0 "register_operand" "")
19089         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19090                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19091   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19092   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19093               (clobber (reg:CC FLAGS_REG))])]
19094   "operands[2] = gen_lowpart (SImode, operands[2]);")
19095
19096 (define_peephole2
19097   [(set (match_operand:DI 0 "register_operand" "")
19098         (plus:DI (match_dup 0)
19099                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19100   "peep2_regno_dead_p (0, FLAGS_REG)"
19101   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19102               (clobber (reg:CC FLAGS_REG))])]
19103   "")
19104
19105 (define_peephole2
19106   [(set (match_operand:SI 0 "register_operand" "")
19107         (mult:SI (match_dup 0)
19108                  (match_operand:SI 1 "const_int_operand" "")))]
19109   "exact_log2 (INTVAL (operands[1])) >= 0
19110    && peep2_regno_dead_p (0, FLAGS_REG)"
19111   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19112               (clobber (reg:CC FLAGS_REG))])]
19113   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19114
19115 (define_peephole2
19116   [(set (match_operand:DI 0 "register_operand" "")
19117         (mult:DI (match_dup 0)
19118                  (match_operand:DI 1 "const_int_operand" "")))]
19119   "exact_log2 (INTVAL (operands[1])) >= 0
19120    && peep2_regno_dead_p (0, FLAGS_REG)"
19121   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19122               (clobber (reg:CC FLAGS_REG))])]
19123   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19124
19125 (define_peephole2
19126   [(set (match_operand:SI 0 "register_operand" "")
19127         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19128                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19129   "exact_log2 (INTVAL (operands[2])) >= 0
19130    && REGNO (operands[0]) == REGNO (operands[1])
19131    && peep2_regno_dead_p (0, FLAGS_REG)"
19132   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19133               (clobber (reg:CC FLAGS_REG))])]
19134   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19135
19136 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19137 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19138 ;; many CPUs it is also faster, since special hardware to avoid esp
19139 ;; dependencies is present.
19140
19141 ;; While some of these conversions may be done using splitters, we use peepholes
19142 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19143
19144 ;; Convert prologue esp subtractions to push.
19145 ;; We need register to push.  In order to keep verify_flow_info happy we have
19146 ;; two choices
19147 ;; - use scratch and clobber it in order to avoid dependencies
19148 ;; - use already live register
19149 ;; We can't use the second way right now, since there is no reliable way how to
19150 ;; verify that given register is live.  First choice will also most likely in
19151 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19152 ;; call clobbered registers are dead.  We may want to use base pointer as an
19153 ;; alternative when no register is available later.
19154
19155 (define_peephole2
19156   [(match_scratch:SI 0 "r")
19157    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19158               (clobber (reg:CC FLAGS_REG))
19159               (clobber (mem:BLK (scratch)))])]
19160   "optimize_size || !TARGET_SUB_ESP_4"
19161   [(clobber (match_dup 0))
19162    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19163               (clobber (mem:BLK (scratch)))])])
19164
19165 (define_peephole2
19166   [(match_scratch:SI 0 "r")
19167    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19168               (clobber (reg:CC FLAGS_REG))
19169               (clobber (mem:BLK (scratch)))])]
19170   "optimize_size || !TARGET_SUB_ESP_8"
19171   [(clobber (match_dup 0))
19172    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19173    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19174               (clobber (mem:BLK (scratch)))])])
19175
19176 ;; Convert esp subtractions to push.
19177 (define_peephole2
19178   [(match_scratch:SI 0 "r")
19179    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19180               (clobber (reg:CC FLAGS_REG))])]
19181   "optimize_size || !TARGET_SUB_ESP_4"
19182   [(clobber (match_dup 0))
19183    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19184
19185 (define_peephole2
19186   [(match_scratch:SI 0 "r")
19187    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19188               (clobber (reg:CC FLAGS_REG))])]
19189   "optimize_size || !TARGET_SUB_ESP_8"
19190   [(clobber (match_dup 0))
19191    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19192    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19193
19194 ;; Convert epilogue deallocator to pop.
19195 (define_peephole2
19196   [(match_scratch:SI 0 "r")
19197    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19198               (clobber (reg:CC FLAGS_REG))
19199               (clobber (mem:BLK (scratch)))])]
19200   "optimize_size || !TARGET_ADD_ESP_4"
19201   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19202               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19203               (clobber (mem:BLK (scratch)))])]
19204   "")
19205
19206 ;; Two pops case is tricky, since pop causes dependency on destination register.
19207 ;; We use two registers if available.
19208 (define_peephole2
19209   [(match_scratch:SI 0 "r")
19210    (match_scratch:SI 1 "r")
19211    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19212               (clobber (reg:CC FLAGS_REG))
19213               (clobber (mem:BLK (scratch)))])]
19214   "optimize_size || !TARGET_ADD_ESP_8"
19215   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19216               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19217               (clobber (mem:BLK (scratch)))])
19218    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19219               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19220   "")
19221
19222 (define_peephole2
19223   [(match_scratch:SI 0 "r")
19224    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19225               (clobber (reg:CC FLAGS_REG))
19226               (clobber (mem:BLK (scratch)))])]
19227   "optimize_size"
19228   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19229               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19230               (clobber (mem:BLK (scratch)))])
19231    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19232               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19233   "")
19234
19235 ;; Convert esp additions to pop.
19236 (define_peephole2
19237   [(match_scratch:SI 0 "r")
19238    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19239               (clobber (reg:CC FLAGS_REG))])]
19240   ""
19241   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19242               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19243   "")
19244
19245 ;; Two pops case is tricky, since pop causes dependency on destination register.
19246 ;; We use two registers if available.
19247 (define_peephole2
19248   [(match_scratch:SI 0 "r")
19249    (match_scratch:SI 1 "r")
19250    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19251               (clobber (reg:CC FLAGS_REG))])]
19252   ""
19253   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19254               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19255    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19256               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19257   "")
19258
19259 (define_peephole2
19260   [(match_scratch:SI 0 "r")
19261    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19262               (clobber (reg:CC FLAGS_REG))])]
19263   "optimize_size"
19264   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19265               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19266    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19267               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19268   "")
19269 \f
19270 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19271 ;; required and register dies.  Similarly for 128 to plus -128.
19272 (define_peephole2
19273   [(set (match_operand 0 "flags_reg_operand" "")
19274         (match_operator 1 "compare_operator"
19275           [(match_operand 2 "register_operand" "")
19276            (match_operand 3 "const_int_operand" "")]))]
19277   "(INTVAL (operands[3]) == -1
19278     || INTVAL (operands[3]) == 1
19279     || INTVAL (operands[3]) == 128)
19280    && ix86_match_ccmode (insn, CCGCmode)
19281    && peep2_reg_dead_p (1, operands[2])"
19282   [(parallel [(set (match_dup 0)
19283                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19284               (clobber (match_dup 2))])]
19285   "")
19286 \f
19287 (define_peephole2
19288   [(match_scratch:DI 0 "r")
19289    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19290               (clobber (reg:CC FLAGS_REG))
19291               (clobber (mem:BLK (scratch)))])]
19292   "optimize_size || !TARGET_SUB_ESP_4"
19293   [(clobber (match_dup 0))
19294    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19295               (clobber (mem:BLK (scratch)))])])
19296
19297 (define_peephole2
19298   [(match_scratch:DI 0 "r")
19299    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19300               (clobber (reg:CC FLAGS_REG))
19301               (clobber (mem:BLK (scratch)))])]
19302   "optimize_size || !TARGET_SUB_ESP_8"
19303   [(clobber (match_dup 0))
19304    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19305    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19306               (clobber (mem:BLK (scratch)))])])
19307
19308 ;; Convert esp subtractions to push.
19309 (define_peephole2
19310   [(match_scratch:DI 0 "r")
19311    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19312               (clobber (reg:CC FLAGS_REG))])]
19313   "optimize_size || !TARGET_SUB_ESP_4"
19314   [(clobber (match_dup 0))
19315    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19316
19317 (define_peephole2
19318   [(match_scratch:DI 0 "r")
19319    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19320               (clobber (reg:CC FLAGS_REG))])]
19321   "optimize_size || !TARGET_SUB_ESP_8"
19322   [(clobber (match_dup 0))
19323    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19324    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19325
19326 ;; Convert epilogue deallocator to pop.
19327 (define_peephole2
19328   [(match_scratch:DI 0 "r")
19329    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19330               (clobber (reg:CC FLAGS_REG))
19331               (clobber (mem:BLK (scratch)))])]
19332   "optimize_size || !TARGET_ADD_ESP_4"
19333   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19334               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19335               (clobber (mem:BLK (scratch)))])]
19336   "")
19337
19338 ;; Two pops case is tricky, since pop causes dependency on destination register.
19339 ;; We use two registers if available.
19340 (define_peephole2
19341   [(match_scratch:DI 0 "r")
19342    (match_scratch:DI 1 "r")
19343    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19344               (clobber (reg:CC FLAGS_REG))
19345               (clobber (mem:BLK (scratch)))])]
19346   "optimize_size || !TARGET_ADD_ESP_8"
19347   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19348               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19349               (clobber (mem:BLK (scratch)))])
19350    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19351               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19352   "")
19353
19354 (define_peephole2
19355   [(match_scratch:DI 0 "r")
19356    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19357               (clobber (reg:CC FLAGS_REG))
19358               (clobber (mem:BLK (scratch)))])]
19359   "optimize_size"
19360   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19361               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19362               (clobber (mem:BLK (scratch)))])
19363    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19364               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19365   "")
19366
19367 ;; Convert esp additions to pop.
19368 (define_peephole2
19369   [(match_scratch:DI 0 "r")
19370    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19371               (clobber (reg:CC FLAGS_REG))])]
19372   ""
19373   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19374               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19375   "")
19376
19377 ;; Two pops case is tricky, since pop causes dependency on destination register.
19378 ;; We use two registers if available.
19379 (define_peephole2
19380   [(match_scratch:DI 0 "r")
19381    (match_scratch:DI 1 "r")
19382    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19383               (clobber (reg:CC FLAGS_REG))])]
19384   ""
19385   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19386               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19387    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19388               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19389   "")
19390
19391 (define_peephole2
19392   [(match_scratch:DI 0 "r")
19393    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19394               (clobber (reg:CC FLAGS_REG))])]
19395   "optimize_size"
19396   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19397               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19398    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19399               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19400   "")
19401 \f
19402 ;; Convert imul by three, five and nine into lea
19403 (define_peephole2
19404   [(parallel
19405     [(set (match_operand:SI 0 "register_operand" "")
19406           (mult:SI (match_operand:SI 1 "register_operand" "")
19407                    (match_operand:SI 2 "const_int_operand" "")))
19408      (clobber (reg:CC FLAGS_REG))])]
19409   "INTVAL (operands[2]) == 3
19410    || INTVAL (operands[2]) == 5
19411    || INTVAL (operands[2]) == 9"
19412   [(set (match_dup 0)
19413         (plus:SI (mult:SI (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:SI 0 "register_operand" "")
19420           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19421                    (match_operand:SI 2 "const_int_operand" "")))
19422      (clobber (reg:CC FLAGS_REG))])]
19423   "!optimize_size 
19424    && (INTVAL (operands[2]) == 3
19425        || INTVAL (operands[2]) == 5
19426        || INTVAL (operands[2]) == 9)"
19427   [(set (match_dup 0) (match_dup 1))
19428    (set (match_dup 0)
19429         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19430                  (match_dup 0)))]
19431   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19432
19433 (define_peephole2
19434   [(parallel
19435     [(set (match_operand:DI 0 "register_operand" "")
19436           (mult:DI (match_operand:DI 1 "register_operand" "")
19437                    (match_operand:DI 2 "const_int_operand" "")))
19438      (clobber (reg:CC FLAGS_REG))])]
19439   "TARGET_64BIT
19440    && (INTVAL (operands[2]) == 3
19441        || INTVAL (operands[2]) == 5
19442        || INTVAL (operands[2]) == 9)"
19443   [(set (match_dup 0)
19444         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19445                  (match_dup 1)))]
19446   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19447
19448 (define_peephole2
19449   [(parallel
19450     [(set (match_operand:DI 0 "register_operand" "")
19451           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19452                    (match_operand:DI 2 "const_int_operand" "")))
19453      (clobber (reg:CC FLAGS_REG))])]
19454   "TARGET_64BIT
19455    && !optimize_size 
19456    && (INTVAL (operands[2]) == 3
19457        || INTVAL (operands[2]) == 5
19458        || INTVAL (operands[2]) == 9)"
19459   [(set (match_dup 0) (match_dup 1))
19460    (set (match_dup 0)
19461         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19462                  (match_dup 0)))]
19463   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19464
19465 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19466 ;; imul $32bit_imm, reg, reg is direct decoded.
19467 (define_peephole2
19468   [(match_scratch:DI 3 "r")
19469    (parallel [(set (match_operand:DI 0 "register_operand" "")
19470                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19471                             (match_operand:DI 2 "immediate_operand" "")))
19472               (clobber (reg:CC FLAGS_REG))])]
19473   "TARGET_K8 && !optimize_size
19474    && (GET_CODE (operands[2]) != CONST_INT
19475        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19476   [(set (match_dup 3) (match_dup 1))
19477    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19478               (clobber (reg:CC FLAGS_REG))])]
19479 "")
19480
19481 (define_peephole2
19482   [(match_scratch:SI 3 "r")
19483    (parallel [(set (match_operand:SI 0 "register_operand" "")
19484                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19485                             (match_operand:SI 2 "immediate_operand" "")))
19486               (clobber (reg:CC FLAGS_REG))])]
19487   "TARGET_K8 && !optimize_size
19488    && (GET_CODE (operands[2]) != CONST_INT
19489        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19490   [(set (match_dup 3) (match_dup 1))
19491    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19492               (clobber (reg:CC FLAGS_REG))])]
19493 "")
19494
19495 (define_peephole2
19496   [(match_scratch:SI 3 "r")
19497    (parallel [(set (match_operand:DI 0 "register_operand" "")
19498                    (zero_extend:DI
19499                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19500                               (match_operand:SI 2 "immediate_operand" ""))))
19501               (clobber (reg:CC FLAGS_REG))])]
19502   "TARGET_K8 && !optimize_size
19503    && (GET_CODE (operands[2]) != CONST_INT
19504        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19505   [(set (match_dup 3) (match_dup 1))
19506    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19507               (clobber (reg:CC FLAGS_REG))])]
19508 "")
19509
19510 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19511 ;; Convert it into imul reg, reg
19512 ;; It would be better to force assembler to encode instruction using long
19513 ;; immediate, but there is apparently no way to do so.
19514 (define_peephole2
19515   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19516                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19517                             (match_operand:DI 2 "const_int_operand" "")))
19518               (clobber (reg:CC FLAGS_REG))])
19519    (match_scratch:DI 3 "r")]
19520   "TARGET_K8 && !optimize_size
19521    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19522   [(set (match_dup 3) (match_dup 2))
19523    (parallel [(set (match_dup 0) (mult:DI (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
19530 (define_peephole2
19531   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19532                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19533                             (match_operand:SI 2 "const_int_operand" "")))
19534               (clobber (reg:CC FLAGS_REG))])
19535    (match_scratch:SI 3 "r")]
19536   "TARGET_K8 && !optimize_size
19537    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19538   [(set (match_dup 3) (match_dup 2))
19539    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19540               (clobber (reg:CC FLAGS_REG))])]
19541 {
19542   if (!rtx_equal_p (operands[0], operands[1]))
19543     emit_move_insn (operands[0], operands[1]);
19544 })
19545
19546 (define_peephole2
19547   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19548                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19549                             (match_operand:HI 2 "immediate_operand" "")))
19550               (clobber (reg:CC FLAGS_REG))])
19551    (match_scratch:HI 3 "r")]
19552   "TARGET_K8 && !optimize_size"
19553   [(set (match_dup 3) (match_dup 2))
19554    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19555               (clobber (reg:CC FLAGS_REG))])]
19556 {
19557   if (!rtx_equal_p (operands[0], operands[1]))
19558     emit_move_insn (operands[0], operands[1]);
19559 })
19560 \f
19561 ;; Call-value patterns last so that the wildcard operand does not
19562 ;; disrupt insn-recog's switch tables.
19563
19564 (define_insn "*call_value_pop_0"
19565   [(set (match_operand 0 "" "")
19566         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19567               (match_operand:SI 2 "" "")))
19568    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19569                             (match_operand:SI 3 "immediate_operand" "")))]
19570   "!TARGET_64BIT"
19571 {
19572   if (SIBLING_CALL_P (insn))
19573     return "jmp\t%P1";
19574   else
19575     return "call\t%P1";
19576 }
19577   [(set_attr "type" "callv")])
19578
19579 (define_insn "*call_value_pop_1"
19580   [(set (match_operand 0 "" "")
19581         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19582               (match_operand:SI 2 "" "")))
19583    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19584                             (match_operand:SI 3 "immediate_operand" "i")))]
19585   "!TARGET_64BIT"
19586 {
19587   if (constant_call_address_operand (operands[1], Pmode))
19588     {
19589       if (SIBLING_CALL_P (insn))
19590         return "jmp\t%P1";
19591       else
19592         return "call\t%P1";
19593     }
19594   if (SIBLING_CALL_P (insn))
19595     return "jmp\t%A1";
19596   else
19597     return "call\t%A1";
19598 }
19599   [(set_attr "type" "callv")])
19600
19601 (define_insn "*call_value_0"
19602   [(set (match_operand 0 "" "")
19603         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19604               (match_operand:SI 2 "" "")))]
19605   "!TARGET_64BIT"
19606 {
19607   if (SIBLING_CALL_P (insn))
19608     return "jmp\t%P1";
19609   else
19610     return "call\t%P1";
19611 }
19612   [(set_attr "type" "callv")])
19613
19614 (define_insn "*call_value_0_rex64"
19615   [(set (match_operand 0 "" "")
19616         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19617               (match_operand:DI 2 "const_int_operand" "")))]
19618   "TARGET_64BIT"
19619 {
19620   if (SIBLING_CALL_P (insn))
19621     return "jmp\t%P1";
19622   else
19623     return "call\t%P1";
19624 }
19625   [(set_attr "type" "callv")])
19626
19627 (define_insn "*call_value_1"
19628   [(set (match_operand 0 "" "")
19629         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19630               (match_operand:SI 2 "" "")))]
19631   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19632 {
19633   if (constant_call_address_operand (operands[1], Pmode))
19634     return "call\t%P1";
19635   return "call\t%A1";
19636 }
19637   [(set_attr "type" "callv")])
19638
19639 (define_insn "*sibcall_value_1"
19640   [(set (match_operand 0 "" "")
19641         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19642               (match_operand:SI 2 "" "")))]
19643   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19644 {
19645   if (constant_call_address_operand (operands[1], Pmode))
19646     return "jmp\t%P1";
19647   return "jmp\t%A1";
19648 }
19649   [(set_attr "type" "callv")])
19650
19651 (define_insn "*call_value_1_rex64"
19652   [(set (match_operand 0 "" "")
19653         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19654               (match_operand:DI 2 "" "")))]
19655   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19656 {
19657   if (constant_call_address_operand (operands[1], Pmode))
19658     return "call\t%P1";
19659   return "call\t%A1";
19660 }
19661   [(set_attr "type" "callv")])
19662
19663 (define_insn "*sibcall_value_1_rex64"
19664   [(set (match_operand 0 "" "")
19665         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19666               (match_operand:DI 2 "" "")))]
19667   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19668   "jmp\t%P1"
19669   [(set_attr "type" "callv")])
19670
19671 (define_insn "*sibcall_value_1_rex64_v"
19672   [(set (match_operand 0 "" "")
19673         (call (mem:QI (reg:DI 40))
19674               (match_operand:DI 1 "" "")))]
19675   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19676   "jmp\t*%%r11"
19677   [(set_attr "type" "callv")])
19678 \f
19679 (define_insn "trap"
19680   [(trap_if (const_int 1) (const_int 5))]
19681   ""
19682   "int\t$5")
19683
19684 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19685 ;;; for the sake of bounds checking.  By emitting bounds checks as
19686 ;;; conditional traps rather than as conditional jumps around
19687 ;;; unconditional traps we avoid introducing spurious basic-block
19688 ;;; boundaries and facilitate elimination of redundant checks.  In
19689 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19690 ;;; interrupt 5.
19691 ;;; 
19692 ;;; FIXME: Static branch prediction rules for ix86 are such that
19693 ;;; forward conditional branches predict as untaken.  As implemented
19694 ;;; below, pseudo conditional traps violate that rule.  We should use
19695 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19696 ;;; section loaded at the end of the text segment and branch forward
19697 ;;; there on bounds-failure, and then jump back immediately (in case
19698 ;;; the system chooses to ignore bounds violations, or to report
19699 ;;; violations and continue execution).
19700
19701 (define_expand "conditional_trap"
19702   [(trap_if (match_operator 0 "comparison_operator"
19703              [(match_dup 2) (const_int 0)])
19704             (match_operand 1 "const_int_operand" ""))]
19705   ""
19706 {
19707   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19708                               ix86_expand_compare (GET_CODE (operands[0]),
19709                                                    NULL, NULL),
19710                               operands[1]));
19711   DONE;
19712 })
19713
19714 (define_insn "*conditional_trap_1"
19715   [(trap_if (match_operator 0 "comparison_operator"
19716              [(reg FLAGS_REG) (const_int 0)])
19717             (match_operand 1 "const_int_operand" ""))]
19718   ""
19719 {
19720   operands[2] = gen_label_rtx ();
19721   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19722   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19723                              CODE_LABEL_NUMBER (operands[2]));
19724   RET;
19725 })
19726
19727         ;; Pentium III SIMD instructions.
19728
19729 ;; Moves for SSE/MMX regs.
19730
19731 (define_insn "movv4sf_internal"
19732   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19733         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19734   "TARGET_SSE"
19735   "@
19736     xorps\t%0, %0
19737     movaps\t{%1, %0|%0, %1}
19738     movaps\t{%1, %0|%0, %1}"
19739   [(set_attr "type" "ssemov")
19740    (set_attr "mode" "V4SF")])
19741
19742 (define_split
19743   [(set (match_operand:V4SF 0 "register_operand" "")
19744         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19745   "TARGET_SSE && reload_completed"
19746   [(set (match_dup 0)
19747         (vec_merge:V4SF
19748          (vec_duplicate:V4SF (match_dup 1))
19749          (match_dup 2)
19750          (const_int 1)))]
19751 {
19752   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19753   operands[2] = CONST0_RTX (V4SFmode);
19754 })
19755
19756 (define_insn "movv4si_internal"
19757   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
19758         (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
19759   "TARGET_SSE"
19760 {
19761   switch (which_alternative)
19762     {
19763     case 0:
19764       if (get_attr_mode (insn) == MODE_V4SF)
19765         return "xorps\t%0, %0";
19766       else
19767         return "pxor\t%0, %0";
19768     case 1:
19769     case 2:
19770       if (get_attr_mode (insn) == MODE_V4SF)
19771         return "movaps\t{%1, %0|%0, %1}";
19772       else
19773         return "movdqa\t{%1, %0|%0, %1}";
19774     default:
19775       abort ();
19776     }
19777 }
19778   [(set_attr "type" "ssemov")
19779    (set (attr "mode")
19780         (cond [(eq_attr "alternative" "0,1")
19781                  (if_then_else
19782                    (ne (symbol_ref "optimize_size")
19783                        (const_int 0))
19784                    (const_string "V4SF")
19785                    (const_string "TI"))
19786                (eq_attr "alternative" "2")
19787                  (if_then_else
19788                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19789                             (const_int 0))
19790                         (ne (symbol_ref "optimize_size")
19791                             (const_int 0)))
19792                    (const_string "V4SF")
19793                    (const_string "TI"))]
19794                (const_string "TI")))])
19795
19796 (define_insn "movv2di_internal"
19797   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
19798         (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
19799   "TARGET_SSE"
19800 {
19801   switch (which_alternative)
19802     {
19803     case 0:
19804       if (get_attr_mode (insn) == MODE_V4SF)
19805         return "xorps\t%0, %0";
19806       else
19807         return "pxor\t%0, %0";
19808     case 1:
19809     case 2:
19810       if (get_attr_mode (insn) == MODE_V4SF)
19811         return "movaps\t{%1, %0|%0, %1}";
19812       else
19813         return "movdqa\t{%1, %0|%0, %1}";
19814     default:
19815       abort ();
19816     }
19817 }
19818   [(set_attr "type" "ssemov")
19819    (set (attr "mode")
19820         (cond [(eq_attr "alternative" "0,1")
19821                  (if_then_else
19822                    (ne (symbol_ref "optimize_size")
19823                        (const_int 0))
19824                    (const_string "V4SF")
19825                    (const_string "TI"))
19826                (eq_attr "alternative" "2")
19827                  (if_then_else
19828                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19829                             (const_int 0))
19830                         (ne (symbol_ref "optimize_size")
19831                             (const_int 0)))
19832                    (const_string "V4SF")
19833                    (const_string "TI"))]
19834                (const_string "TI")))])
19835
19836 (define_split
19837   [(set (match_operand:V2DF 0 "register_operand" "")
19838         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19839   "TARGET_SSE2 && reload_completed"
19840   [(set (match_dup 0)
19841         (vec_merge:V2DF
19842          (vec_duplicate:V2DF (match_dup 1))
19843          (match_dup 2)
19844          (const_int 1)))]
19845 {
19846   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19847   operands[2] = CONST0_RTX (V2DFmode);
19848 })
19849
19850 (define_insn "movv8qi_internal"
19851   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19852         (match_operand:V8QI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19853   "TARGET_MMX
19854    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19855   "@
19856     pxor\t%0, %0
19857     movq\t{%1, %0|%0, %1}
19858     movq\t{%1, %0|%0, %1}
19859     movdq2q\t{%1, %0|%0, %1}
19860     movq2dq\t{%1, %0|%0, %1}
19861     movq\t{%1, %0|%0, %1}
19862     movq\t{%1, %0|%0, %1}"
19863   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19864    (set_attr "mode" "DI")])
19865
19866 (define_insn "movv4hi_internal"
19867   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19868         (match_operand:V4HI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19869   "TARGET_MMX
19870    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19871   "@
19872     pxor\t%0, %0
19873     movq\t{%1, %0|%0, %1}
19874     movq\t{%1, %0|%0, %1}
19875     movdq2q\t{%1, %0|%0, %1}
19876     movq2dq\t{%1, %0|%0, %1}
19877     movq\t{%1, %0|%0, %1}
19878     movq\t{%1, %0|%0, %1}"
19879   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19880    (set_attr "mode" "DI")])
19881
19882 (define_insn "*movv2si_internal"
19883   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19884         (match_operand:V2SI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19885   "TARGET_MMX
19886    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19887   "@
19888     pxor\t%0, %0
19889     movq\t{%1, %0|%0, %1}
19890     movq\t{%1, %0|%0, %1}
19891     movdq2q\t{%1, %0|%0, %1}
19892     movq2dq\t{%1, %0|%0, %1}
19893     movq\t{%1, %0|%0, %1}
19894     movq\t{%1, %0|%0, %1}"
19895   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19896    (set_attr "mode" "DI")])
19897
19898 (define_insn "movv2sf_internal"
19899   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*x,?m")
19900         (match_operand:V2SF 1 "vector_move_operand" "C,ym,y,*Y,y,*xm,*x"))]
19901   "TARGET_3DNOW
19902    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19903   "@
19904     pxor\t%0, %0
19905     movq\t{%1, %0|%0, %1}
19906     movq\t{%1, %0|%0, %1}
19907     movdq2q\t{%1, %0|%0, %1}
19908     movq2dq\t{%1, %0|%0, %1}
19909     movlps\t{%1, %0|%0, %1}
19910     movlps\t{%1, %0|%0, %1}"
19911   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19912    (set_attr "mode" "DI,DI,DI,DI,DI,V2SF,V2SF")])
19913
19914 (define_expand "movti"
19915   [(set (match_operand:TI 0 "nonimmediate_operand" "")
19916         (match_operand:TI 1 "nonimmediate_operand" ""))]
19917   "TARGET_SSE || TARGET_64BIT"
19918 {
19919   if (TARGET_64BIT)
19920     ix86_expand_move (TImode, operands);
19921   else
19922     ix86_expand_vector_move (TImode, operands);
19923   DONE;
19924 })
19925
19926 (define_expand "movtf"
19927   [(set (match_operand:TF 0 "nonimmediate_operand" "")
19928         (match_operand:TF 1 "nonimmediate_operand" ""))]
19929   "TARGET_64BIT"
19930 {
19931   if (TARGET_64BIT)
19932     ix86_expand_move (TFmode, operands);
19933   else
19934     ix86_expand_vector_move (TFmode, operands);
19935   DONE;
19936 })
19937
19938 (define_insn "movv2df_internal"
19939   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19940         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19941   "TARGET_SSE2
19942    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19943 {
19944   switch (which_alternative)
19945     {
19946     case 0:
19947       if (get_attr_mode (insn) == MODE_V4SF)
19948         return "xorps\t%0, %0";
19949       else
19950         return "xorpd\t%0, %0";
19951     case 1:
19952     case 2:
19953       if (get_attr_mode (insn) == MODE_V4SF)
19954         return "movaps\t{%1, %0|%0, %1}";
19955       else
19956         return "movapd\t{%1, %0|%0, %1}";
19957     default:
19958       abort ();
19959     }
19960 }
19961   [(set_attr "type" "ssemov")
19962    (set (attr "mode")
19963         (cond [(eq_attr "alternative" "0,1")
19964                  (if_then_else
19965                    (ne (symbol_ref "optimize_size")
19966                        (const_int 0))
19967                    (const_string "V4SF")
19968                    (const_string "V2DF"))
19969                (eq_attr "alternative" "2")
19970                  (if_then_else
19971                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19972                             (const_int 0))
19973                         (ne (symbol_ref "optimize_size")
19974                             (const_int 0)))
19975                    (const_string "V4SF")
19976                    (const_string "V2DF"))]
19977                (const_string "V2DF")))])
19978
19979 (define_insn "movv8hi_internal"
19980   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
19981         (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
19982   "TARGET_SSE2
19983    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19984 {
19985   switch (which_alternative)
19986     {
19987     case 0:
19988       if (get_attr_mode (insn) == MODE_V4SF)
19989         return "xorps\t%0, %0";
19990       else
19991         return "pxor\t%0, %0";
19992     case 1:
19993     case 2:
19994       if (get_attr_mode (insn) == MODE_V4SF)
19995         return "movaps\t{%1, %0|%0, %1}";
19996       else
19997         return "movdqa\t{%1, %0|%0, %1}";
19998     default:
19999       abort ();
20000     }
20001 }
20002   [(set_attr "type" "ssemov")
20003    (set (attr "mode")
20004         (cond [(eq_attr "alternative" "0,1")
20005                  (if_then_else
20006                    (ne (symbol_ref "optimize_size")
20007                        (const_int 0))
20008                    (const_string "V4SF")
20009                    (const_string "TI"))
20010                (eq_attr "alternative" "2")
20011                  (if_then_else
20012                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20013                             (const_int 0))
20014                         (ne (symbol_ref "optimize_size")
20015                             (const_int 0)))
20016                    (const_string "V4SF")
20017                    (const_string "TI"))]
20018                (const_string "TI")))])
20019
20020 (define_insn "movv16qi_internal"
20021   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
20022         (match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
20023   "TARGET_SSE2
20024    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20025 {
20026   switch (which_alternative)
20027     {
20028     case 0:
20029       if (get_attr_mode (insn) == MODE_V4SF)
20030         return "xorps\t%0, %0";
20031       else
20032         return "pxor\t%0, %0";
20033     case 1:
20034     case 2:
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")
20044    (set (attr "mode")
20045         (cond [(eq_attr "alternative" "0,1")
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" "2")
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 "TI")))])
20060
20061 (define_expand "movv2df"
20062   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
20063         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
20064   "TARGET_SSE2"
20065 {
20066   ix86_expand_vector_move (V2DFmode, operands);
20067   DONE;
20068 })
20069
20070 (define_expand "movv8hi"
20071   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
20072         (match_operand:V8HI 1 "nonimmediate_operand" ""))]
20073   "TARGET_SSE2"
20074 {
20075   ix86_expand_vector_move (V8HImode, operands);
20076   DONE;
20077 })
20078
20079 (define_expand "movv16qi"
20080   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
20081         (match_operand:V16QI 1 "nonimmediate_operand" ""))]
20082   "TARGET_SSE2"
20083 {
20084   ix86_expand_vector_move (V16QImode, operands);
20085   DONE;
20086 })
20087
20088 (define_expand "movv4sf"
20089   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20090         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
20091   "TARGET_SSE"
20092 {
20093   ix86_expand_vector_move (V4SFmode, operands);
20094   DONE;
20095 })
20096
20097 (define_expand "movv4si"
20098   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
20099         (match_operand:V4SI 1 "nonimmediate_operand" ""))]
20100   "TARGET_SSE"
20101 {
20102   ix86_expand_vector_move (V4SImode, operands);
20103   DONE;
20104 })
20105
20106 (define_expand "movv2di"
20107   [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
20108         (match_operand:V2DI 1 "nonimmediate_operand" ""))]
20109   "TARGET_SSE"
20110 {
20111   ix86_expand_vector_move (V2DImode, operands);
20112   DONE;
20113 })
20114
20115 (define_expand "movv2si"
20116   [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
20117         (match_operand:V2SI 1 "nonimmediate_operand" ""))]
20118   "TARGET_MMX"
20119 {
20120   ix86_expand_vector_move (V2SImode, operands);
20121   DONE;
20122 })
20123
20124 (define_expand "movv4hi"
20125   [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
20126         (match_operand:V4HI 1 "nonimmediate_operand" ""))]
20127   "TARGET_MMX"
20128 {
20129   ix86_expand_vector_move (V4HImode, operands);
20130   DONE;
20131 })
20132
20133 (define_expand "movv8qi"
20134   [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
20135         (match_operand:V8QI 1 "nonimmediate_operand" ""))]
20136   "TARGET_MMX"
20137 {
20138   ix86_expand_vector_move (V8QImode, operands);
20139   DONE;
20140 })
20141
20142 (define_expand "movv2sf"
20143   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
20144         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
20145    "TARGET_3DNOW"
20146 {
20147   ix86_expand_vector_move (V2SFmode, operands);
20148   DONE;
20149 })
20150
20151 (define_insn "*pushti"
20152   [(set (match_operand:TI 0 "push_operand" "=<")
20153         (match_operand:TI 1 "register_operand" "x"))]
20154   "TARGET_SSE"
20155   "#")
20156
20157 (define_insn "*pushv2df"
20158   [(set (match_operand:V2DF 0 "push_operand" "=<")
20159         (match_operand:V2DF 1 "register_operand" "x"))]
20160   "TARGET_SSE"
20161   "#")
20162
20163 (define_insn "*pushv2di"
20164   [(set (match_operand:V2DI 0 "push_operand" "=<")
20165         (match_operand:V2DI 1 "register_operand" "x"))]
20166   "TARGET_SSE2"
20167   "#")
20168
20169 (define_insn "*pushv8hi"
20170   [(set (match_operand:V8HI 0 "push_operand" "=<")
20171         (match_operand:V8HI 1 "register_operand" "x"))]
20172   "TARGET_SSE2"
20173   "#")
20174
20175 (define_insn "*pushv16qi"
20176   [(set (match_operand:V16QI 0 "push_operand" "=<")
20177         (match_operand:V16QI 1 "register_operand" "x"))]
20178   "TARGET_SSE2"
20179   "#")
20180
20181 (define_insn "*pushv4sf"
20182   [(set (match_operand:V4SF 0 "push_operand" "=<")
20183         (match_operand:V4SF 1 "register_operand" "x"))]
20184   "TARGET_SSE"
20185   "#")
20186
20187 (define_insn "*pushv4si"
20188   [(set (match_operand:V4SI 0 "push_operand" "=<")
20189         (match_operand:V4SI 1 "register_operand" "x"))]
20190   "TARGET_SSE2"
20191   "#")
20192
20193 (define_insn "*pushv2si"
20194   [(set (match_operand:V2SI 0 "push_operand" "=<")
20195         (match_operand:V2SI 1 "register_operand" "y"))]
20196   "TARGET_MMX"
20197   "#")
20198
20199 (define_insn "*pushv4hi"
20200   [(set (match_operand:V4HI 0 "push_operand" "=<")
20201         (match_operand:V4HI 1 "register_operand" "y"))]
20202   "TARGET_MMX"
20203   "#")
20204
20205 (define_insn "*pushv8qi"
20206   [(set (match_operand:V8QI 0 "push_operand" "=<")
20207         (match_operand:V8QI 1 "register_operand" "y"))]
20208   "TARGET_MMX"
20209   "#")
20210
20211 (define_insn "*pushv2sf"
20212   [(set (match_operand:V2SF 0 "push_operand" "=<")
20213         (match_operand:V2SF 1 "register_operand" "y"))]
20214   "TARGET_3DNOW"
20215   "#")
20216
20217 (define_split
20218   [(set (match_operand 0 "push_operand" "")
20219         (match_operand 1 "register_operand" ""))]
20220   "!TARGET_64BIT && reload_completed
20221    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20222   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20223    (set (match_dup 2) (match_dup 1))]
20224   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20225                                  stack_pointer_rtx);
20226    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20227
20228 (define_split
20229   [(set (match_operand 0 "push_operand" "")
20230         (match_operand 1 "register_operand" ""))]
20231   "TARGET_64BIT && reload_completed
20232    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20233   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20234    (set (match_dup 2) (match_dup 1))]
20235   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20236                                  stack_pointer_rtx);
20237    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20238
20239
20240 (define_insn "movti_internal"
20241   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
20242         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
20243   "TARGET_SSE && !TARGET_64BIT
20244    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20245 {
20246   switch (which_alternative)
20247     {
20248     case 0:
20249       if (get_attr_mode (insn) == MODE_V4SF)
20250         return "xorps\t%0, %0";
20251       else
20252         return "pxor\t%0, %0";
20253     case 1:
20254     case 2:
20255       if (get_attr_mode (insn) == MODE_V4SF)
20256         return "movaps\t{%1, %0|%0, %1}";
20257       else
20258         return "movdqa\t{%1, %0|%0, %1}";
20259     default:
20260       abort ();
20261     }
20262 }
20263   [(set_attr "type" "ssemov,ssemov,ssemov")
20264    (set (attr "mode")
20265         (cond [(eq_attr "alternative" "0,1")
20266                  (if_then_else
20267                    (ne (symbol_ref "optimize_size")
20268                        (const_int 0))
20269                    (const_string "V4SF")
20270                    (const_string "TI"))
20271                (eq_attr "alternative" "2")
20272                  (if_then_else
20273                    (ne (symbol_ref "optimize_size")
20274                        (const_int 0))
20275                    (const_string "V4SF")
20276                    (const_string "TI"))]
20277                (const_string "TI")))])
20278
20279 (define_insn "*movti_rex64"
20280   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
20281         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
20282   "TARGET_64BIT
20283    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20284 {
20285   switch (which_alternative)
20286     {
20287     case 0:
20288     case 1:
20289       return "#";
20290     case 2:
20291       if (get_attr_mode (insn) == MODE_V4SF)
20292         return "xorps\t%0, %0";
20293       else
20294         return "pxor\t%0, %0";
20295     case 3:
20296     case 4:
20297       if (get_attr_mode (insn) == MODE_V4SF)
20298         return "movaps\t{%1, %0|%0, %1}";
20299       else
20300         return "movdqa\t{%1, %0|%0, %1}";
20301     default:
20302       abort ();
20303     }
20304 }
20305   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20306    (set (attr "mode")
20307         (cond [(eq_attr "alternative" "2,3")
20308                  (if_then_else
20309                    (ne (symbol_ref "optimize_size")
20310                        (const_int 0))
20311                    (const_string "V4SF")
20312                    (const_string "TI"))
20313                (eq_attr "alternative" "4")
20314                  (if_then_else
20315                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20316                             (const_int 0))
20317                         (ne (symbol_ref "optimize_size")
20318                             (const_int 0)))
20319                    (const_string "V4SF")
20320                    (const_string "TI"))]
20321                (const_string "DI")))])
20322
20323 (define_insn "*movtf_rex64"
20324   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20325         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20326   "TARGET_64BIT
20327    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20328 {
20329   switch (which_alternative)
20330     {
20331     case 0:
20332     case 1:
20333       return "#";
20334     case 2:
20335       if (get_attr_mode (insn) == MODE_V4SF)
20336         return "xorps\t%0, %0";
20337       else
20338         return "pxor\t%0, %0";
20339     case 3:
20340     case 4:
20341       if (get_attr_mode (insn) == MODE_V4SF)
20342         return "movaps\t{%1, %0|%0, %1}";
20343       else
20344         return "movdqa\t{%1, %0|%0, %1}";
20345     default:
20346       abort ();
20347     }
20348 }
20349   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20350    (set (attr "mode")
20351         (cond [(eq_attr "alternative" "2,3")
20352                  (if_then_else
20353                    (ne (symbol_ref "optimize_size")
20354                        (const_int 0))
20355                    (const_string "V4SF")
20356                    (const_string "TI"))
20357                (eq_attr "alternative" "4")
20358                  (if_then_else
20359                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20360                             (const_int 0))
20361                         (ne (symbol_ref "optimize_size")
20362                             (const_int 0)))
20363                    (const_string "V4SF")
20364                    (const_string "TI"))]
20365                (const_string "DI")))])
20366
20367 (define_split
20368   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20369         (match_operand:TI 1 "general_operand" ""))]
20370   "reload_completed && !SSE_REG_P (operands[0])
20371    && !SSE_REG_P (operands[1])"
20372   [(const_int 0)]
20373   "ix86_split_long_move (operands); DONE;")
20374
20375 (define_split
20376   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20377         (match_operand:TF 1 "general_operand" ""))]
20378   "reload_completed && !SSE_REG_P (operands[0])
20379    && !SSE_REG_P (operands[1])"
20380   [(const_int 0)]
20381   "ix86_split_long_move (operands); DONE;")
20382
20383 ;; These two patterns are useful for specifying exactly whether to use
20384 ;; movaps or movups
20385 (define_expand "sse_movaps"
20386   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20387         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20388                      UNSPEC_MOVA))]
20389   "TARGET_SSE"
20390 {
20391   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20392     {
20393       rtx tmp = gen_reg_rtx (V4SFmode);
20394       emit_insn (gen_sse_movaps (tmp, operands[1]));
20395       emit_move_insn (operands[0], tmp);
20396       DONE;
20397     }
20398 })
20399
20400 (define_insn "*sse_movaps_1"
20401   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20402         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20403                      UNSPEC_MOVA))]
20404   "TARGET_SSE
20405    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20406   "movaps\t{%1, %0|%0, %1}"
20407   [(set_attr "type" "ssemov,ssemov")
20408    (set_attr "mode" "V4SF")])
20409
20410 (define_expand "sse_movups"
20411   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20412         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20413                      UNSPEC_MOVU))]
20414   "TARGET_SSE"
20415 {
20416   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20417     {
20418       rtx tmp = gen_reg_rtx (V4SFmode);
20419       emit_insn (gen_sse_movups (tmp, operands[1]));
20420       emit_move_insn (operands[0], tmp);
20421       DONE;
20422     }
20423 })
20424
20425 (define_insn "*sse_movups_1"
20426   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20427         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20428                      UNSPEC_MOVU))]
20429   "TARGET_SSE
20430    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20431   "movups\t{%1, %0|%0, %1}"
20432   [(set_attr "type" "ssecvt,ssecvt")
20433    (set_attr "mode" "V4SF")])
20434
20435 ;; SSE Strange Moves.
20436
20437 (define_insn "sse_movmskps"
20438   [(set (match_operand:SI 0 "register_operand" "=r")
20439         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20440                    UNSPEC_MOVMSK))]
20441   "TARGET_SSE"
20442   "movmskps\t{%1, %0|%0, %1}"
20443   [(set_attr "type" "ssecvt")
20444    (set_attr "mode" "V4SF")])
20445
20446 (define_insn "mmx_pmovmskb"
20447   [(set (match_operand:SI 0 "register_operand" "=r")
20448         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20449                    UNSPEC_MOVMSK))]
20450   "TARGET_SSE || TARGET_3DNOW_A"
20451   "pmovmskb\t{%1, %0|%0, %1}"
20452   [(set_attr "type" "ssecvt")
20453    (set_attr "mode" "V4SF")])
20454
20455
20456 (define_insn "mmx_maskmovq"
20457   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20458         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20459                       (match_operand:V8QI 2 "register_operand" "y")]
20460                      UNSPEC_MASKMOV))]
20461   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20462   ;; @@@ check ordering of operands in intel/nonintel syntax
20463   "maskmovq\t{%2, %1|%1, %2}"
20464   [(set_attr "type" "mmxcvt")
20465    (set_attr "mode" "DI")])
20466
20467 (define_insn "mmx_maskmovq_rex"
20468   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20469         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20470                       (match_operand:V8QI 2 "register_operand" "y")]
20471                      UNSPEC_MASKMOV))]
20472   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20473   ;; @@@ check ordering of operands in intel/nonintel syntax
20474   "maskmovq\t{%2, %1|%1, %2}"
20475   [(set_attr "type" "mmxcvt")
20476    (set_attr "mode" "DI")])
20477
20478 (define_insn "sse_movntv4sf"
20479   [(set (match_operand:V4SF 0 "memory_operand" "=m")
20480         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20481                      UNSPEC_MOVNT))]
20482   "TARGET_SSE"
20483   "movntps\t{%1, %0|%0, %1}"
20484   [(set_attr "type" "ssemov")
20485    (set_attr "mode" "V4SF")])
20486
20487 (define_insn "sse_movntdi"
20488   [(set (match_operand:DI 0 "memory_operand" "=m")
20489         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20490                    UNSPEC_MOVNT))]
20491   "TARGET_SSE || TARGET_3DNOW_A"
20492   "movntq\t{%1, %0|%0, %1}"
20493   [(set_attr "type" "mmxmov")
20494    (set_attr "mode" "DI")])
20495
20496 (define_insn "sse_movhlps"
20497   [(set (match_operand:V4SF 0 "register_operand" "=x")
20498         (vec_merge:V4SF
20499          (match_operand:V4SF 1 "register_operand" "0")
20500          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20501                           (parallel [(const_int 2)
20502                                      (const_int 3)
20503                                      (const_int 0)
20504                                      (const_int 1)]))
20505          (const_int 3)))]
20506   "TARGET_SSE"
20507   "movhlps\t{%2, %0|%0, %2}"
20508   [(set_attr "type" "ssecvt")
20509    (set_attr "mode" "V4SF")])
20510
20511 (define_insn "sse_movlhps"
20512   [(set (match_operand:V4SF 0 "register_operand" "=x")
20513         (vec_merge:V4SF
20514          (match_operand:V4SF 1 "register_operand" "0")
20515          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20516                           (parallel [(const_int 2)
20517                                      (const_int 3)
20518                                      (const_int 0)
20519                                      (const_int 1)]))
20520          (const_int 12)))]
20521   "TARGET_SSE"
20522   "movlhps\t{%2, %0|%0, %2}"
20523   [(set_attr "type" "ssecvt")
20524    (set_attr "mode" "V4SF")])
20525
20526 (define_insn "sse_movhps"
20527   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20528         (vec_merge:V4SF
20529          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20530          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20531          (const_int 12)))]
20532   "TARGET_SSE
20533    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20534   "movhps\t{%2, %0|%0, %2}"
20535   [(set_attr "type" "ssecvt")
20536    (set_attr "mode" "V4SF")])
20537
20538 (define_insn "sse_movlps"
20539   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20540         (vec_merge:V4SF
20541          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20542          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20543          (const_int 3)))]
20544   "TARGET_SSE
20545    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20546   "movlps\t{%2, %0|%0, %2}"
20547   [(set_attr "type" "ssecvt")
20548    (set_attr "mode" "V4SF")])
20549
20550 (define_expand "sse_loadss"
20551   [(match_operand:V4SF 0 "register_operand" "")
20552    (match_operand:SF 1 "memory_operand" "")]
20553   "TARGET_SSE"
20554 {
20555   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20556                                CONST0_RTX (V4SFmode)));
20557   DONE;
20558 })
20559
20560 (define_insn "sse_loadss_1"
20561   [(set (match_operand:V4SF 0 "register_operand" "=x")
20562         (vec_merge:V4SF
20563          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20564          (match_operand:V4SF 2 "const0_operand" "X")
20565          (const_int 1)))]
20566   "TARGET_SSE"
20567   "movss\t{%1, %0|%0, %1}"
20568   [(set_attr "type" "ssemov")
20569    (set_attr "mode" "SF")])
20570
20571 (define_insn "sse_movss"
20572   [(set (match_operand:V4SF 0 "register_operand" "=x")
20573         (vec_merge:V4SF
20574          (match_operand:V4SF 1 "register_operand" "0")
20575          (match_operand:V4SF 2 "register_operand" "x")
20576          (const_int 14)))]
20577   "TARGET_SSE"
20578   "movss\t{%2, %0|%0, %2}"
20579   [(set_attr "type" "ssemov")
20580    (set_attr "mode" "SF")])
20581
20582 (define_insn "sse_storess"
20583   [(set (match_operand:SF 0 "memory_operand" "=m")
20584         (vec_select:SF
20585          (match_operand:V4SF 1 "register_operand" "x")
20586          (parallel [(const_int 0)])))]
20587   "TARGET_SSE"
20588   "movss\t{%1, %0|%0, %1}"
20589   [(set_attr "type" "ssemov")
20590    (set_attr "mode" "SF")])
20591
20592 (define_insn "sse_shufps"
20593   [(set (match_operand:V4SF 0 "register_operand" "=x")
20594         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20595                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20596                       (match_operand:SI 3 "immediate_operand" "i")]
20597                      UNSPEC_SHUFFLE))]
20598   "TARGET_SSE"
20599   ;; @@@ check operand order for intel/nonintel syntax
20600   "shufps\t{%3, %2, %0|%0, %2, %3}"
20601   [(set_attr "type" "ssecvt")
20602    (set_attr "mode" "V4SF")])
20603
20604
20605 ;; SSE arithmetic
20606
20607 (define_insn "addv4sf3"
20608   [(set (match_operand:V4SF 0 "register_operand" "=x")
20609         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20610                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20611   "TARGET_SSE"
20612   "addps\t{%2, %0|%0, %2}"
20613   [(set_attr "type" "sseadd")
20614    (set_attr "mode" "V4SF")])
20615
20616 (define_insn "vmaddv4sf3"
20617   [(set (match_operand:V4SF 0 "register_operand" "=x")
20618         (vec_merge:V4SF
20619          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20620                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20621          (match_dup 1)
20622          (const_int 1)))]
20623   "TARGET_SSE"
20624   "addss\t{%2, %0|%0, %2}"
20625   [(set_attr "type" "sseadd")
20626    (set_attr "mode" "SF")])
20627
20628 (define_insn "subv4sf3"
20629   [(set (match_operand:V4SF 0 "register_operand" "=x")
20630         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20631                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20632   "TARGET_SSE"
20633   "subps\t{%2, %0|%0, %2}"
20634   [(set_attr "type" "sseadd")
20635    (set_attr "mode" "V4SF")])
20636
20637 (define_insn "vmsubv4sf3"
20638   [(set (match_operand:V4SF 0 "register_operand" "=x")
20639         (vec_merge:V4SF
20640          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20641                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20642          (match_dup 1)
20643          (const_int 1)))]
20644   "TARGET_SSE"
20645   "subss\t{%2, %0|%0, %2}"
20646   [(set_attr "type" "sseadd")
20647    (set_attr "mode" "SF")])
20648
20649 ;; ??? Should probably be done by generic code instead.
20650 (define_expand "negv4sf2"
20651   [(set (match_operand:V4SF 0 "register_operand" "")
20652         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20653                   (match_dup 2)))]
20654   "TARGET_SSE"
20655 {
20656   rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20657   rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20658   operands[2] = force_reg (V4SFmode, vm0);
20659 })
20660
20661 (define_insn "mulv4sf3"
20662   [(set (match_operand:V4SF 0 "register_operand" "=x")
20663         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20664                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20665   "TARGET_SSE"
20666   "mulps\t{%2, %0|%0, %2}"
20667   [(set_attr "type" "ssemul")
20668    (set_attr "mode" "V4SF")])
20669
20670 (define_insn "vmmulv4sf3"
20671   [(set (match_operand:V4SF 0 "register_operand" "=x")
20672         (vec_merge:V4SF
20673          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20674                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20675          (match_dup 1)
20676          (const_int 1)))]
20677   "TARGET_SSE"
20678   "mulss\t{%2, %0|%0, %2}"
20679   [(set_attr "type" "ssemul")
20680    (set_attr "mode" "SF")])
20681
20682 (define_insn "divv4sf3"
20683   [(set (match_operand:V4SF 0 "register_operand" "=x")
20684         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20685                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20686   "TARGET_SSE"
20687   "divps\t{%2, %0|%0, %2}"
20688   [(set_attr "type" "ssediv")
20689    (set_attr "mode" "V4SF")])
20690
20691 (define_insn "vmdivv4sf3"
20692   [(set (match_operand:V4SF 0 "register_operand" "=x")
20693         (vec_merge:V4SF
20694          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20695                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20696          (match_dup 1)
20697          (const_int 1)))]
20698   "TARGET_SSE"
20699   "divss\t{%2, %0|%0, %2}"
20700   [(set_attr "type" "ssediv")
20701    (set_attr "mode" "SF")])
20702
20703
20704 ;; SSE square root/reciprocal
20705
20706 (define_insn "rcpv4sf2"
20707   [(set (match_operand:V4SF 0 "register_operand" "=x")
20708         (unspec:V4SF
20709          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20710   "TARGET_SSE"
20711   "rcpps\t{%1, %0|%0, %1}"
20712   [(set_attr "type" "sse")
20713    (set_attr "mode" "V4SF")])
20714
20715 (define_insn "vmrcpv4sf2"
20716   [(set (match_operand:V4SF 0 "register_operand" "=x")
20717         (vec_merge:V4SF
20718          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20719                       UNSPEC_RCP)
20720          (match_operand:V4SF 2 "register_operand" "0")
20721          (const_int 1)))]
20722   "TARGET_SSE"
20723   "rcpss\t{%1, %0|%0, %1}"
20724   [(set_attr "type" "sse")
20725    (set_attr "mode" "SF")])
20726
20727 (define_insn "rsqrtv4sf2"
20728   [(set (match_operand:V4SF 0 "register_operand" "=x")
20729         (unspec:V4SF
20730          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20731   "TARGET_SSE"
20732   "rsqrtps\t{%1, %0|%0, %1}"
20733   [(set_attr "type" "sse")
20734    (set_attr "mode" "V4SF")])
20735
20736 (define_insn "vmrsqrtv4sf2"
20737   [(set (match_operand:V4SF 0 "register_operand" "=x")
20738         (vec_merge:V4SF
20739          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20740                       UNSPEC_RSQRT)
20741          (match_operand:V4SF 2 "register_operand" "0")
20742          (const_int 1)))]
20743   "TARGET_SSE"
20744   "rsqrtss\t{%1, %0|%0, %1}"
20745   [(set_attr "type" "sse")
20746    (set_attr "mode" "SF")])
20747
20748 (define_insn "sqrtv4sf2"
20749   [(set (match_operand:V4SF 0 "register_operand" "=x")
20750         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20751   "TARGET_SSE"
20752   "sqrtps\t{%1, %0|%0, %1}"
20753   [(set_attr "type" "sse")
20754    (set_attr "mode" "V4SF")])
20755
20756 (define_insn "vmsqrtv4sf2"
20757   [(set (match_operand:V4SF 0 "register_operand" "=x")
20758         (vec_merge:V4SF
20759          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20760          (match_operand:V4SF 2 "register_operand" "0")
20761          (const_int 1)))]
20762   "TARGET_SSE"
20763   "sqrtss\t{%1, %0|%0, %1}"
20764   [(set_attr "type" "sse")
20765    (set_attr "mode" "SF")])
20766
20767 ;; SSE logical operations.
20768
20769 ;; SSE defines logical operations on floating point values.  This brings
20770 ;; interesting challenge to RTL representation where logicals are only valid
20771 ;; on integral types.  We deal with this by representing the floating point
20772 ;; logical as logical on arguments casted to TImode as this is what hardware
20773 ;; really does.  Unfortunately hardware requires the type information to be
20774 ;; present and thus we must avoid subregs from being simplified and eliminated
20775 ;; in later compilation phases.
20776 ;;
20777 ;; We have following variants from each instruction:
20778 ;; sse_andsf3 - the operation taking V4SF vector operands
20779 ;;              and doing TImode cast on them
20780 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20781 ;;                      TImode, since backend insist on eliminating casts
20782 ;;                      on memory operands
20783 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20784 ;;                   We cannot accept memory operand here as instruction reads
20785 ;;                   whole scalar.  This is generated only post reload by GCC
20786 ;;                   scalar float operations that expands to logicals (fabs)
20787 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20788 ;;                   memory operand.  Eventually combine can be able
20789 ;;                   to synthesize these using splitter.
20790 ;; sse2_anddf3, *sse2_anddf3_memory
20791 ;;              
20792 ;; 
20793 ;; These are not called andti3 etc. because we really really don't want
20794 ;; the compiler to widen DImode ands to TImode ands and then try to move
20795 ;; into DImode subregs of SSE registers, and them together, and move out
20796 ;; of DImode subregs again!
20797 ;; SSE1 single precision floating point logical operation
20798 (define_expand "sse_andv4sf3"
20799   [(set (match_operand:V4SF 0 "register_operand" "")
20800         (and:V4SF (match_operand:V4SF 1 "register_operand" "")
20801                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20802   "TARGET_SSE"
20803   "")
20804
20805 (define_insn "*sse_andv4sf3"
20806   [(set (match_operand:V4SF 0 "register_operand" "=x")
20807         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20808                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20809   "TARGET_SSE
20810    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20811   "andps\t{%2, %0|%0, %2}"
20812   [(set_attr "type" "sselog")
20813    (set_attr "mode" "V4SF")])
20814
20815 (define_expand "sse_nandv4sf3"
20816   [(set (match_operand:V4SF 0 "register_operand" "")
20817         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
20818                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20819   "TARGET_SSE"
20820   "")
20821
20822 (define_insn "*sse_nandv4sf3"
20823   [(set (match_operand:V4SF 0 "register_operand" "=x")
20824         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
20825                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20826   "TARGET_SSE"
20827   "andnps\t{%2, %0|%0, %2}"
20828   [(set_attr "type" "sselog")
20829    (set_attr "mode" "V4SF")])
20830
20831 (define_expand "sse_iorv4sf3"
20832   [(set (match_operand:V4SF 0 "register_operand" "")
20833         (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
20834                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20835   "TARGET_SSE"
20836   "")
20837
20838 (define_insn "*sse_iorv4sf3"
20839   [(set (match_operand:V4SF 0 "register_operand" "=x")
20840         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20841                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20842   "TARGET_SSE
20843    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20844   "orps\t{%2, %0|%0, %2}"
20845   [(set_attr "type" "sselog")
20846    (set_attr "mode" "V4SF")])
20847
20848 (define_expand "sse_xorv4sf3"
20849   [(set (match_operand:V4SF 0 "register_operand" "")
20850         (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
20851                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20852   "TARGET_SSE"
20853   "")
20854
20855 (define_insn "*sse_xorv4sf3"
20856   [(set (match_operand:V4SF 0 "register_operand" "=x")
20857         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20858                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20859   "TARGET_SSE
20860    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20861   "xorps\t{%2, %0|%0, %2}"
20862   [(set_attr "type" "sselog")
20863    (set_attr "mode" "V4SF")])
20864
20865 ;; SSE2 double precision floating point logical operation
20866
20867 (define_expand "sse2_andv2df3"
20868   [(set (match_operand:V2DF 0 "register_operand" "")
20869         (and:V2DF (match_operand:V2DF 1 "register_operand" "")
20870                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20871   "TARGET_SSE2"
20872   "")
20873
20874 (define_insn "*sse2_andv2df3"
20875   [(set (match_operand:V2DF 0 "register_operand" "=x")
20876         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20877                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20878   "TARGET_SSE2
20879    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20880   "andpd\t{%2, %0|%0, %2}"
20881   [(set_attr "type" "sselog")
20882    (set_attr "mode" "V2DF")])
20883
20884 (define_expand "sse2_nandv2df3"
20885   [(set (match_operand:V2DF 0 "register_operand" "")
20886         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
20887                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20888   "TARGET_SSE2"
20889   "")
20890
20891 (define_insn "*sse2_nandv2df3"
20892   [(set (match_operand:V2DF 0 "register_operand" "=x")
20893         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
20894                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20895   "TARGET_SSE2"
20896   "andnpd\t{%2, %0|%0, %2}"
20897   [(set_attr "type" "sselog")
20898    (set_attr "mode" "V2DF")])
20899
20900 (define_expand "sse2_iorv2df3"
20901   [(set (match_operand:V2DF 0 "register_operand" "")
20902         (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
20903                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20904   "TARGET_SSE2"
20905   "")
20906
20907 (define_insn "*sse2_iorv2df3"
20908   [(set (match_operand:V2DF 0 "register_operand" "=x")
20909         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20910                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20911   "TARGET_SSE2
20912    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20913   "orpd\t{%2, %0|%0, %2}"
20914   [(set_attr "type" "sselog")
20915    (set_attr "mode" "V2DF")])
20916
20917 (define_expand "sse2_xorv2df3"
20918   [(set (match_operand:V2DF 0 "register_operand" "")
20919         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
20920                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20921   "TARGET_SSE2"
20922   "")
20923
20924 (define_insn "*sse2_xorv2df3"
20925   [(set (match_operand:V2DF 0 "register_operand" "=x")
20926         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20927                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20928   "TARGET_SSE2
20929    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20930   "xorpd\t{%2, %0|%0, %2}"
20931   [(set_attr "type" "sselog")
20932    (set_attr "mode" "V2DF")])
20933
20934 ;; SSE2 integral logicals.  These patterns must always come after floating
20935 ;; point ones since we don't want compiler to use integer opcodes on floating
20936 ;; point SSE values to avoid matching of subregs in the match_operand.
20937 (define_insn "*sse2_andti3"
20938   [(set (match_operand:TI 0 "register_operand" "=x")
20939         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20940                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20941   "TARGET_SSE2
20942    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20943   "pand\t{%2, %0|%0, %2}"
20944   [(set_attr "type" "sselog")
20945    (set_attr "mode" "TI")])
20946
20947 (define_insn "sse2_andv2di3"
20948   [(set (match_operand:V2DI 0 "register_operand" "=x")
20949         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20950                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20951   "TARGET_SSE2
20952    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20953   "pand\t{%2, %0|%0, %2}"
20954   [(set_attr "type" "sselog")
20955    (set_attr "mode" "TI")])
20956
20957 (define_insn "*sse2_nandti3"
20958   [(set (match_operand:TI 0 "register_operand" "=x")
20959         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20960                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20961   "TARGET_SSE2"
20962   "pandn\t{%2, %0|%0, %2}"
20963   [(set_attr "type" "sselog")
20964    (set_attr "mode" "TI")])
20965
20966 (define_insn "sse2_nandv2di3"
20967   [(set (match_operand:V2DI 0 "register_operand" "=x")
20968         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20969                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20970   "TARGET_SSE2
20971    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20972   "pandn\t{%2, %0|%0, %2}"
20973   [(set_attr "type" "sselog")
20974    (set_attr "mode" "TI")])
20975
20976 (define_insn "*sse2_iorti3"
20977   [(set (match_operand:TI 0 "register_operand" "=x")
20978         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20979                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20980   "TARGET_SSE2
20981    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20982   "por\t{%2, %0|%0, %2}"
20983   [(set_attr "type" "sselog")
20984    (set_attr "mode" "TI")])
20985
20986 (define_insn "sse2_iorv2di3"
20987   [(set (match_operand:V2DI 0 "register_operand" "=x")
20988         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20989                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20990   "TARGET_SSE2
20991    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20992   "por\t{%2, %0|%0, %2}"
20993   [(set_attr "type" "sselog")
20994    (set_attr "mode" "TI")])
20995
20996 (define_insn "*sse2_xorti3"
20997   [(set (match_operand:TI 0 "register_operand" "=x")
20998         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20999                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21000   "TARGET_SSE2
21001    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21002   "pxor\t{%2, %0|%0, %2}"
21003   [(set_attr "type" "sselog")
21004    (set_attr "mode" "TI")])
21005
21006 (define_insn "sse2_xorv2di3"
21007   [(set (match_operand:V2DI 0 "register_operand" "=x")
21008         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21009                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21010   "TARGET_SSE2
21011    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21012   "pxor\t{%2, %0|%0, %2}"
21013   [(set_attr "type" "sselog")
21014    (set_attr "mode" "TI")])
21015
21016 ;; Use xor, but don't show input operands so they aren't live before
21017 ;; this insn.
21018 (define_insn "sse_clrv4sf"
21019   [(set (match_operand:V4SF 0 "register_operand" "=x")
21020         (match_operand:V4SF 1 "const0_operand" "X"))]
21021   "TARGET_SSE"
21022 {
21023   if (get_attr_mode (insn) == MODE_TI)
21024     return "pxor\t{%0, %0|%0, %0}";
21025   else
21026     return "xorps\t{%0, %0|%0, %0}";
21027 }
21028   [(set_attr "type" "sselog")
21029    (set_attr "memory" "none")
21030    (set (attr "mode")
21031         (if_then_else
21032            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
21033                          (const_int 0))
21034                      (ne (symbol_ref "TARGET_SSE2")
21035                          (const_int 0)))
21036                 (eq (symbol_ref "optimize_size")
21037                     (const_int 0)))
21038          (const_string "TI")
21039          (const_string "V4SF")))])
21040
21041 ;; Use xor, but don't show input operands so they aren't live before
21042 ;; this insn.
21043 (define_insn "sse_clrv2df"
21044   [(set (match_operand:V2DF 0 "register_operand" "=x")
21045         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
21046   "TARGET_SSE2"
21047   "xorpd\t{%0, %0|%0, %0}"
21048   [(set_attr "type" "sselog")
21049    (set_attr "memory" "none")
21050    (set_attr "mode" "V4SF")])
21051
21052 ;; SSE mask-generating compares
21053
21054 (define_insn "maskcmpv4sf3"
21055   [(set (match_operand:V4SI 0 "register_operand" "=x")
21056         (match_operator:V4SI 3 "sse_comparison_operator"
21057                 [(match_operand:V4SF 1 "register_operand" "0")
21058                  (match_operand:V4SF 2 "register_operand" "x")]))]
21059   "TARGET_SSE"
21060   "cmp%D3ps\t{%2, %0|%0, %2}"
21061   [(set_attr "type" "ssecmp")
21062    (set_attr "mode" "V4SF")])
21063
21064 (define_insn "maskncmpv4sf3"
21065   [(set (match_operand:V4SI 0 "register_operand" "=x")
21066         (not:V4SI
21067          (match_operator:V4SI 3 "sse_comparison_operator"
21068                 [(match_operand:V4SF 1 "register_operand" "0")
21069                  (match_operand:V4SF 2 "register_operand" "x")])))]
21070   "TARGET_SSE"
21071 {
21072   if (GET_CODE (operands[3]) == UNORDERED)
21073     return "cmpordps\t{%2, %0|%0, %2}";
21074   else
21075     return "cmpn%D3ps\t{%2, %0|%0, %2}";
21076 }
21077   [(set_attr "type" "ssecmp")
21078    (set_attr "mode" "V4SF")])
21079
21080 (define_insn "vmmaskcmpv4sf3"
21081   [(set (match_operand:V4SI 0 "register_operand" "=x")
21082         (vec_merge:V4SI
21083          (match_operator:V4SI 3 "sse_comparison_operator"
21084                 [(match_operand:V4SF 1 "register_operand" "0")
21085                  (match_operand:V4SF 2 "register_operand" "x")])
21086          (subreg:V4SI (match_dup 1) 0)
21087          (const_int 1)))]
21088   "TARGET_SSE"
21089   "cmp%D3ss\t{%2, %0|%0, %2}"
21090   [(set_attr "type" "ssecmp")
21091    (set_attr "mode" "SF")])
21092
21093 (define_insn "vmmaskncmpv4sf3"
21094   [(set (match_operand:V4SI 0 "register_operand" "=x")
21095         (vec_merge:V4SI
21096          (not:V4SI
21097           (match_operator:V4SI 3 "sse_comparison_operator"
21098                 [(match_operand:V4SF 1 "register_operand" "0")
21099                  (match_operand:V4SF 2 "register_operand" "x")]))
21100          (subreg:V4SI (match_dup 1) 0)
21101          (const_int 1)))]
21102   "TARGET_SSE"
21103 {
21104   if (GET_CODE (operands[3]) == UNORDERED)
21105     return "cmpordss\t{%2, %0|%0, %2}";
21106   else
21107     return "cmpn%D3ss\t{%2, %0|%0, %2}";
21108 }
21109   [(set_attr "type" "ssecmp")
21110    (set_attr "mode" "SF")])
21111
21112 (define_insn "sse_comi"
21113   [(set (reg:CCFP FLAGS_REG)
21114         (compare:CCFP (vec_select:SF
21115                        (match_operand:V4SF 0 "register_operand" "x")
21116                        (parallel [(const_int 0)]))
21117                       (vec_select:SF
21118                        (match_operand:V4SF 1 "register_operand" "x")
21119                        (parallel [(const_int 0)]))))]
21120   "TARGET_SSE"
21121   "comiss\t{%1, %0|%0, %1}"
21122   [(set_attr "type" "ssecomi")
21123    (set_attr "mode" "SF")])
21124
21125 (define_insn "sse_ucomi"
21126   [(set (reg:CCFPU FLAGS_REG)
21127         (compare:CCFPU (vec_select:SF
21128                         (match_operand:V4SF 0 "register_operand" "x")
21129                         (parallel [(const_int 0)]))
21130                        (vec_select:SF
21131                         (match_operand:V4SF 1 "register_operand" "x")
21132                         (parallel [(const_int 0)]))))]
21133   "TARGET_SSE"
21134   "ucomiss\t{%1, %0|%0, %1}"
21135   [(set_attr "type" "ssecomi")
21136    (set_attr "mode" "SF")])
21137
21138
21139 ;; SSE unpack
21140
21141 (define_insn "sse_unpckhps"
21142   [(set (match_operand:V4SF 0 "register_operand" "=x")
21143         (vec_merge:V4SF
21144          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21145                           (parallel [(const_int 2)
21146                                      (const_int 0)
21147                                      (const_int 3)
21148                                      (const_int 1)]))
21149          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21150                           (parallel [(const_int 0)
21151                                      (const_int 2)
21152                                      (const_int 1)
21153                                      (const_int 3)]))
21154          (const_int 5)))]
21155   "TARGET_SSE"
21156   "unpckhps\t{%2, %0|%0, %2}"
21157   [(set_attr "type" "ssecvt")
21158    (set_attr "mode" "V4SF")])
21159
21160 (define_insn "sse_unpcklps"
21161   [(set (match_operand:V4SF 0 "register_operand" "=x")
21162         (vec_merge:V4SF
21163          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21164                           (parallel [(const_int 0)
21165                                      (const_int 2)
21166                                      (const_int 1)
21167                                      (const_int 3)]))
21168          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21169                           (parallel [(const_int 2)
21170                                      (const_int 0)
21171                                      (const_int 3)
21172                                      (const_int 1)]))
21173          (const_int 5)))]
21174   "TARGET_SSE"
21175   "unpcklps\t{%2, %0|%0, %2}"
21176   [(set_attr "type" "ssecvt")
21177    (set_attr "mode" "V4SF")])
21178
21179
21180 ;; SSE min/max
21181
21182 (define_insn "smaxv4sf3"
21183   [(set (match_operand:V4SF 0 "register_operand" "=x")
21184         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21185                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21186   "TARGET_SSE"
21187   "maxps\t{%2, %0|%0, %2}"
21188   [(set_attr "type" "sse")
21189    (set_attr "mode" "V4SF")])
21190
21191 (define_insn "vmsmaxv4sf3"
21192   [(set (match_operand:V4SF 0 "register_operand" "=x")
21193         (vec_merge:V4SF
21194          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21195                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21196          (match_dup 1)
21197          (const_int 1)))]
21198   "TARGET_SSE"
21199   "maxss\t{%2, %0|%0, %2}"
21200   [(set_attr "type" "sse")
21201    (set_attr "mode" "SF")])
21202
21203 (define_insn "sminv4sf3"
21204   [(set (match_operand:V4SF 0 "register_operand" "=x")
21205         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21206                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21207   "TARGET_SSE"
21208   "minps\t{%2, %0|%0, %2}"
21209   [(set_attr "type" "sse")
21210    (set_attr "mode" "V4SF")])
21211
21212 (define_insn "vmsminv4sf3"
21213   [(set (match_operand:V4SF 0 "register_operand" "=x")
21214         (vec_merge:V4SF
21215          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21216                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21217          (match_dup 1)
21218          (const_int 1)))]
21219   "TARGET_SSE"
21220   "minss\t{%2, %0|%0, %2}"
21221   [(set_attr "type" "sse")
21222    (set_attr "mode" "SF")])
21223
21224 ;; SSE <-> integer/MMX conversions
21225
21226 (define_insn "cvtpi2ps"
21227   [(set (match_operand:V4SF 0 "register_operand" "=x")
21228         (vec_merge:V4SF
21229          (match_operand:V4SF 1 "register_operand" "0")
21230          (vec_duplicate:V4SF
21231           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
21232          (const_int 12)))]
21233   "TARGET_SSE"
21234   "cvtpi2ps\t{%2, %0|%0, %2}"
21235   [(set_attr "type" "ssecvt")
21236    (set_attr "mode" "V4SF")])
21237
21238 (define_insn "cvtps2pi"
21239   [(set (match_operand:V2SI 0 "register_operand" "=y")
21240         (vec_select:V2SI
21241          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21242          (parallel [(const_int 0) (const_int 1)])))]
21243   "TARGET_SSE"
21244   "cvtps2pi\t{%1, %0|%0, %1}"
21245   [(set_attr "type" "ssecvt")
21246    (set_attr "mode" "V4SF")])
21247
21248 (define_insn "cvttps2pi"
21249   [(set (match_operand:V2SI 0 "register_operand" "=y")
21250         (vec_select:V2SI
21251          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21252                       UNSPEC_FIX)
21253          (parallel [(const_int 0) (const_int 1)])))]
21254   "TARGET_SSE"
21255   "cvttps2pi\t{%1, %0|%0, %1}"
21256   [(set_attr "type" "ssecvt")
21257    (set_attr "mode" "SF")])
21258
21259 (define_insn "cvtsi2ss"
21260   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21261         (vec_merge:V4SF
21262          (match_operand:V4SF 1 "register_operand" "0,0")
21263          (vec_duplicate:V4SF
21264           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21265          (const_int 14)))]
21266   "TARGET_SSE"
21267   "cvtsi2ss\t{%2, %0|%0, %2}"
21268   [(set_attr "type" "sseicvt")
21269    (set_attr "athlon_decode" "vector,double")
21270    (set_attr "mode" "SF")])
21271
21272 (define_insn "cvtsi2ssq"
21273   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21274         (vec_merge:V4SF
21275          (match_operand:V4SF 1 "register_operand" "0,0")
21276          (vec_duplicate:V4SF
21277           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21278          (const_int 14)))]
21279   "TARGET_SSE && TARGET_64BIT"
21280   "cvtsi2ssq\t{%2, %0|%0, %2}"
21281   [(set_attr "type" "sseicvt")
21282    (set_attr "athlon_decode" "vector,double")
21283    (set_attr "mode" "SF")])
21284
21285 (define_insn "cvtss2si"
21286   [(set (match_operand:SI 0 "register_operand" "=r,r")
21287         (vec_select:SI
21288          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21289          (parallel [(const_int 0)])))]
21290   "TARGET_SSE"
21291   "cvtss2si\t{%1, %0|%0, %1}"
21292   [(set_attr "type" "sseicvt")
21293    (set_attr "athlon_decode" "double,vector")
21294    (set_attr "mode" "SI")])
21295
21296 (define_insn "cvtss2siq"
21297   [(set (match_operand:DI 0 "register_operand" "=r,r")
21298         (vec_select:DI
21299          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21300          (parallel [(const_int 0)])))]
21301   "TARGET_SSE"
21302   "cvtss2siq\t{%1, %0|%0, %1}"
21303   [(set_attr "type" "sseicvt")
21304    (set_attr "athlon_decode" "double,vector")
21305    (set_attr "mode" "DI")])
21306
21307 (define_insn "cvttss2si"
21308   [(set (match_operand:SI 0 "register_operand" "=r,r")
21309         (vec_select:SI
21310          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21311                       UNSPEC_FIX)
21312          (parallel [(const_int 0)])))]
21313   "TARGET_SSE"
21314   "cvttss2si\t{%1, %0|%0, %1}"
21315   [(set_attr "type" "sseicvt")
21316    (set_attr "mode" "SF")
21317    (set_attr "athlon_decode" "double,vector")])
21318
21319 (define_insn "cvttss2siq"
21320   [(set (match_operand:DI 0 "register_operand" "=r,r")
21321         (vec_select:DI
21322          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21323                       UNSPEC_FIX)
21324          (parallel [(const_int 0)])))]
21325   "TARGET_SSE && TARGET_64BIT"
21326   "cvttss2siq\t{%1, %0|%0, %1}"
21327   [(set_attr "type" "sseicvt")
21328    (set_attr "mode" "SF")
21329    (set_attr "athlon_decode" "double,vector")])
21330
21331
21332 ;; MMX insns
21333
21334 ;; MMX arithmetic
21335
21336 (define_insn "addv8qi3"
21337   [(set (match_operand:V8QI 0 "register_operand" "=y")
21338         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21339                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21340   "TARGET_MMX"
21341   "paddb\t{%2, %0|%0, %2}"
21342   [(set_attr "type" "mmxadd")
21343    (set_attr "mode" "DI")])
21344
21345 (define_insn "addv4hi3"
21346   [(set (match_operand:V4HI 0 "register_operand" "=y")
21347         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21348                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21349   "TARGET_MMX"
21350   "paddw\t{%2, %0|%0, %2}"
21351   [(set_attr "type" "mmxadd")
21352    (set_attr "mode" "DI")])
21353
21354 (define_insn "addv2si3"
21355   [(set (match_operand:V2SI 0 "register_operand" "=y")
21356         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21357                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21358   "TARGET_MMX"
21359   "paddd\t{%2, %0|%0, %2}"
21360   [(set_attr "type" "mmxadd")
21361    (set_attr "mode" "DI")])
21362
21363 (define_insn "mmx_adddi3"
21364   [(set (match_operand:DI 0 "register_operand" "=y")
21365         (unspec:DI
21366          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21367                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21368          UNSPEC_NOP))]
21369   "TARGET_MMX"
21370   "paddq\t{%2, %0|%0, %2}"
21371   [(set_attr "type" "mmxadd")
21372    (set_attr "mode" "DI")])
21373
21374 (define_insn "ssaddv8qi3"
21375   [(set (match_operand:V8QI 0 "register_operand" "=y")
21376         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21377                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21378   "TARGET_MMX"
21379   "paddsb\t{%2, %0|%0, %2}"
21380   [(set_attr "type" "mmxadd")
21381    (set_attr "mode" "DI")])
21382
21383 (define_insn "ssaddv4hi3"
21384   [(set (match_operand:V4HI 0 "register_operand" "=y")
21385         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21386                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21387   "TARGET_MMX"
21388   "paddsw\t{%2, %0|%0, %2}"
21389   [(set_attr "type" "mmxadd")
21390    (set_attr "mode" "DI")])
21391
21392 (define_insn "usaddv8qi3"
21393   [(set (match_operand:V8QI 0 "register_operand" "=y")
21394         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21395                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21396   "TARGET_MMX"
21397   "paddusb\t{%2, %0|%0, %2}"
21398   [(set_attr "type" "mmxadd")
21399    (set_attr "mode" "DI")])
21400
21401 (define_insn "usaddv4hi3"
21402   [(set (match_operand:V4HI 0 "register_operand" "=y")
21403         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21404                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21405   "TARGET_MMX"
21406   "paddusw\t{%2, %0|%0, %2}"
21407   [(set_attr "type" "mmxadd")
21408    (set_attr "mode" "DI")])
21409
21410 (define_insn "subv8qi3"
21411   [(set (match_operand:V8QI 0 "register_operand" "=y")
21412         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21413                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21414   "TARGET_MMX"
21415   "psubb\t{%2, %0|%0, %2}"
21416   [(set_attr "type" "mmxadd")
21417    (set_attr "mode" "DI")])
21418
21419 (define_insn "subv4hi3"
21420   [(set (match_operand:V4HI 0 "register_operand" "=y")
21421         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21422                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21423   "TARGET_MMX"
21424   "psubw\t{%2, %0|%0, %2}"
21425   [(set_attr "type" "mmxadd")
21426    (set_attr "mode" "DI")])
21427
21428 (define_insn "subv2si3"
21429   [(set (match_operand:V2SI 0 "register_operand" "=y")
21430         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21431                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21432   "TARGET_MMX"
21433   "psubd\t{%2, %0|%0, %2}"
21434   [(set_attr "type" "mmxadd")
21435    (set_attr "mode" "DI")])
21436
21437 (define_insn "mmx_subdi3"
21438   [(set (match_operand:DI 0 "register_operand" "=y")
21439         (unspec:DI
21440          [(minus:DI (match_operand:DI 1 "register_operand" "0")
21441                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21442          UNSPEC_NOP))]
21443   "TARGET_MMX"
21444   "psubq\t{%2, %0|%0, %2}"
21445   [(set_attr "type" "mmxadd")
21446    (set_attr "mode" "DI")])
21447
21448 (define_insn "sssubv8qi3"
21449   [(set (match_operand:V8QI 0 "register_operand" "=y")
21450         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21451                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21452   "TARGET_MMX"
21453   "psubsb\t{%2, %0|%0, %2}"
21454   [(set_attr "type" "mmxadd")
21455    (set_attr "mode" "DI")])
21456
21457 (define_insn "sssubv4hi3"
21458   [(set (match_operand:V4HI 0 "register_operand" "=y")
21459         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21460                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21461   "TARGET_MMX"
21462   "psubsw\t{%2, %0|%0, %2}"
21463   [(set_attr "type" "mmxadd")
21464    (set_attr "mode" "DI")])
21465
21466 (define_insn "ussubv8qi3"
21467   [(set (match_operand:V8QI 0 "register_operand" "=y")
21468         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21469                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21470   "TARGET_MMX"
21471   "psubusb\t{%2, %0|%0, %2}"
21472   [(set_attr "type" "mmxadd")
21473    (set_attr "mode" "DI")])
21474
21475 (define_insn "ussubv4hi3"
21476   [(set (match_operand:V4HI 0 "register_operand" "=y")
21477         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21478                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21479   "TARGET_MMX"
21480   "psubusw\t{%2, %0|%0, %2}"
21481   [(set_attr "type" "mmxadd")
21482    (set_attr "mode" "DI")])
21483
21484 (define_insn "mulv4hi3"
21485   [(set (match_operand:V4HI 0 "register_operand" "=y")
21486         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21487                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21488   "TARGET_MMX"
21489   "pmullw\t{%2, %0|%0, %2}"
21490   [(set_attr "type" "mmxmul")
21491    (set_attr "mode" "DI")])
21492
21493 (define_insn "smulv4hi3_highpart"
21494   [(set (match_operand:V4HI 0 "register_operand" "=y")
21495         (truncate:V4HI
21496          (lshiftrt:V4SI
21497           (mult:V4SI (sign_extend:V4SI
21498                       (match_operand:V4HI 1 "register_operand" "0"))
21499                      (sign_extend:V4SI
21500                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21501           (const_int 16))))]
21502   "TARGET_MMX"
21503   "pmulhw\t{%2, %0|%0, %2}"
21504   [(set_attr "type" "mmxmul")
21505    (set_attr "mode" "DI")])
21506
21507 (define_insn "umulv4hi3_highpart"
21508   [(set (match_operand:V4HI 0 "register_operand" "=y")
21509         (truncate:V4HI
21510          (lshiftrt:V4SI
21511           (mult:V4SI (zero_extend:V4SI
21512                       (match_operand:V4HI 1 "register_operand" "0"))
21513                      (zero_extend:V4SI
21514                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21515           (const_int 16))))]
21516   "TARGET_SSE || TARGET_3DNOW_A"
21517   "pmulhuw\t{%2, %0|%0, %2}"
21518   [(set_attr "type" "mmxmul")
21519    (set_attr "mode" "DI")])
21520
21521 (define_insn "mmx_pmaddwd"
21522   [(set (match_operand:V2SI 0 "register_operand" "=y")
21523         (plus:V2SI
21524          (mult:V2SI
21525           (sign_extend:V2SI
21526            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21527                             (parallel [(const_int 0) (const_int 2)])))
21528           (sign_extend:V2SI
21529            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21530                             (parallel [(const_int 0) (const_int 2)]))))
21531          (mult:V2SI
21532           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21533                                              (parallel [(const_int 1)
21534                                                         (const_int 3)])))
21535           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21536                                              (parallel [(const_int 1)
21537                                                         (const_int 3)]))))))]
21538   "TARGET_MMX"
21539   "pmaddwd\t{%2, %0|%0, %2}"
21540   [(set_attr "type" "mmxmul")
21541    (set_attr "mode" "DI")])
21542
21543
21544 ;; MMX logical operations
21545 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21546 ;; normal code that also wants to use the FPU from getting broken.
21547 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21548 (define_insn "mmx_iordi3"
21549   [(set (match_operand:DI 0 "register_operand" "=y")
21550         (unspec:DI
21551          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21552                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21553          UNSPEC_NOP))]
21554   "TARGET_MMX"
21555   "por\t{%2, %0|%0, %2}"
21556   [(set_attr "type" "mmxadd")
21557    (set_attr "mode" "DI")])
21558
21559 (define_insn "mmx_xordi3"
21560   [(set (match_operand:DI 0 "register_operand" "=y")
21561         (unspec:DI
21562          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21563                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21564          UNSPEC_NOP))]
21565   "TARGET_MMX"
21566   "pxor\t{%2, %0|%0, %2}"
21567   [(set_attr "type" "mmxadd")
21568    (set_attr "mode" "DI")
21569    (set_attr "memory" "none")])
21570
21571 ;; Same as pxor, but don't show input operands so that we don't think
21572 ;; they are live.
21573 (define_insn "mmx_clrdi"
21574   [(set (match_operand:DI 0 "register_operand" "=y")
21575         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21576   "TARGET_MMX"
21577   "pxor\t{%0, %0|%0, %0}"
21578   [(set_attr "type" "mmxadd")
21579    (set_attr "mode" "DI")
21580    (set_attr "memory" "none")])
21581
21582 (define_insn "mmx_anddi3"
21583   [(set (match_operand:DI 0 "register_operand" "=y")
21584         (unspec:DI
21585          [(and:DI (match_operand:DI 1 "register_operand" "%0")
21586                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21587          UNSPEC_NOP))]
21588   "TARGET_MMX"
21589   "pand\t{%2, %0|%0, %2}"
21590   [(set_attr "type" "mmxadd")
21591    (set_attr "mode" "DI")])
21592
21593 (define_insn "mmx_nanddi3"
21594   [(set (match_operand:DI 0 "register_operand" "=y")
21595         (unspec:DI
21596          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21597                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21598          UNSPEC_NOP))]
21599   "TARGET_MMX"
21600   "pandn\t{%2, %0|%0, %2}"
21601   [(set_attr "type" "mmxadd")
21602    (set_attr "mode" "DI")])
21603
21604
21605 ;; MMX unsigned averages/sum of absolute differences
21606
21607 (define_insn "mmx_uavgv8qi3"
21608   [(set (match_operand:V8QI 0 "register_operand" "=y")
21609         (ashiftrt:V8QI
21610          (plus:V8QI (plus:V8QI
21611                      (match_operand:V8QI 1 "register_operand" "0")
21612                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21613                     (const_vector:V8QI [(const_int 1)
21614                                         (const_int 1)
21615                                         (const_int 1)
21616                                         (const_int 1)
21617                                         (const_int 1)
21618                                         (const_int 1)
21619                                         (const_int 1)
21620                                         (const_int 1)]))
21621          (const_int 1)))]
21622   "TARGET_SSE || TARGET_3DNOW_A"
21623   "pavgb\t{%2, %0|%0, %2}"
21624   [(set_attr "type" "mmxshft")
21625    (set_attr "mode" "DI")])
21626
21627 (define_insn "mmx_uavgv4hi3"
21628   [(set (match_operand:V4HI 0 "register_operand" "=y")
21629         (ashiftrt:V4HI
21630          (plus:V4HI (plus:V4HI
21631                      (match_operand:V4HI 1 "register_operand" "0")
21632                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21633                     (const_vector:V4HI [(const_int 1)
21634                                         (const_int 1)
21635                                         (const_int 1)
21636                                         (const_int 1)]))
21637          (const_int 1)))]
21638   "TARGET_SSE || TARGET_3DNOW_A"
21639   "pavgw\t{%2, %0|%0, %2}"
21640   [(set_attr "type" "mmxshft")
21641    (set_attr "mode" "DI")])
21642
21643 (define_insn "mmx_psadbw"
21644   [(set (match_operand:DI 0 "register_operand" "=y")
21645         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21646                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21647                    UNSPEC_PSADBW))]
21648   "TARGET_SSE || TARGET_3DNOW_A"
21649   "psadbw\t{%2, %0|%0, %2}"
21650   [(set_attr "type" "mmxshft")
21651    (set_attr "mode" "DI")])
21652
21653
21654 ;; MMX insert/extract/shuffle
21655
21656 (define_insn "mmx_pinsrw"
21657   [(set (match_operand:V4HI 0 "register_operand" "=y")
21658         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21659                         (vec_duplicate:V4HI
21660                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21661                         (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21662   "TARGET_SSE || TARGET_3DNOW_A"
21663   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21664   [(set_attr "type" "mmxcvt")
21665    (set_attr "mode" "DI")])
21666
21667 (define_insn "mmx_pextrw"
21668   [(set (match_operand:SI 0 "register_operand" "=r")
21669         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21670                                        (parallel
21671                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21672   "TARGET_SSE || TARGET_3DNOW_A"
21673   "pextrw\t{%2, %1, %0|%0, %1, %2}"
21674   [(set_attr "type" "mmxcvt")
21675    (set_attr "mode" "DI")])
21676
21677 (define_insn "mmx_pshufw"
21678   [(set (match_operand:V4HI 0 "register_operand" "=y")
21679         (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21680                       (match_operand:SI 2 "immediate_operand" "i")]
21681                      UNSPEC_SHUFFLE))]
21682   "TARGET_SSE || TARGET_3DNOW_A"
21683   "pshufw\t{%2, %1, %0|%0, %1, %2}"
21684   [(set_attr "type" "mmxcvt")
21685    (set_attr "mode" "DI")])
21686
21687
21688 ;; MMX mask-generating comparisons
21689
21690 (define_insn "eqv8qi3"
21691   [(set (match_operand:V8QI 0 "register_operand" "=y")
21692         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21693                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21694   "TARGET_MMX"
21695   "pcmpeqb\t{%2, %0|%0, %2}"
21696   [(set_attr "type" "mmxcmp")
21697    (set_attr "mode" "DI")])
21698
21699 (define_insn "eqv4hi3"
21700   [(set (match_operand:V4HI 0 "register_operand" "=y")
21701         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21702                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21703   "TARGET_MMX"
21704   "pcmpeqw\t{%2, %0|%0, %2}"
21705   [(set_attr "type" "mmxcmp")
21706    (set_attr "mode" "DI")])
21707
21708 (define_insn "eqv2si3"
21709   [(set (match_operand:V2SI 0 "register_operand" "=y")
21710         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21711                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21712   "TARGET_MMX"
21713   "pcmpeqd\t{%2, %0|%0, %2}"
21714   [(set_attr "type" "mmxcmp")
21715    (set_attr "mode" "DI")])
21716
21717 (define_insn "gtv8qi3"
21718   [(set (match_operand:V8QI 0 "register_operand" "=y")
21719         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21720                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21721   "TARGET_MMX"
21722   "pcmpgtb\t{%2, %0|%0, %2}"
21723   [(set_attr "type" "mmxcmp")
21724    (set_attr "mode" "DI")])
21725
21726 (define_insn "gtv4hi3"
21727   [(set (match_operand:V4HI 0 "register_operand" "=y")
21728         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21729                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21730   "TARGET_MMX"
21731   "pcmpgtw\t{%2, %0|%0, %2}"
21732   [(set_attr "type" "mmxcmp")
21733    (set_attr "mode" "DI")])
21734
21735 (define_insn "gtv2si3"
21736   [(set (match_operand:V2SI 0 "register_operand" "=y")
21737         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21738                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21739   "TARGET_MMX"
21740   "pcmpgtd\t{%2, %0|%0, %2}"
21741   [(set_attr "type" "mmxcmp")
21742    (set_attr "mode" "DI")])
21743
21744
21745 ;; MMX max/min insns
21746
21747 (define_insn "umaxv8qi3"
21748   [(set (match_operand:V8QI 0 "register_operand" "=y")
21749         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21750                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21751   "TARGET_SSE || TARGET_3DNOW_A"
21752   "pmaxub\t{%2, %0|%0, %2}"
21753   [(set_attr "type" "mmxadd")
21754    (set_attr "mode" "DI")])
21755
21756 (define_insn "smaxv4hi3"
21757   [(set (match_operand:V4HI 0 "register_operand" "=y")
21758         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21759                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21760   "TARGET_SSE || TARGET_3DNOW_A"
21761   "pmaxsw\t{%2, %0|%0, %2}"
21762   [(set_attr "type" "mmxadd")
21763    (set_attr "mode" "DI")])
21764
21765 (define_insn "uminv8qi3"
21766   [(set (match_operand:V8QI 0 "register_operand" "=y")
21767         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21768                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21769   "TARGET_SSE || TARGET_3DNOW_A"
21770   "pminub\t{%2, %0|%0, %2}"
21771   [(set_attr "type" "mmxadd")
21772    (set_attr "mode" "DI")])
21773
21774 (define_insn "sminv4hi3"
21775   [(set (match_operand:V4HI 0 "register_operand" "=y")
21776         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21777                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21778   "TARGET_SSE || TARGET_3DNOW_A"
21779   "pminsw\t{%2, %0|%0, %2}"
21780   [(set_attr "type" "mmxadd")
21781    (set_attr "mode" "DI")])
21782
21783
21784 ;; MMX shifts
21785
21786 (define_insn "ashrv4hi3"
21787   [(set (match_operand:V4HI 0 "register_operand" "=y")
21788         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21789                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21790   "TARGET_MMX"
21791   "psraw\t{%2, %0|%0, %2}"
21792   [(set_attr "type" "mmxshft")
21793    (set_attr "mode" "DI")])
21794
21795 (define_insn "ashrv2si3"
21796   [(set (match_operand:V2SI 0 "register_operand" "=y")
21797         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21798                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21799   "TARGET_MMX"
21800   "psrad\t{%2, %0|%0, %2}"
21801   [(set_attr "type" "mmxshft")
21802    (set_attr "mode" "DI")])
21803
21804 (define_insn "lshrv4hi3"
21805   [(set (match_operand:V4HI 0 "register_operand" "=y")
21806         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21807                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21808   "TARGET_MMX"
21809   "psrlw\t{%2, %0|%0, %2}"
21810   [(set_attr "type" "mmxshft")
21811    (set_attr "mode" "DI")])
21812
21813 (define_insn "lshrv2si3"
21814   [(set (match_operand:V2SI 0 "register_operand" "=y")
21815         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21816                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21817   "TARGET_MMX"
21818   "psrld\t{%2, %0|%0, %2}"
21819   [(set_attr "type" "mmxshft")
21820    (set_attr "mode" "DI")])
21821
21822 ;; See logical MMX insns.
21823 (define_insn "mmx_lshrdi3"
21824   [(set (match_operand:DI 0 "register_operand" "=y")
21825         (unspec:DI
21826           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21827                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
21828           UNSPEC_NOP))]
21829   "TARGET_MMX"
21830   "psrlq\t{%2, %0|%0, %2}"
21831   [(set_attr "type" "mmxshft")
21832    (set_attr "mode" "DI")])
21833
21834 (define_insn "ashlv4hi3"
21835   [(set (match_operand:V4HI 0 "register_operand" "=y")
21836         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21837                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21838   "TARGET_MMX"
21839   "psllw\t{%2, %0|%0, %2}"
21840   [(set_attr "type" "mmxshft")
21841    (set_attr "mode" "DI")])
21842
21843 (define_insn "ashlv2si3"
21844   [(set (match_operand:V2SI 0 "register_operand" "=y")
21845         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21846                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21847   "TARGET_MMX"
21848   "pslld\t{%2, %0|%0, %2}"
21849   [(set_attr "type" "mmxshft")
21850    (set_attr "mode" "DI")])
21851
21852 ;; See logical MMX insns.
21853 (define_insn "mmx_ashldi3"
21854   [(set (match_operand:DI 0 "register_operand" "=y")
21855         (unspec:DI
21856          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21857                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
21858          UNSPEC_NOP))]
21859   "TARGET_MMX"
21860   "psllq\t{%2, %0|%0, %2}"
21861   [(set_attr "type" "mmxshft")
21862    (set_attr "mode" "DI")])
21863
21864
21865 ;; MMX pack/unpack insns.
21866
21867 (define_insn "mmx_packsswb"
21868   [(set (match_operand:V8QI 0 "register_operand" "=y")
21869         (vec_concat:V8QI
21870          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21871          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21872   "TARGET_MMX"
21873   "packsswb\t{%2, %0|%0, %2}"
21874   [(set_attr "type" "mmxshft")
21875    (set_attr "mode" "DI")])
21876
21877 (define_insn "mmx_packssdw"
21878   [(set (match_operand:V4HI 0 "register_operand" "=y")
21879         (vec_concat:V4HI
21880          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21881          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21882   "TARGET_MMX"
21883   "packssdw\t{%2, %0|%0, %2}"
21884   [(set_attr "type" "mmxshft")
21885    (set_attr "mode" "DI")])
21886
21887 (define_insn "mmx_packuswb"
21888   [(set (match_operand:V8QI 0 "register_operand" "=y")
21889         (vec_concat:V8QI
21890          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21891          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21892   "TARGET_MMX"
21893   "packuswb\t{%2, %0|%0, %2}"
21894   [(set_attr "type" "mmxshft")
21895    (set_attr "mode" "DI")])
21896
21897 (define_insn "mmx_punpckhbw"
21898   [(set (match_operand:V8QI 0 "register_operand" "=y")
21899         (vec_merge:V8QI
21900          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21901                           (parallel [(const_int 4)
21902                                      (const_int 0)
21903                                      (const_int 5)
21904                                      (const_int 1)
21905                                      (const_int 6)
21906                                      (const_int 2)
21907                                      (const_int 7)
21908                                      (const_int 3)]))
21909          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21910                           (parallel [(const_int 0)
21911                                      (const_int 4)
21912                                      (const_int 1)
21913                                      (const_int 5)
21914                                      (const_int 2)
21915                                      (const_int 6)
21916                                      (const_int 3)
21917                                      (const_int 7)]))
21918          (const_int 85)))]
21919   "TARGET_MMX"
21920   "punpckhbw\t{%2, %0|%0, %2}"
21921   [(set_attr "type" "mmxcvt")
21922    (set_attr "mode" "DI")])
21923
21924 (define_insn "mmx_punpckhwd"
21925   [(set (match_operand:V4HI 0 "register_operand" "=y")
21926         (vec_merge:V4HI
21927          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21928                           (parallel [(const_int 0)
21929                                      (const_int 2)
21930                                      (const_int 1)
21931                                      (const_int 3)]))
21932          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21933                           (parallel [(const_int 2)
21934                                      (const_int 0)
21935                                      (const_int 3)
21936                                      (const_int 1)]))
21937          (const_int 5)))]
21938   "TARGET_MMX"
21939   "punpckhwd\t{%2, %0|%0, %2}"
21940   [(set_attr "type" "mmxcvt")
21941    (set_attr "mode" "DI")])
21942
21943 (define_insn "mmx_punpckhdq"
21944   [(set (match_operand:V2SI 0 "register_operand" "=y")
21945         (vec_merge:V2SI
21946          (match_operand:V2SI 1 "register_operand" "0")
21947          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21948                           (parallel [(const_int 1)
21949                                      (const_int 0)]))
21950          (const_int 1)))]
21951   "TARGET_MMX"
21952   "punpckhdq\t{%2, %0|%0, %2}"
21953   [(set_attr "type" "mmxcvt")
21954    (set_attr "mode" "DI")])
21955
21956 (define_insn "mmx_punpcklbw"
21957   [(set (match_operand:V8QI 0 "register_operand" "=y")
21958         (vec_merge:V8QI
21959          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21960                           (parallel [(const_int 0)
21961                                      (const_int 4)
21962                                      (const_int 1)
21963                                      (const_int 5)
21964                                      (const_int 2)
21965                                      (const_int 6)
21966                                      (const_int 3)
21967                                      (const_int 7)]))
21968          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21969                           (parallel [(const_int 4)
21970                                      (const_int 0)
21971                                      (const_int 5)
21972                                      (const_int 1)
21973                                      (const_int 6)
21974                                      (const_int 2)
21975                                      (const_int 7)
21976                                      (const_int 3)]))
21977          (const_int 85)))]
21978   "TARGET_MMX"
21979   "punpcklbw\t{%2, %0|%0, %2}"
21980   [(set_attr "type" "mmxcvt")
21981    (set_attr "mode" "DI")])
21982
21983 (define_insn "mmx_punpcklwd"
21984   [(set (match_operand:V4HI 0 "register_operand" "=y")
21985         (vec_merge:V4HI
21986          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21987                           (parallel [(const_int 2)
21988                                      (const_int 0)
21989                                      (const_int 3)
21990                                      (const_int 1)]))
21991          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21992                           (parallel [(const_int 0)
21993                                      (const_int 2)
21994                                      (const_int 1)
21995                                      (const_int 3)]))
21996          (const_int 5)))]
21997   "TARGET_MMX"
21998   "punpcklwd\t{%2, %0|%0, %2}"
21999   [(set_attr "type" "mmxcvt")
22000    (set_attr "mode" "DI")])
22001
22002 (define_insn "mmx_punpckldq"
22003   [(set (match_operand:V2SI 0 "register_operand" "=y")
22004         (vec_merge:V2SI
22005          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
22006                            (parallel [(const_int 1)
22007                                       (const_int 0)]))
22008          (match_operand:V2SI 2 "register_operand" "y")
22009          (const_int 1)))]
22010   "TARGET_MMX"
22011   "punpckldq\t{%2, %0|%0, %2}"
22012   [(set_attr "type" "mmxcvt")
22013    (set_attr "mode" "DI")])
22014
22015
22016 ;; Miscellaneous stuff
22017
22018 (define_insn "emms"
22019   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
22020    (clobber (reg:XF 8))
22021    (clobber (reg:XF 9))
22022    (clobber (reg:XF 10))
22023    (clobber (reg:XF 11))
22024    (clobber (reg:XF 12))
22025    (clobber (reg:XF 13))
22026    (clobber (reg:XF 14))
22027    (clobber (reg:XF 15))
22028    (clobber (reg:DI 29))
22029    (clobber (reg:DI 30))
22030    (clobber (reg:DI 31))
22031    (clobber (reg:DI 32))
22032    (clobber (reg:DI 33))
22033    (clobber (reg:DI 34))
22034    (clobber (reg:DI 35))
22035    (clobber (reg:DI 36))]
22036   "TARGET_MMX"
22037   "emms"
22038   [(set_attr "type" "mmx")
22039    (set_attr "memory" "unknown")])
22040
22041 (define_insn "ldmxcsr"
22042   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
22043                     UNSPECV_LDMXCSR)]
22044   "TARGET_SSE"
22045   "ldmxcsr\t%0"
22046   [(set_attr "type" "sse")
22047    (set_attr "memory" "load")])
22048
22049 (define_insn "stmxcsr"
22050   [(set (match_operand:SI 0 "memory_operand" "=m")
22051         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
22052   "TARGET_SSE"
22053   "stmxcsr\t%0"
22054   [(set_attr "type" "sse")
22055    (set_attr "memory" "store")])
22056
22057 (define_expand "sfence"
22058   [(set (match_dup 0)
22059         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22060   "TARGET_SSE || TARGET_3DNOW_A"
22061 {
22062   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22063   MEM_VOLATILE_P (operands[0]) = 1;
22064 })
22065
22066 (define_insn "*sfence_insn"
22067   [(set (match_operand:BLK 0 "" "")
22068         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22069   "TARGET_SSE || TARGET_3DNOW_A"
22070   "sfence"
22071   [(set_attr "type" "sse")
22072    (set_attr "memory" "unknown")])
22073
22074 (define_expand "sse_prologue_save"
22075   [(parallel [(set (match_operand:BLK 0 "" "")
22076                    (unspec:BLK [(reg:DI 21)
22077                                 (reg:DI 22)
22078                                 (reg:DI 23)
22079                                 (reg:DI 24)
22080                                 (reg:DI 25)
22081                                 (reg:DI 26)
22082                                 (reg:DI 27)
22083                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22084               (use (match_operand:DI 1 "register_operand" ""))
22085               (use (match_operand:DI 2 "immediate_operand" ""))
22086               (use (label_ref:DI (match_operand 3 "" "")))])]
22087   "TARGET_64BIT"
22088   "")
22089
22090 (define_insn "*sse_prologue_save_insn"
22091   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22092                           (match_operand:DI 4 "const_int_operand" "n")))
22093         (unspec:BLK [(reg:DI 21)
22094                      (reg:DI 22)
22095                      (reg:DI 23)
22096                      (reg:DI 24)
22097                      (reg:DI 25)
22098                      (reg:DI 26)
22099                      (reg:DI 27)
22100                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22101    (use (match_operand:DI 1 "register_operand" "r"))
22102    (use (match_operand:DI 2 "const_int_operand" "i"))
22103    (use (label_ref:DI (match_operand 3 "" "X")))]
22104   "TARGET_64BIT
22105    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
22106    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22107   "*
22108 {
22109   int i;
22110   operands[0] = gen_rtx_MEM (Pmode,
22111                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22112   output_asm_insn (\"jmp\\t%A1\", operands);
22113   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22114     {
22115       operands[4] = adjust_address (operands[0], DImode, i*16);
22116       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22117       PUT_MODE (operands[4], TImode);
22118       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22119         output_asm_insn (\"rex\", operands);
22120       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
22121     }
22122   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
22123                              CODE_LABEL_NUMBER (operands[3]));
22124   RET;
22125 }
22126   "
22127   [(set_attr "type" "other")
22128    (set_attr "length_immediate" "0")
22129    (set_attr "length_address" "0")
22130    (set_attr "length" "135")
22131    (set_attr "memory" "store")
22132    (set_attr "modrm" "0")
22133    (set_attr "mode" "DI")])
22134
22135 ;; 3Dnow! instructions
22136
22137 (define_insn "addv2sf3"
22138   [(set (match_operand:V2SF 0 "register_operand" "=y")
22139         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22140                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22141   "TARGET_3DNOW"
22142   "pfadd\\t{%2, %0|%0, %2}"
22143   [(set_attr "type" "mmxadd")
22144    (set_attr "mode" "V2SF")])
22145
22146 (define_insn "subv2sf3"
22147   [(set (match_operand:V2SF 0 "register_operand" "=y")
22148         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22149                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22150   "TARGET_3DNOW"
22151   "pfsub\\t{%2, %0|%0, %2}"
22152   [(set_attr "type" "mmxadd")
22153    (set_attr "mode" "V2SF")])
22154
22155 (define_insn "subrv2sf3"
22156   [(set (match_operand:V2SF 0 "register_operand" "=y")
22157         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
22158                     (match_operand:V2SF 1 "register_operand" "0")))]
22159   "TARGET_3DNOW"
22160   "pfsubr\\t{%2, %0|%0, %2}"
22161   [(set_attr "type" "mmxadd")
22162    (set_attr "mode" "V2SF")])
22163
22164 (define_insn "gtv2sf3"
22165   [(set (match_operand:V2SI 0 "register_operand" "=y")
22166         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
22167                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22168  "TARGET_3DNOW"
22169   "pfcmpgt\\t{%2, %0|%0, %2}"
22170   [(set_attr "type" "mmxcmp")
22171    (set_attr "mode" "V2SF")])
22172
22173 (define_insn "gev2sf3"
22174   [(set (match_operand:V2SI 0 "register_operand" "=y")
22175         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
22176                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22177   "TARGET_3DNOW"
22178   "pfcmpge\\t{%2, %0|%0, %2}"
22179   [(set_attr "type" "mmxcmp")
22180    (set_attr "mode" "V2SF")])
22181
22182 (define_insn "eqv2sf3"
22183   [(set (match_operand:V2SI 0 "register_operand" "=y")
22184         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
22185                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22186   "TARGET_3DNOW"
22187   "pfcmpeq\\t{%2, %0|%0, %2}"
22188   [(set_attr "type" "mmxcmp")
22189    (set_attr "mode" "V2SF")])
22190
22191 (define_insn "pfmaxv2sf3"
22192   [(set (match_operand:V2SF 0 "register_operand" "=y")
22193         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
22194                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22195   "TARGET_3DNOW"
22196   "pfmax\\t{%2, %0|%0, %2}"
22197   [(set_attr "type" "mmxadd")
22198    (set_attr "mode" "V2SF")])
22199
22200 (define_insn "pfminv2sf3"
22201   [(set (match_operand:V2SF 0 "register_operand" "=y")
22202         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
22203                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22204   "TARGET_3DNOW"
22205   "pfmin\\t{%2, %0|%0, %2}"
22206   [(set_attr "type" "mmxadd")
22207    (set_attr "mode" "V2SF")])
22208
22209 (define_insn "mulv2sf3"
22210   [(set (match_operand:V2SF 0 "register_operand" "=y")
22211         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
22212                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22213   "TARGET_3DNOW"
22214   "pfmul\\t{%2, %0|%0, %2}"
22215   [(set_attr "type" "mmxmul")
22216    (set_attr "mode" "V2SF")])
22217
22218 (define_insn "femms"
22219   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
22220    (clobber (reg:XF 8))
22221    (clobber (reg:XF 9))
22222    (clobber (reg:XF 10))
22223    (clobber (reg:XF 11))
22224    (clobber (reg:XF 12))
22225    (clobber (reg:XF 13))
22226    (clobber (reg:XF 14))
22227    (clobber (reg:XF 15))
22228    (clobber (reg:DI 29))
22229    (clobber (reg:DI 30))
22230    (clobber (reg:DI 31))
22231    (clobber (reg:DI 32))
22232    (clobber (reg:DI 33))
22233    (clobber (reg:DI 34))
22234    (clobber (reg:DI 35))
22235    (clobber (reg:DI 36))]
22236   "TARGET_3DNOW"
22237   "femms"
22238   [(set_attr "type" "mmx")
22239    (set_attr "memory" "none")]) 
22240
22241 (define_insn "pf2id"
22242   [(set (match_operand:V2SI 0 "register_operand" "=y")
22243         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
22244   "TARGET_3DNOW"
22245   "pf2id\\t{%1, %0|%0, %1}"
22246   [(set_attr "type" "mmxcvt")
22247    (set_attr "mode" "V2SF")])
22248
22249 (define_insn "pf2iw"
22250   [(set (match_operand:V2SI 0 "register_operand" "=y")
22251         (sign_extend:V2SI
22252            (ss_truncate:V2HI
22253               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22254   "TARGET_3DNOW_A"
22255   "pf2iw\\t{%1, %0|%0, %1}"
22256   [(set_attr "type" "mmxcvt")
22257    (set_attr "mode" "V2SF")])
22258
22259 (define_insn "pfacc"
22260   [(set (match_operand:V2SF 0 "register_operand" "=y")
22261         (vec_concat:V2SF
22262            (plus:SF
22263               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22264                              (parallel [(const_int  0)]))
22265               (vec_select:SF (match_dup 1)
22266                              (parallel [(const_int 1)])))
22267            (plus:SF
22268               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22269                              (parallel [(const_int  0)]))
22270               (vec_select:SF (match_dup 2)
22271                              (parallel [(const_int 1)])))))]
22272   "TARGET_3DNOW"
22273   "pfacc\\t{%2, %0|%0, %2}"
22274   [(set_attr "type" "mmxadd")
22275    (set_attr "mode" "V2SF")])
22276
22277 (define_insn "pfnacc"
22278   [(set (match_operand:V2SF 0 "register_operand" "=y")
22279         (vec_concat:V2SF
22280            (minus:SF
22281               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22282                              (parallel [(const_int 0)]))
22283               (vec_select:SF (match_dup 1)
22284                              (parallel [(const_int 1)])))
22285            (minus:SF
22286               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22287                              (parallel [(const_int  0)]))
22288               (vec_select:SF (match_dup 2)
22289                              (parallel [(const_int 1)])))))]
22290   "TARGET_3DNOW_A"
22291   "pfnacc\\t{%2, %0|%0, %2}"
22292   [(set_attr "type" "mmxadd")
22293    (set_attr "mode" "V2SF")])
22294
22295 (define_insn "pfpnacc"
22296   [(set (match_operand:V2SF 0 "register_operand" "=y")
22297         (vec_concat:V2SF
22298            (minus:SF
22299               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22300                              (parallel [(const_int 0)]))
22301               (vec_select:SF (match_dup 1)
22302                              (parallel [(const_int 1)])))
22303            (plus:SF
22304               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22305                              (parallel [(const_int 0)]))
22306               (vec_select:SF (match_dup 2)
22307                              (parallel [(const_int 1)])))))]
22308   "TARGET_3DNOW_A"
22309   "pfpnacc\\t{%2, %0|%0, %2}"
22310   [(set_attr "type" "mmxadd")
22311    (set_attr "mode" "V2SF")])
22312
22313 (define_insn "pi2fw"
22314   [(set (match_operand:V2SF 0 "register_operand" "=y")
22315         (float:V2SF
22316            (vec_concat:V2SI
22317               (sign_extend:SI
22318                  (truncate:HI
22319                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22320                                    (parallel [(const_int 0)]))))
22321               (sign_extend:SI
22322                  (truncate:HI
22323                     (vec_select:SI (match_dup 1)
22324                                    (parallel [(const_int  1)])))))))]
22325   "TARGET_3DNOW_A"
22326   "pi2fw\\t{%1, %0|%0, %1}"
22327   [(set_attr "type" "mmxcvt")
22328    (set_attr "mode" "V2SF")])
22329
22330 (define_insn "floatv2si2"
22331   [(set (match_operand:V2SF 0 "register_operand" "=y")
22332         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22333   "TARGET_3DNOW"
22334   "pi2fd\\t{%1, %0|%0, %1}"
22335   [(set_attr "type" "mmxcvt")
22336    (set_attr "mode" "V2SF")])
22337
22338 ;; This insn is identical to pavgb in operation, but the opcode is
22339 ;; different.  To avoid accidentally matching pavgb, use an unspec.
22340
22341 (define_insn "pavgusb"
22342  [(set (match_operand:V8QI 0 "register_operand" "=y")
22343        (unspec:V8QI
22344           [(match_operand:V8QI 1 "register_operand" "0")
22345            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22346           UNSPEC_PAVGUSB))]
22347   "TARGET_3DNOW"
22348   "pavgusb\\t{%2, %0|%0, %2}"
22349   [(set_attr "type" "mmxshft")
22350    (set_attr "mode" "TI")])
22351
22352 ;; 3DNow reciprocal and sqrt
22353  
22354 (define_insn "pfrcpv2sf2"
22355   [(set (match_operand:V2SF 0 "register_operand" "=y")
22356         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22357         UNSPEC_PFRCP))]
22358   "TARGET_3DNOW"
22359   "pfrcp\\t{%1, %0|%0, %1}"
22360   [(set_attr "type" "mmx")
22361    (set_attr "mode" "TI")])
22362
22363 (define_insn "pfrcpit1v2sf3"
22364   [(set (match_operand:V2SF 0 "register_operand" "=y")
22365         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22366                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22367                      UNSPEC_PFRCPIT1))]
22368   "TARGET_3DNOW"
22369   "pfrcpit1\\t{%2, %0|%0, %2}"
22370   [(set_attr "type" "mmx")
22371    (set_attr "mode" "TI")])
22372
22373 (define_insn "pfrcpit2v2sf3"
22374   [(set (match_operand:V2SF 0 "register_operand" "=y")
22375         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22376                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22377                      UNSPEC_PFRCPIT2))]
22378   "TARGET_3DNOW"
22379   "pfrcpit2\\t{%2, %0|%0, %2}"
22380   [(set_attr "type" "mmx")
22381    (set_attr "mode" "TI")])
22382
22383 (define_insn "pfrsqrtv2sf2"
22384   [(set (match_operand:V2SF 0 "register_operand" "=y")
22385         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22386                      UNSPEC_PFRSQRT))]
22387   "TARGET_3DNOW"
22388   "pfrsqrt\\t{%1, %0|%0, %1}"
22389   [(set_attr "type" "mmx")
22390    (set_attr "mode" "TI")])
22391                 
22392 (define_insn "pfrsqit1v2sf3"
22393   [(set (match_operand:V2SF 0 "register_operand" "=y")
22394         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22395                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22396                      UNSPEC_PFRSQIT1))]
22397   "TARGET_3DNOW"
22398   "pfrsqit1\\t{%2, %0|%0, %2}"
22399   [(set_attr "type" "mmx")
22400    (set_attr "mode" "TI")])
22401
22402 (define_insn "pmulhrwv4hi3"
22403   [(set (match_operand:V4HI 0 "register_operand" "=y")
22404         (truncate:V4HI
22405            (lshiftrt:V4SI
22406               (plus:V4SI
22407                  (mult:V4SI
22408                     (sign_extend:V4SI
22409                        (match_operand:V4HI 1 "register_operand" "0"))
22410                     (sign_extend:V4SI
22411                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22412                  (const_vector:V4SI [(const_int 32768)
22413                                      (const_int 32768)
22414                                      (const_int 32768)
22415                                      (const_int 32768)]))
22416               (const_int 16))))]
22417   "TARGET_3DNOW"
22418   "pmulhrw\\t{%2, %0|%0, %2}"
22419   [(set_attr "type" "mmxmul")
22420    (set_attr "mode" "TI")])
22421
22422 (define_insn "pswapdv2si2"
22423   [(set (match_operand:V2SI 0 "register_operand" "=y")
22424         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22425                          (parallel [(const_int 1) (const_int 0)])))]
22426   "TARGET_3DNOW_A"
22427   "pswapd\\t{%1, %0|%0, %1}"
22428   [(set_attr "type" "mmxcvt")
22429    (set_attr "mode" "TI")])
22430
22431 (define_insn "pswapdv2sf2"
22432   [(set (match_operand:V2SF 0 "register_operand" "=y")
22433         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22434                          (parallel [(const_int 1) (const_int 0)])))]
22435   "TARGET_3DNOW_A"
22436   "pswapd\\t{%1, %0|%0, %1}"
22437   [(set_attr "type" "mmxcvt")
22438    (set_attr "mode" "TI")])
22439
22440 (define_expand "prefetch"
22441   [(prefetch (match_operand 0 "address_operand" "")
22442              (match_operand:SI 1 "const_int_operand" "")
22443              (match_operand:SI 2 "const_int_operand" ""))]
22444   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22445 {
22446   int rw = INTVAL (operands[1]);
22447   int locality = INTVAL (operands[2]);
22448
22449   if (rw != 0 && rw != 1)
22450     abort ();
22451   if (locality < 0 || locality > 3)
22452     abort ();
22453   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22454     abort ();
22455
22456   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22457      suported by SSE counterpart or the SSE prefetch is not available
22458      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22459      of locality.  */
22460   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22461     operands[2] = GEN_INT (3);
22462   else
22463     operands[1] = const0_rtx;
22464 })
22465
22466 (define_insn "*prefetch_sse"
22467   [(prefetch (match_operand:SI 0 "address_operand" "p")
22468              (const_int 0)
22469              (match_operand:SI 1 "const_int_operand" ""))]
22470   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22471 {
22472   static const char * const patterns[4] = {
22473    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22474   };
22475
22476   int locality = INTVAL (operands[1]);
22477   if (locality < 0 || locality > 3)
22478     abort ();
22479
22480   return patterns[locality];  
22481 }
22482   [(set_attr "type" "sse")
22483    (set_attr "memory" "none")])
22484
22485 (define_insn "*prefetch_sse_rex"
22486   [(prefetch (match_operand:DI 0 "address_operand" "p")
22487              (const_int 0)
22488              (match_operand:SI 1 "const_int_operand" ""))]
22489   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22490 {
22491   static const char * const patterns[4] = {
22492    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22493   };
22494
22495   int locality = INTVAL (operands[1]);
22496   if (locality < 0 || locality > 3)
22497     abort ();
22498
22499   return patterns[locality];  
22500 }
22501   [(set_attr "type" "sse")
22502    (set_attr "memory" "none")])
22503
22504 (define_insn "*prefetch_3dnow"
22505   [(prefetch (match_operand:SI 0 "address_operand" "p")
22506              (match_operand:SI 1 "const_int_operand" "n")
22507              (const_int 3))]
22508   "TARGET_3DNOW && !TARGET_64BIT"
22509 {
22510   if (INTVAL (operands[1]) == 0)
22511     return "prefetch\t%a0";
22512   else
22513     return "prefetchw\t%a0";
22514 }
22515   [(set_attr "type" "mmx")
22516    (set_attr "memory" "none")])
22517
22518 (define_insn "*prefetch_3dnow_rex"
22519   [(prefetch (match_operand:DI 0 "address_operand" "p")
22520              (match_operand:SI 1 "const_int_operand" "n")
22521              (const_int 3))]
22522   "TARGET_3DNOW && TARGET_64BIT"
22523 {
22524   if (INTVAL (operands[1]) == 0)
22525     return "prefetch\t%a0";
22526   else
22527     return "prefetchw\t%a0";
22528 }
22529   [(set_attr "type" "mmx")
22530    (set_attr "memory" "none")])
22531
22532 ;; SSE2 support
22533
22534 (define_insn "addv2df3"
22535   [(set (match_operand:V2DF 0 "register_operand" "=x")
22536         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22537                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22538   "TARGET_SSE2"
22539   "addpd\t{%2, %0|%0, %2}"
22540   [(set_attr "type" "sseadd")
22541    (set_attr "mode" "V2DF")])
22542
22543 (define_insn "vmaddv2df3"
22544   [(set (match_operand:V2DF 0 "register_operand" "=x")
22545         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22546                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22547                         (match_dup 1)
22548                         (const_int 1)))]
22549   "TARGET_SSE2"
22550   "addsd\t{%2, %0|%0, %2}"
22551   [(set_attr "type" "sseadd")
22552    (set_attr "mode" "DF")])
22553
22554 (define_insn "subv2df3"
22555   [(set (match_operand:V2DF 0 "register_operand" "=x")
22556         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22557                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22558   "TARGET_SSE2"
22559   "subpd\t{%2, %0|%0, %2}"
22560   [(set_attr "type" "sseadd")
22561    (set_attr "mode" "V2DF")])
22562
22563 (define_insn "vmsubv2df3"
22564   [(set (match_operand:V2DF 0 "register_operand" "=x")
22565         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22566                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22567                         (match_dup 1)
22568                         (const_int 1)))]
22569   "TARGET_SSE2"
22570   "subsd\t{%2, %0|%0, %2}"
22571   [(set_attr "type" "sseadd")
22572    (set_attr "mode" "DF")])
22573
22574 (define_insn "mulv2df3"
22575   [(set (match_operand:V2DF 0 "register_operand" "=x")
22576         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22577                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22578   "TARGET_SSE2"
22579   "mulpd\t{%2, %0|%0, %2}"
22580   [(set_attr "type" "ssemul")
22581    (set_attr "mode" "V2DF")])
22582
22583 (define_insn "vmmulv2df3"
22584   [(set (match_operand:V2DF 0 "register_operand" "=x")
22585         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22586                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22587                         (match_dup 1)
22588                         (const_int 1)))]
22589   "TARGET_SSE2"
22590   "mulsd\t{%2, %0|%0, %2}"
22591   [(set_attr "type" "ssemul")
22592    (set_attr "mode" "DF")])
22593
22594 (define_insn "divv2df3"
22595   [(set (match_operand:V2DF 0 "register_operand" "=x")
22596         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22597                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22598   "TARGET_SSE2"
22599   "divpd\t{%2, %0|%0, %2}"
22600   [(set_attr "type" "ssediv")
22601    (set_attr "mode" "V2DF")])
22602
22603 (define_insn "vmdivv2df3"
22604   [(set (match_operand:V2DF 0 "register_operand" "=x")
22605         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22606                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22607                         (match_dup 1)
22608                         (const_int 1)))]
22609   "TARGET_SSE2"
22610   "divsd\t{%2, %0|%0, %2}"
22611   [(set_attr "type" "ssediv")
22612    (set_attr "mode" "DF")])
22613
22614 ;; SSE min/max
22615
22616 (define_insn "smaxv2df3"
22617   [(set (match_operand:V2DF 0 "register_operand" "=x")
22618         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22619                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22620   "TARGET_SSE2"
22621   "maxpd\t{%2, %0|%0, %2}"
22622   [(set_attr "type" "sseadd")
22623    (set_attr "mode" "V2DF")])
22624
22625 (define_insn "vmsmaxv2df3"
22626   [(set (match_operand:V2DF 0 "register_operand" "=x")
22627         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22628                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22629                         (match_dup 1)
22630                         (const_int 1)))]
22631   "TARGET_SSE2"
22632   "maxsd\t{%2, %0|%0, %2}"
22633   [(set_attr "type" "sseadd")
22634    (set_attr "mode" "DF")])
22635
22636 (define_insn "sminv2df3"
22637   [(set (match_operand:V2DF 0 "register_operand" "=x")
22638         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22639                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22640   "TARGET_SSE2"
22641   "minpd\t{%2, %0|%0, %2}"
22642   [(set_attr "type" "sseadd")
22643    (set_attr "mode" "V2DF")])
22644
22645 (define_insn "vmsminv2df3"
22646   [(set (match_operand:V2DF 0 "register_operand" "=x")
22647         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22648                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22649                         (match_dup 1)
22650                         (const_int 1)))]
22651   "TARGET_SSE2"
22652   "minsd\t{%2, %0|%0, %2}"
22653   [(set_attr "type" "sseadd")
22654    (set_attr "mode" "DF")])
22655 ;; SSE2 square root.  There doesn't appear to be an extension for the
22656 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22657
22658 (define_insn "sqrtv2df2"
22659   [(set (match_operand:V2DF 0 "register_operand" "=x")
22660         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22661   "TARGET_SSE2"
22662   "sqrtpd\t{%1, %0|%0, %1}"
22663   [(set_attr "type" "sse")
22664    (set_attr "mode" "V2DF")])
22665
22666 (define_insn "vmsqrtv2df2"
22667   [(set (match_operand:V2DF 0 "register_operand" "=x")
22668         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22669                         (match_operand:V2DF 2 "register_operand" "0")
22670                         (const_int 1)))]
22671   "TARGET_SSE2"
22672   "sqrtsd\t{%1, %0|%0, %1}"
22673   [(set_attr "type" "sse")
22674    (set_attr "mode" "SF")])
22675
22676 ;; SSE mask-generating compares
22677
22678 (define_insn "maskcmpv2df3"
22679   [(set (match_operand:V2DI 0 "register_operand" "=x")
22680         (match_operator:V2DI 3 "sse_comparison_operator"
22681                              [(match_operand:V2DF 1 "register_operand" "0")
22682                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22683   "TARGET_SSE2"
22684   "cmp%D3pd\t{%2, %0|%0, %2}"
22685   [(set_attr "type" "ssecmp")
22686    (set_attr "mode" "V2DF")])
22687
22688 (define_insn "maskncmpv2df3"
22689   [(set (match_operand:V2DI 0 "register_operand" "=x")
22690         (not:V2DI
22691          (match_operator:V2DI 3 "sse_comparison_operator"
22692                               [(match_operand:V2DF 1 "register_operand" "0")
22693                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22694   "TARGET_SSE2"
22695 {
22696   if (GET_CODE (operands[3]) == UNORDERED)
22697     return "cmpordps\t{%2, %0|%0, %2}";
22698   else
22699     return "cmpn%D3pd\t{%2, %0|%0, %2}";
22700 }
22701   [(set_attr "type" "ssecmp")
22702    (set_attr "mode" "V2DF")])
22703
22704 (define_insn "vmmaskcmpv2df3"
22705   [(set (match_operand:V2DI 0 "register_operand" "=x")
22706         (vec_merge:V2DI
22707          (match_operator:V2DI 3 "sse_comparison_operator"
22708                               [(match_operand:V2DF 1 "register_operand" "0")
22709                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22710          (subreg:V2DI (match_dup 1) 0)
22711          (const_int 1)))]
22712   "TARGET_SSE2"
22713   "cmp%D3sd\t{%2, %0|%0, %2}"
22714   [(set_attr "type" "ssecmp")
22715    (set_attr "mode" "DF")])
22716
22717 (define_insn "vmmaskncmpv2df3"
22718   [(set (match_operand:V2DI 0 "register_operand" "=x")
22719         (vec_merge:V2DI
22720          (not:V2DI
22721           (match_operator:V2DI 3 "sse_comparison_operator"
22722                                [(match_operand:V2DF 1 "register_operand" "0")
22723                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22724          (subreg:V2DI (match_dup 1) 0)
22725          (const_int 1)))]
22726   "TARGET_SSE2"
22727 {
22728   if (GET_CODE (operands[3]) == UNORDERED)
22729     return "cmpordsd\t{%2, %0|%0, %2}";
22730   else
22731     return "cmpn%D3sd\t{%2, %0|%0, %2}";
22732 }
22733   [(set_attr "type" "ssecmp")
22734    (set_attr "mode" "DF")])
22735
22736 (define_insn "sse2_comi"
22737   [(set (reg:CCFP FLAGS_REG)
22738         (compare:CCFP (vec_select:DF
22739                        (match_operand:V2DF 0 "register_operand" "x")
22740                        (parallel [(const_int 0)]))
22741                       (vec_select:DF
22742                        (match_operand:V2DF 1 "register_operand" "x")
22743                        (parallel [(const_int 0)]))))]
22744   "TARGET_SSE2"
22745   "comisd\t{%1, %0|%0, %1}"
22746   [(set_attr "type" "ssecomi")
22747    (set_attr "mode" "DF")])
22748
22749 (define_insn "sse2_ucomi"
22750   [(set (reg:CCFPU FLAGS_REG)
22751         (compare:CCFPU (vec_select:DF
22752                          (match_operand:V2DF 0 "register_operand" "x")
22753                          (parallel [(const_int 0)]))
22754                         (vec_select:DF
22755                          (match_operand:V2DF 1 "register_operand" "x")
22756                          (parallel [(const_int 0)]))))]
22757   "TARGET_SSE2"
22758   "ucomisd\t{%1, %0|%0, %1}"
22759   [(set_attr "type" "ssecomi")
22760    (set_attr "mode" "DF")])
22761
22762 ;; SSE Strange Moves.
22763
22764 (define_insn "sse2_movmskpd"
22765   [(set (match_operand:SI 0 "register_operand" "=r")
22766         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22767                    UNSPEC_MOVMSK))]
22768   "TARGET_SSE2"
22769   "movmskpd\t{%1, %0|%0, %1}"
22770   [(set_attr "type" "ssecvt")
22771    (set_attr "mode" "V2DF")])
22772
22773 (define_insn "sse2_pmovmskb"
22774   [(set (match_operand:SI 0 "register_operand" "=r")
22775         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22776                    UNSPEC_MOVMSK))]
22777   "TARGET_SSE2"
22778   "pmovmskb\t{%1, %0|%0, %1}"
22779   [(set_attr "type" "ssecvt")
22780    (set_attr "mode" "V2DF")])
22781
22782 (define_insn "sse2_maskmovdqu"
22783   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22784         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22785                        (match_operand:V16QI 2 "register_operand" "x")]
22786                       UNSPEC_MASKMOV))]
22787   "TARGET_SSE2"
22788   ;; @@@ check ordering of operands in intel/nonintel syntax
22789   "maskmovdqu\t{%2, %1|%1, %2}"
22790   [(set_attr "type" "ssecvt")
22791    (set_attr "mode" "TI")])
22792
22793 (define_insn "sse2_maskmovdqu_rex64"
22794   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22795         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22796                        (match_operand:V16QI 2 "register_operand" "x")]
22797                       UNSPEC_MASKMOV))]
22798   "TARGET_SSE2"
22799   ;; @@@ check ordering of operands in intel/nonintel syntax
22800   "maskmovdqu\t{%2, %1|%1, %2}"
22801   [(set_attr "type" "ssecvt")
22802    (set_attr "mode" "TI")])
22803
22804 (define_insn "sse2_movntv2df"
22805   [(set (match_operand:V2DF 0 "memory_operand" "=m")
22806         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22807                      UNSPEC_MOVNT))]
22808   "TARGET_SSE2"
22809   "movntpd\t{%1, %0|%0, %1}"
22810   [(set_attr "type" "ssecvt")
22811    (set_attr "mode" "V2DF")])
22812
22813 (define_insn "sse2_movntv2di"
22814   [(set (match_operand:V2DI 0 "memory_operand" "=m")
22815         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22816                      UNSPEC_MOVNT))]
22817   "TARGET_SSE2"
22818   "movntdq\t{%1, %0|%0, %1}"
22819   [(set_attr "type" "ssecvt")
22820    (set_attr "mode" "TI")])
22821
22822 (define_insn "sse2_movntsi"
22823   [(set (match_operand:SI 0 "memory_operand" "=m")
22824         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22825                    UNSPEC_MOVNT))]
22826   "TARGET_SSE2"
22827   "movnti\t{%1, %0|%0, %1}"
22828   [(set_attr "type" "ssecvt")
22829    (set_attr "mode" "V2DF")])
22830
22831 ;; SSE <-> integer/MMX conversions
22832
22833 ;; Conversions between SI and SF
22834
22835 (define_insn "cvtdq2ps"
22836   [(set (match_operand:V4SF 0 "register_operand" "=x")
22837         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22838   "TARGET_SSE2"
22839   "cvtdq2ps\t{%1, %0|%0, %1}"
22840   [(set_attr "type" "ssecvt")
22841    (set_attr "mode" "V2DF")])
22842
22843 (define_insn "cvtps2dq"
22844   [(set (match_operand:V4SI 0 "register_operand" "=x")
22845         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22846   "TARGET_SSE2"
22847   "cvtps2dq\t{%1, %0|%0, %1}"
22848   [(set_attr "type" "ssecvt")
22849    (set_attr "mode" "TI")])
22850
22851 (define_insn "cvttps2dq"
22852   [(set (match_operand:V4SI 0 "register_operand" "=x")
22853         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22854                      UNSPEC_FIX))]
22855   "TARGET_SSE2"
22856   "cvttps2dq\t{%1, %0|%0, %1}"
22857   [(set_attr "type" "ssecvt")
22858    (set_attr "mode" "TI")])
22859
22860 ;; Conversions between SI and DF
22861
22862 (define_insn "cvtdq2pd"
22863   [(set (match_operand:V2DF 0 "register_operand" "=x")
22864         (float:V2DF (vec_select:V2SI
22865                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22866                      (parallel
22867                       [(const_int 0)
22868                        (const_int 1)]))))]
22869   "TARGET_SSE2"
22870   "cvtdq2pd\t{%1, %0|%0, %1}"
22871   [(set_attr "type" "ssecvt")
22872    (set_attr "mode" "V2DF")])
22873
22874 (define_insn "cvtpd2dq"
22875   [(set (match_operand:V4SI 0 "register_operand" "=x")
22876         (vec_concat:V4SI
22877          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22878          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22879   "TARGET_SSE2"
22880   "cvtpd2dq\t{%1, %0|%0, %1}"
22881   [(set_attr "type" "ssecvt")
22882    (set_attr "mode" "TI")])
22883
22884 (define_insn "cvttpd2dq"
22885   [(set (match_operand:V4SI 0 "register_operand" "=x")
22886         (vec_concat:V4SI
22887          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22888                       UNSPEC_FIX)
22889          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22890   "TARGET_SSE2"
22891   "cvttpd2dq\t{%1, %0|%0, %1}"
22892   [(set_attr "type" "ssecvt")
22893    (set_attr "mode" "TI")])
22894
22895 (define_insn "cvtpd2pi"
22896   [(set (match_operand:V2SI 0 "register_operand" "=y")
22897         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22898   "TARGET_SSE2"
22899   "cvtpd2pi\t{%1, %0|%0, %1}"
22900   [(set_attr "type" "ssecvt")
22901    (set_attr "mode" "TI")])
22902
22903 (define_insn "cvttpd2pi"
22904   [(set (match_operand:V2SI 0 "register_operand" "=y")
22905         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22906                      UNSPEC_FIX))]
22907   "TARGET_SSE2"
22908   "cvttpd2pi\t{%1, %0|%0, %1}"
22909   [(set_attr "type" "ssecvt")
22910    (set_attr "mode" "TI")])
22911
22912 (define_insn "cvtpi2pd"
22913   [(set (match_operand:V2DF 0 "register_operand" "=x")
22914         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22915   "TARGET_SSE2"
22916   "cvtpi2pd\t{%1, %0|%0, %1}"
22917   [(set_attr "type" "ssecvt")
22918    (set_attr "mode" "TI")])
22919
22920 ;; Conversions between SI and DF
22921
22922 (define_insn "cvtsd2si"
22923   [(set (match_operand:SI 0 "register_operand" "=r,r")
22924         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22925                                (parallel [(const_int 0)]))))]
22926   "TARGET_SSE2"
22927   "cvtsd2si\t{%1, %0|%0, %1}"
22928   [(set_attr "type" "sseicvt")
22929    (set_attr "athlon_decode" "double,vector")
22930    (set_attr "mode" "SI")])
22931
22932 (define_insn "cvtsd2siq"
22933   [(set (match_operand:DI 0 "register_operand" "=r,r")
22934         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22935                                (parallel [(const_int 0)]))))]
22936   "TARGET_SSE2 && TARGET_64BIT"
22937   "cvtsd2siq\t{%1, %0|%0, %1}"
22938   [(set_attr "type" "sseicvt")
22939    (set_attr "athlon_decode" "double,vector")
22940    (set_attr "mode" "DI")])
22941
22942 (define_insn "cvttsd2si"
22943   [(set (match_operand:SI 0 "register_operand" "=r,r")
22944         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22945                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22946   "TARGET_SSE2"
22947   "cvttsd2si\t{%1, %0|%0, %1}"
22948   [(set_attr "type" "sseicvt")
22949    (set_attr "mode" "SI")
22950    (set_attr "athlon_decode" "double,vector")])
22951
22952 (define_insn "cvttsd2siq"
22953   [(set (match_operand:DI 0 "register_operand" "=r,r")
22954         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22955                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22956   "TARGET_SSE2 && TARGET_64BIT"
22957   "cvttsd2siq\t{%1, %0|%0, %1}"
22958   [(set_attr "type" "sseicvt")
22959    (set_attr "mode" "DI")
22960    (set_attr "athlon_decode" "double,vector")])
22961
22962 (define_insn "cvtsi2sd"
22963   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22964         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22965                         (vec_duplicate:V2DF
22966                           (float:DF
22967                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22968                         (const_int 2)))]
22969   "TARGET_SSE2"
22970   "cvtsi2sd\t{%2, %0|%0, %2}"
22971   [(set_attr "type" "sseicvt")
22972    (set_attr "mode" "DF")
22973    (set_attr "athlon_decode" "double,direct")])
22974
22975 (define_insn "cvtsi2sdq"
22976   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22977         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22978                         (vec_duplicate:V2DF
22979                           (float:DF
22980                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22981                         (const_int 2)))]
22982   "TARGET_SSE2 && TARGET_64BIT"
22983   "cvtsi2sdq\t{%2, %0|%0, %2}"
22984   [(set_attr "type" "sseicvt")
22985    (set_attr "mode" "DF")
22986    (set_attr "athlon_decode" "double,direct")])
22987
22988 ;; Conversions between SF and DF
22989
22990 (define_insn "cvtsd2ss"
22991   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22992         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22993                         (vec_duplicate:V4SF
22994                           (float_truncate:V2SF
22995                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22996                         (const_int 14)))]
22997   "TARGET_SSE2"
22998   "cvtsd2ss\t{%2, %0|%0, %2}"
22999   [(set_attr "type" "ssecvt")
23000    (set_attr "athlon_decode" "vector,double")
23001    (set_attr "mode" "SF")])
23002
23003 (define_insn "cvtss2sd"
23004   [(set (match_operand:V2DF 0 "register_operand" "=x")
23005         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
23006                         (float_extend:V2DF
23007                           (vec_select:V2SF
23008                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
23009                             (parallel [(const_int 0)
23010                                        (const_int 1)])))
23011                         (const_int 2)))]
23012   "TARGET_SSE2"
23013   "cvtss2sd\t{%2, %0|%0, %2}"
23014   [(set_attr "type" "ssecvt")
23015    (set_attr "mode" "DF")])
23016
23017 (define_insn "cvtpd2ps"
23018   [(set (match_operand:V4SF 0 "register_operand" "=x")
23019         (subreg:V4SF
23020           (vec_concat:V4SI
23021             (subreg:V2SI (float_truncate:V2SF
23022                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
23023             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
23024   "TARGET_SSE2"
23025   "cvtpd2ps\t{%1, %0|%0, %1}"
23026   [(set_attr "type" "ssecvt")
23027    (set_attr "mode" "V4SF")])
23028
23029 (define_insn "cvtps2pd"
23030   [(set (match_operand:V2DF 0 "register_operand" "=x")
23031         (float_extend:V2DF
23032           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
23033                            (parallel [(const_int 0)
23034                                       (const_int 1)]))))]
23035   "TARGET_SSE2"
23036   "cvtps2pd\t{%1, %0|%0, %1}"
23037   [(set_attr "type" "ssecvt")
23038    (set_attr "mode" "V2DF")])
23039
23040 ;; SSE2 variants of MMX insns
23041
23042 ;; MMX arithmetic
23043
23044 (define_insn "addv16qi3"
23045   [(set (match_operand:V16QI 0 "register_operand" "=x")
23046         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23047                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23048   "TARGET_SSE2"
23049   "paddb\t{%2, %0|%0, %2}"
23050   [(set_attr "type" "sseiadd")
23051    (set_attr "mode" "TI")])
23052
23053 (define_insn "addv8hi3"
23054   [(set (match_operand:V8HI 0 "register_operand" "=x")
23055         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23056                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23057   "TARGET_SSE2"
23058   "paddw\t{%2, %0|%0, %2}"
23059   [(set_attr "type" "sseiadd")
23060    (set_attr "mode" "TI")])
23061
23062 (define_insn "addv4si3"
23063   [(set (match_operand:V4SI 0 "register_operand" "=x")
23064         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
23065                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23066   "TARGET_SSE2"
23067   "paddd\t{%2, %0|%0, %2}"
23068   [(set_attr "type" "sseiadd")
23069    (set_attr "mode" "TI")])
23070
23071 (define_insn "addv2di3"
23072   [(set (match_operand:V2DI 0 "register_operand" "=x")
23073         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
23074                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23075   "TARGET_SSE2"
23076   "paddq\t{%2, %0|%0, %2}"
23077   [(set_attr "type" "sseiadd")
23078    (set_attr "mode" "TI")])
23079
23080 (define_insn "ssaddv16qi3"
23081   [(set (match_operand:V16QI 0 "register_operand" "=x")
23082         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23083                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23084   "TARGET_SSE2"
23085   "paddsb\t{%2, %0|%0, %2}"
23086   [(set_attr "type" "sseiadd")
23087    (set_attr "mode" "TI")])
23088
23089 (define_insn "ssaddv8hi3"
23090   [(set (match_operand:V8HI 0 "register_operand" "=x")
23091         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23092                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23093   "TARGET_SSE2"
23094   "paddsw\t{%2, %0|%0, %2}"
23095   [(set_attr "type" "sseiadd")
23096    (set_attr "mode" "TI")])
23097
23098 (define_insn "usaddv16qi3"
23099   [(set (match_operand:V16QI 0 "register_operand" "=x")
23100         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23101                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23102   "TARGET_SSE2"
23103   "paddusb\t{%2, %0|%0, %2}"
23104   [(set_attr "type" "sseiadd")
23105    (set_attr "mode" "TI")])
23106
23107 (define_insn "usaddv8hi3"
23108   [(set (match_operand:V8HI 0 "register_operand" "=x")
23109         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23110                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23111   "TARGET_SSE2"
23112   "paddusw\t{%2, %0|%0, %2}"
23113   [(set_attr "type" "sseiadd")
23114    (set_attr "mode" "TI")])
23115
23116 (define_insn "subv16qi3"
23117   [(set (match_operand:V16QI 0 "register_operand" "=x")
23118         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23119                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23120   "TARGET_SSE2"
23121   "psubb\t{%2, %0|%0, %2}"
23122   [(set_attr "type" "sseiadd")
23123    (set_attr "mode" "TI")])
23124
23125 (define_insn "subv8hi3"
23126   [(set (match_operand:V8HI 0 "register_operand" "=x")
23127         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23128                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23129   "TARGET_SSE2"
23130   "psubw\t{%2, %0|%0, %2}"
23131   [(set_attr "type" "sseiadd")
23132    (set_attr "mode" "TI")])
23133
23134 (define_insn "subv4si3"
23135   [(set (match_operand:V4SI 0 "register_operand" "=x")
23136         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
23137                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23138   "TARGET_SSE2"
23139   "psubd\t{%2, %0|%0, %2}"
23140   [(set_attr "type" "sseiadd")
23141    (set_attr "mode" "TI")])
23142
23143 (define_insn "subv2di3"
23144   [(set (match_operand:V2DI 0 "register_operand" "=x")
23145         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
23146                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23147   "TARGET_SSE2"
23148   "psubq\t{%2, %0|%0, %2}"
23149   [(set_attr "type" "sseiadd")
23150    (set_attr "mode" "TI")])
23151
23152 (define_insn "sssubv16qi3"
23153   [(set (match_operand:V16QI 0 "register_operand" "=x")
23154         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23155                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23156   "TARGET_SSE2"
23157   "psubsb\t{%2, %0|%0, %2}"
23158   [(set_attr "type" "sseiadd")
23159    (set_attr "mode" "TI")])
23160
23161 (define_insn "sssubv8hi3"
23162   [(set (match_operand:V8HI 0 "register_operand" "=x")
23163         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23164                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23165   "TARGET_SSE2"
23166   "psubsw\t{%2, %0|%0, %2}"
23167   [(set_attr "type" "sseiadd")
23168    (set_attr "mode" "TI")])
23169
23170 (define_insn "ussubv16qi3"
23171   [(set (match_operand:V16QI 0 "register_operand" "=x")
23172         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23173                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23174   "TARGET_SSE2"
23175   "psubusb\t{%2, %0|%0, %2}"
23176   [(set_attr "type" "sseiadd")
23177    (set_attr "mode" "TI")])
23178
23179 (define_insn "ussubv8hi3"
23180   [(set (match_operand:V8HI 0 "register_operand" "=x")
23181         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23182                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23183   "TARGET_SSE2"
23184   "psubusw\t{%2, %0|%0, %2}"
23185   [(set_attr "type" "sseiadd")
23186    (set_attr "mode" "TI")])
23187
23188 (define_insn "mulv8hi3"
23189   [(set (match_operand:V8HI 0 "register_operand" "=x")
23190         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
23191                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23192   "TARGET_SSE2"
23193   "pmullw\t{%2, %0|%0, %2}"
23194   [(set_attr "type" "sseimul")
23195    (set_attr "mode" "TI")])
23196
23197 (define_insn "smulv8hi3_highpart"
23198   [(set (match_operand:V8HI 0 "register_operand" "=x")
23199         (truncate:V8HI
23200          (lshiftrt:V8SI
23201           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23202                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23203           (const_int 16))))]
23204   "TARGET_SSE2"
23205   "pmulhw\t{%2, %0|%0, %2}"
23206   [(set_attr "type" "sseimul")
23207    (set_attr "mode" "TI")])
23208
23209 (define_insn "umulv8hi3_highpart"
23210   [(set (match_operand:V8HI 0 "register_operand" "=x")
23211         (truncate:V8HI
23212          (lshiftrt:V8SI
23213           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23214                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23215           (const_int 16))))]
23216   "TARGET_SSE2"
23217   "pmulhuw\t{%2, %0|%0, %2}"
23218   [(set_attr "type" "sseimul")
23219    (set_attr "mode" "TI")])
23220
23221 (define_insn "sse2_umulsidi3"
23222   [(set (match_operand:DI 0 "register_operand" "=y")
23223         (mult:DI (zero_extend:DI (vec_select:SI
23224                                   (match_operand:V2SI 1 "register_operand" "0")
23225                                   (parallel [(const_int 0)])))
23226                  (zero_extend:DI (vec_select:SI
23227                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
23228                                   (parallel [(const_int 0)])))))]
23229   "TARGET_SSE2"
23230   "pmuludq\t{%2, %0|%0, %2}"
23231   [(set_attr "type" "mmxmul")
23232    (set_attr "mode" "DI")])
23233
23234 (define_insn "sse2_umulv2siv2di3"
23235   [(set (match_operand:V2DI 0 "register_operand" "=x")
23236         (mult:V2DI (zero_extend:V2DI
23237                      (vec_select:V2SI
23238                        (match_operand:V4SI 1 "register_operand" "0")
23239                        (parallel [(const_int 0) (const_int 2)])))
23240                    (zero_extend:V2DI
23241                      (vec_select:V2SI
23242                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
23243                        (parallel [(const_int 0) (const_int 2)])))))]
23244   "TARGET_SSE2"
23245   "pmuludq\t{%2, %0|%0, %2}"
23246   [(set_attr "type" "sseimul")
23247    (set_attr "mode" "TI")])
23248
23249 (define_insn "sse2_pmaddwd"
23250   [(set (match_operand:V4SI 0 "register_operand" "=x")
23251         (plus:V4SI
23252          (mult:V4SI
23253           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23254                                              (parallel [(const_int 0)
23255                                                         (const_int 2)
23256                                                         (const_int 4)
23257                                                         (const_int 6)])))
23258           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23259                                              (parallel [(const_int 0)
23260                                                         (const_int 2)
23261                                                         (const_int 4)
23262                                                         (const_int 6)]))))
23263          (mult:V4SI
23264           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23265                                              (parallel [(const_int 1)
23266                                                         (const_int 3)
23267                                                         (const_int 5)
23268                                                         (const_int 7)])))
23269           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23270                                              (parallel [(const_int 1)
23271                                                         (const_int 3)
23272                                                         (const_int 5)
23273                                                         (const_int 7)]))))))]
23274   "TARGET_SSE2"
23275   "pmaddwd\t{%2, %0|%0, %2}"
23276   [(set_attr "type" "sseiadd")
23277    (set_attr "mode" "TI")])
23278
23279 ;; Same as pxor, but don't show input operands so that we don't think
23280 ;; they are live.
23281 (define_insn "sse2_clrti"
23282   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23283   "TARGET_SSE2"
23284 {
23285   if (get_attr_mode (insn) == MODE_TI)
23286     return "pxor\t%0, %0";
23287   else
23288     return "xorps\t%0, %0";
23289 }
23290   [(set_attr "type" "ssemov")
23291    (set_attr "memory" "none")
23292    (set (attr "mode")
23293               (if_then_else
23294                 (ne (symbol_ref "optimize_size")
23295                     (const_int 0))
23296                 (const_string "V4SF")
23297                 (const_string "TI")))])
23298
23299 ;; MMX unsigned averages/sum of absolute differences
23300
23301 (define_insn "sse2_uavgv16qi3"
23302   [(set (match_operand:V16QI 0 "register_operand" "=x")
23303         (ashiftrt:V16QI
23304          (plus:V16QI (plus:V16QI
23305                      (match_operand:V16QI 1 "register_operand" "0")
23306                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23307                      (const_vector:V16QI [(const_int 1) (const_int 1)
23308                                           (const_int 1) (const_int 1)
23309                                           (const_int 1) (const_int 1)
23310                                           (const_int 1) (const_int 1)
23311                                           (const_int 1) (const_int 1)
23312                                           (const_int 1) (const_int 1)
23313                                           (const_int 1) (const_int 1)
23314                                           (const_int 1) (const_int 1)]))
23315          (const_int 1)))]
23316   "TARGET_SSE2"
23317   "pavgb\t{%2, %0|%0, %2}"
23318   [(set_attr "type" "sseiadd")
23319    (set_attr "mode" "TI")])
23320
23321 (define_insn "sse2_uavgv8hi3"
23322   [(set (match_operand:V8HI 0 "register_operand" "=x")
23323         (ashiftrt:V8HI
23324          (plus:V8HI (plus:V8HI
23325                      (match_operand:V8HI 1 "register_operand" "0")
23326                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23327                     (const_vector:V8HI [(const_int 1) (const_int 1)
23328                                         (const_int 1) (const_int 1)
23329                                         (const_int 1) (const_int 1)
23330                                         (const_int 1) (const_int 1)]))
23331          (const_int 1)))]
23332   "TARGET_SSE2"
23333   "pavgw\t{%2, %0|%0, %2}"
23334   [(set_attr "type" "sseiadd")
23335    (set_attr "mode" "TI")])
23336
23337 ;; @@@ this isn't the right representation.
23338 (define_insn "sse2_psadbw"
23339   [(set (match_operand:V2DI 0 "register_operand" "=x")
23340         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23341                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23342                      UNSPEC_PSADBW))]
23343   "TARGET_SSE2"
23344   "psadbw\t{%2, %0|%0, %2}"
23345   [(set_attr "type" "sseiadd")
23346    (set_attr "mode" "TI")])
23347
23348
23349 ;; MMX insert/extract/shuffle
23350
23351 (define_insn "sse2_pinsrw"
23352   [(set (match_operand:V8HI 0 "register_operand" "=x")
23353         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
23354                         (vec_duplicate:V8HI
23355                          (truncate:HI
23356                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
23357                         (match_operand:SI 3 "const_0_to_255_operand" "N")))]
23358   "TARGET_SSE2"
23359   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
23360   [(set_attr "type" "ssecvt")
23361    (set_attr "mode" "TI")])
23362
23363 (define_insn "sse2_pextrw"
23364   [(set (match_operand:SI 0 "register_operand" "=r")
23365         (zero_extend:SI
23366           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23367                          (parallel
23368                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23369   "TARGET_SSE2"
23370   "pextrw\t{%2, %1, %0|%0, %1, %2}"
23371   [(set_attr "type" "ssecvt")
23372    (set_attr "mode" "TI")])
23373
23374 (define_insn "sse2_pshufd"
23375   [(set (match_operand:V4SI 0 "register_operand" "=x")
23376         (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23377                       (match_operand:SI 2 "immediate_operand" "i")]
23378                      UNSPEC_SHUFFLE))]
23379   "TARGET_SSE2"
23380   "pshufd\t{%2, %1, %0|%0, %1, %2}"
23381   [(set_attr "type" "ssecvt")
23382    (set_attr "mode" "TI")])
23383
23384 (define_insn "sse2_pshuflw"
23385   [(set (match_operand:V8HI 0 "register_operand" "=x")
23386         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23387                       (match_operand:SI 2 "immediate_operand" "i")]
23388                      UNSPEC_PSHUFLW))]
23389   "TARGET_SSE2"
23390   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23391   [(set_attr "type" "ssecvt")
23392    (set_attr "mode" "TI")])
23393
23394 (define_insn "sse2_pshufhw"
23395   [(set (match_operand:V8HI 0 "register_operand" "=x")
23396         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23397                       (match_operand:SI 2 "immediate_operand" "i")]
23398                      UNSPEC_PSHUFHW))]
23399   "TARGET_SSE2"
23400   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23401   [(set_attr "type" "ssecvt")
23402    (set_attr "mode" "TI")])
23403
23404 ;; MMX mask-generating comparisons
23405
23406 (define_insn "eqv16qi3"
23407   [(set (match_operand:V16QI 0 "register_operand" "=x")
23408         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23409                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23410   "TARGET_SSE2"
23411   "pcmpeqb\t{%2, %0|%0, %2}"
23412   [(set_attr "type" "ssecmp")
23413    (set_attr "mode" "TI")])
23414
23415 (define_insn "eqv8hi3"
23416   [(set (match_operand:V8HI 0 "register_operand" "=x")
23417         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23418                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23419   "TARGET_SSE2"
23420   "pcmpeqw\t{%2, %0|%0, %2}"
23421   [(set_attr "type" "ssecmp")
23422    (set_attr "mode" "TI")])
23423
23424 (define_insn "eqv4si3"
23425   [(set (match_operand:V4SI 0 "register_operand" "=x")
23426         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23427                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23428   "TARGET_SSE2"
23429   "pcmpeqd\t{%2, %0|%0, %2}"
23430   [(set_attr "type" "ssecmp")
23431    (set_attr "mode" "TI")])
23432
23433 (define_insn "gtv16qi3"
23434   [(set (match_operand:V16QI 0 "register_operand" "=x")
23435         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23436                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23437   "TARGET_SSE2"
23438   "pcmpgtb\t{%2, %0|%0, %2}"
23439   [(set_attr "type" "ssecmp")
23440    (set_attr "mode" "TI")])
23441
23442 (define_insn "gtv8hi3"
23443   [(set (match_operand:V8HI 0 "register_operand" "=x")
23444         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23445                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23446   "TARGET_SSE2"
23447   "pcmpgtw\t{%2, %0|%0, %2}"
23448   [(set_attr "type" "ssecmp")
23449    (set_attr "mode" "TI")])
23450
23451 (define_insn "gtv4si3"
23452   [(set (match_operand:V4SI 0 "register_operand" "=x")
23453         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23454                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23455   "TARGET_SSE2"
23456   "pcmpgtd\t{%2, %0|%0, %2}"
23457   [(set_attr "type" "ssecmp")
23458    (set_attr "mode" "TI")])
23459
23460
23461 ;; MMX max/min insns
23462
23463 (define_insn "umaxv16qi3"
23464   [(set (match_operand:V16QI 0 "register_operand" "=x")
23465         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23466                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23467   "TARGET_SSE2"
23468   "pmaxub\t{%2, %0|%0, %2}"
23469   [(set_attr "type" "sseiadd")
23470    (set_attr "mode" "TI")])
23471
23472 (define_insn "smaxv8hi3"
23473   [(set (match_operand:V8HI 0 "register_operand" "=x")
23474         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23475                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23476   "TARGET_SSE2"
23477   "pmaxsw\t{%2, %0|%0, %2}"
23478   [(set_attr "type" "sseiadd")
23479    (set_attr "mode" "TI")])
23480
23481 (define_insn "uminv16qi3"
23482   [(set (match_operand:V16QI 0 "register_operand" "=x")
23483         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23484                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23485   "TARGET_SSE2"
23486   "pminub\t{%2, %0|%0, %2}"
23487   [(set_attr "type" "sseiadd")
23488    (set_attr "mode" "TI")])
23489
23490 (define_insn "sminv8hi3"
23491   [(set (match_operand:V8HI 0 "register_operand" "=x")
23492         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23493                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23494   "TARGET_SSE2"
23495   "pminsw\t{%2, %0|%0, %2}"
23496   [(set_attr "type" "sseiadd")
23497    (set_attr "mode" "TI")])
23498
23499
23500 ;; MMX shifts
23501
23502 (define_insn "ashrv8hi3"
23503   [(set (match_operand:V8HI 0 "register_operand" "=x")
23504         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23505                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23506   "TARGET_SSE2"
23507   "psraw\t{%2, %0|%0, %2}"
23508   [(set_attr "type" "sseishft")
23509    (set_attr "mode" "TI")])
23510
23511 (define_insn "ashrv4si3"
23512   [(set (match_operand:V4SI 0 "register_operand" "=x")
23513         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23514                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23515   "TARGET_SSE2"
23516   "psrad\t{%2, %0|%0, %2}"
23517   [(set_attr "type" "sseishft")
23518    (set_attr "mode" "TI")])
23519
23520 (define_insn "lshrv8hi3"
23521   [(set (match_operand:V8HI 0 "register_operand" "=x")
23522         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23523                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23524   "TARGET_SSE2"
23525   "psrlw\t{%2, %0|%0, %2}"
23526   [(set_attr "type" "sseishft")
23527    (set_attr "mode" "TI")])
23528
23529 (define_insn "lshrv4si3"
23530   [(set (match_operand:V4SI 0 "register_operand" "=x")
23531         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23532                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23533   "TARGET_SSE2"
23534   "psrld\t{%2, %0|%0, %2}"
23535   [(set_attr "type" "sseishft")
23536    (set_attr "mode" "TI")])
23537
23538 (define_insn "lshrv2di3"
23539   [(set (match_operand:V2DI 0 "register_operand" "=x")
23540         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23541                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23542   "TARGET_SSE2"
23543   "psrlq\t{%2, %0|%0, %2}"
23544   [(set_attr "type" "sseishft")
23545    (set_attr "mode" "TI")])
23546
23547 (define_insn "ashlv8hi3"
23548   [(set (match_operand:V8HI 0 "register_operand" "=x")
23549         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23550                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23551   "TARGET_SSE2"
23552   "psllw\t{%2, %0|%0, %2}"
23553   [(set_attr "type" "sseishft")
23554    (set_attr "mode" "TI")])
23555
23556 (define_insn "ashlv4si3"
23557   [(set (match_operand:V4SI 0 "register_operand" "=x")
23558         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23559                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23560   "TARGET_SSE2"
23561   "pslld\t{%2, %0|%0, %2}"
23562   [(set_attr "type" "sseishft")
23563    (set_attr "mode" "TI")])
23564
23565 (define_insn "ashlv2di3"
23566   [(set (match_operand:V2DI 0 "register_operand" "=x")
23567         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23568                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23569   "TARGET_SSE2"
23570   "psllq\t{%2, %0|%0, %2}"
23571   [(set_attr "type" "sseishft")
23572    (set_attr "mode" "TI")])
23573
23574 (define_insn "ashrv8hi3_ti"
23575   [(set (match_operand:V8HI 0 "register_operand" "=x")
23576         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23577                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23578   "TARGET_SSE2"
23579   "psraw\t{%2, %0|%0, %2}"
23580   [(set_attr "type" "sseishft")
23581    (set_attr "mode" "TI")])
23582
23583 (define_insn "ashrv4si3_ti"
23584   [(set (match_operand:V4SI 0 "register_operand" "=x")
23585         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23586                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23587   "TARGET_SSE2"
23588   "psrad\t{%2, %0|%0, %2}"
23589   [(set_attr "type" "sseishft")
23590    (set_attr "mode" "TI")])
23591
23592 (define_insn "lshrv8hi3_ti"
23593   [(set (match_operand:V8HI 0 "register_operand" "=x")
23594         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23595                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23596   "TARGET_SSE2"
23597   "psrlw\t{%2, %0|%0, %2}"
23598   [(set_attr "type" "sseishft")
23599    (set_attr "mode" "TI")])
23600
23601 (define_insn "lshrv4si3_ti"
23602   [(set (match_operand:V4SI 0 "register_operand" "=x")
23603         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23604                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23605   "TARGET_SSE2"
23606   "psrld\t{%2, %0|%0, %2}"
23607   [(set_attr "type" "sseishft")
23608    (set_attr "mode" "TI")])
23609
23610 (define_insn "lshrv2di3_ti"
23611   [(set (match_operand:V2DI 0 "register_operand" "=x")
23612         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23613                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23614   "TARGET_SSE2"
23615   "psrlq\t{%2, %0|%0, %2}"
23616   [(set_attr "type" "sseishft")
23617    (set_attr "mode" "TI")])
23618
23619 (define_insn "ashlv8hi3_ti"
23620   [(set (match_operand:V8HI 0 "register_operand" "=x")
23621         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23622                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23623   "TARGET_SSE2"
23624   "psllw\t{%2, %0|%0, %2}"
23625   [(set_attr "type" "sseishft")
23626    (set_attr "mode" "TI")])
23627
23628 (define_insn "ashlv4si3_ti"
23629   [(set (match_operand:V4SI 0 "register_operand" "=x")
23630         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23631                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23632   "TARGET_SSE2"
23633   "pslld\t{%2, %0|%0, %2}"
23634   [(set_attr "type" "sseishft")
23635    (set_attr "mode" "TI")])
23636
23637 (define_insn "ashlv2di3_ti"
23638   [(set (match_operand:V2DI 0 "register_operand" "=x")
23639         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23640                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23641   "TARGET_SSE2"
23642   "psllq\t{%2, %0|%0, %2}"
23643   [(set_attr "type" "sseishft")
23644    (set_attr "mode" "TI")])
23645
23646 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
23647 ;; we wouldn't need here it since we never generate TImode arithmetic.
23648
23649 ;; There has to be some kind of prize for the weirdest new instruction...
23650 (define_insn "sse2_ashlti3"
23651   [(set (match_operand:TI 0 "register_operand" "=x")
23652         (unspec:TI
23653          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23654                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23655                                (const_int 8)))] UNSPEC_NOP))]
23656   "TARGET_SSE2"
23657   "pslldq\t{%2, %0|%0, %2}"
23658   [(set_attr "type" "sseishft")
23659    (set_attr "mode" "TI")])
23660
23661 (define_insn "sse2_lshrti3"
23662   [(set (match_operand:TI 0 "register_operand" "=x")
23663         (unspec:TI
23664          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23665                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23666                                 (const_int 8)))] UNSPEC_NOP))]
23667   "TARGET_SSE2"
23668   "psrldq\t{%2, %0|%0, %2}"
23669   [(set_attr "type" "sseishft")
23670    (set_attr "mode" "TI")])
23671
23672 ;; SSE unpack
23673
23674 (define_insn "sse2_unpckhpd"
23675   [(set (match_operand:V2DF 0 "register_operand" "=x")
23676         (vec_concat:V2DF
23677          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23678                         (parallel [(const_int 1)]))
23679          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23680                         (parallel [(const_int 1)]))))]
23681   "TARGET_SSE2"
23682   "unpckhpd\t{%2, %0|%0, %2}"
23683   [(set_attr "type" "ssecvt")
23684    (set_attr "mode" "V2DF")])
23685
23686 (define_insn "sse2_unpcklpd"
23687   [(set (match_operand:V2DF 0 "register_operand" "=x")
23688         (vec_concat:V2DF
23689          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23690                         (parallel [(const_int 0)]))
23691          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23692                         (parallel [(const_int 0)]))))]
23693   "TARGET_SSE2"
23694   "unpcklpd\t{%2, %0|%0, %2}"
23695   [(set_attr "type" "ssecvt")
23696    (set_attr "mode" "V2DF")])
23697
23698 ;; MMX pack/unpack insns.
23699
23700 (define_insn "sse2_packsswb"
23701   [(set (match_operand:V16QI 0 "register_operand" "=x")
23702         (vec_concat:V16QI
23703          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23704          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23705   "TARGET_SSE2"
23706   "packsswb\t{%2, %0|%0, %2}"
23707   [(set_attr "type" "ssecvt")
23708    (set_attr "mode" "TI")])
23709
23710 (define_insn "sse2_packssdw"
23711   [(set (match_operand:V8HI 0 "register_operand" "=x")
23712         (vec_concat:V8HI
23713          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23714          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23715   "TARGET_SSE2"
23716   "packssdw\t{%2, %0|%0, %2}"
23717   [(set_attr "type" "ssecvt")
23718    (set_attr "mode" "TI")])
23719
23720 (define_insn "sse2_packuswb"
23721   [(set (match_operand:V16QI 0 "register_operand" "=x")
23722         (vec_concat:V16QI
23723          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23724          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23725   "TARGET_SSE2"
23726   "packuswb\t{%2, %0|%0, %2}"
23727   [(set_attr "type" "ssecvt")
23728    (set_attr "mode" "TI")])
23729
23730 (define_insn "sse2_punpckhbw"
23731   [(set (match_operand:V16QI 0 "register_operand" "=x")
23732         (vec_merge:V16QI
23733          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23734                            (parallel [(const_int 8) (const_int 0)
23735                                       (const_int 9) (const_int 1)
23736                                       (const_int 10) (const_int 2)
23737                                       (const_int 11) (const_int 3)
23738                                       (const_int 12) (const_int 4)
23739                                       (const_int 13) (const_int 5)
23740                                       (const_int 14) (const_int 6)
23741                                       (const_int 15) (const_int 7)]))
23742          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23743                            (parallel [(const_int 0) (const_int 8)
23744                                       (const_int 1) (const_int 9)
23745                                       (const_int 2) (const_int 10)
23746                                       (const_int 3) (const_int 11)
23747                                       (const_int 4) (const_int 12)
23748                                       (const_int 5) (const_int 13)
23749                                       (const_int 6) (const_int 14)
23750                                       (const_int 7) (const_int 15)]))
23751          (const_int 21845)))]
23752   "TARGET_SSE2"
23753   "punpckhbw\t{%2, %0|%0, %2}"
23754   [(set_attr "type" "ssecvt")
23755    (set_attr "mode" "TI")])
23756
23757 (define_insn "sse2_punpckhwd"
23758   [(set (match_operand:V8HI 0 "register_operand" "=x")
23759         (vec_merge:V8HI
23760          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23761                           (parallel [(const_int 4) (const_int 0)
23762                                      (const_int 5) (const_int 1)
23763                                      (const_int 6) (const_int 2)
23764                                      (const_int 7) (const_int 3)]))
23765          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23766                           (parallel [(const_int 0) (const_int 4)
23767                                      (const_int 1) (const_int 5)
23768                                      (const_int 2) (const_int 6)
23769                                      (const_int 3) (const_int 7)]))
23770          (const_int 85)))]
23771   "TARGET_SSE2"
23772   "punpckhwd\t{%2, %0|%0, %2}"
23773   [(set_attr "type" "ssecvt")
23774    (set_attr "mode" "TI")])
23775
23776 (define_insn "sse2_punpckhdq"
23777   [(set (match_operand:V4SI 0 "register_operand" "=x")
23778         (vec_merge:V4SI
23779          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23780                           (parallel [(const_int 2) (const_int 0)
23781                                      (const_int 3) (const_int 1)]))
23782          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23783                           (parallel [(const_int 0) (const_int 2)
23784                                      (const_int 1) (const_int 3)]))
23785          (const_int 5)))]
23786   "TARGET_SSE2"
23787   "punpckhdq\t{%2, %0|%0, %2}"
23788   [(set_attr "type" "ssecvt")
23789    (set_attr "mode" "TI")])
23790
23791 (define_insn "sse2_punpcklbw"
23792   [(set (match_operand:V16QI 0 "register_operand" "=x")
23793         (vec_merge:V16QI
23794          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23795                            (parallel [(const_int 0) (const_int 8)
23796                                       (const_int 1) (const_int 9)
23797                                       (const_int 2) (const_int 10)
23798                                       (const_int 3) (const_int 11)
23799                                       (const_int 4) (const_int 12)
23800                                       (const_int 5) (const_int 13)
23801                                       (const_int 6) (const_int 14)
23802                                       (const_int 7) (const_int 15)]))
23803          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23804                            (parallel [(const_int 8) (const_int 0)
23805                                       (const_int 9) (const_int 1)
23806                                       (const_int 10) (const_int 2)
23807                                       (const_int 11) (const_int 3)
23808                                       (const_int 12) (const_int 4)
23809                                       (const_int 13) (const_int 5)
23810                                       (const_int 14) (const_int 6)
23811                                       (const_int 15) (const_int 7)]))
23812          (const_int 21845)))]
23813   "TARGET_SSE2"
23814   "punpcklbw\t{%2, %0|%0, %2}"
23815   [(set_attr "type" "ssecvt")
23816    (set_attr "mode" "TI")])
23817
23818 (define_insn "sse2_punpcklwd"
23819   [(set (match_operand:V8HI 0 "register_operand" "=x")
23820         (vec_merge:V8HI
23821          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23822                           (parallel [(const_int 0) (const_int 4)
23823                                      (const_int 1) (const_int 5)
23824                                      (const_int 2) (const_int 6)
23825                                      (const_int 3) (const_int 7)]))
23826          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23827                           (parallel [(const_int 4) (const_int 0)
23828                                      (const_int 5) (const_int 1)
23829                                      (const_int 6) (const_int 2)
23830                                      (const_int 7) (const_int 3)]))
23831          (const_int 85)))]
23832   "TARGET_SSE2"
23833   "punpcklwd\t{%2, %0|%0, %2}"
23834   [(set_attr "type" "ssecvt")
23835    (set_attr "mode" "TI")])
23836
23837 (define_insn "sse2_punpckldq"
23838   [(set (match_operand:V4SI 0 "register_operand" "=x")
23839         (vec_merge:V4SI
23840          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23841                           (parallel [(const_int 0) (const_int 2)
23842                                      (const_int 1) (const_int 3)]))
23843          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23844                           (parallel [(const_int 2) (const_int 0)
23845                                      (const_int 3) (const_int 1)]))
23846          (const_int 5)))]
23847   "TARGET_SSE2"
23848   "punpckldq\t{%2, %0|%0, %2}"
23849   [(set_attr "type" "ssecvt")
23850    (set_attr "mode" "TI")])
23851
23852 (define_insn "sse2_punpcklqdq"
23853   [(set (match_operand:V2DI 0 "register_operand" "=x")
23854         (vec_merge:V2DI
23855          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23856                           (parallel [(const_int 1)
23857                                      (const_int 0)]))
23858          (match_operand:V2DI 1 "register_operand" "0")
23859          (const_int 1)))]
23860   "TARGET_SSE2"
23861   "punpcklqdq\t{%2, %0|%0, %2}"
23862   [(set_attr "type" "ssecvt")
23863    (set_attr "mode" "TI")])
23864
23865 (define_insn "sse2_punpckhqdq"
23866   [(set (match_operand:V2DI 0 "register_operand" "=x")
23867         (vec_merge:V2DI
23868          (match_operand:V2DI 1 "register_operand" "0")
23869          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23870                           (parallel [(const_int 1)
23871                                      (const_int 0)]))
23872          (const_int 1)))]
23873   "TARGET_SSE2"
23874   "punpckhqdq\t{%2, %0|%0, %2}"
23875   [(set_attr "type" "ssecvt")
23876    (set_attr "mode" "TI")])
23877
23878 ;; SSE2 moves
23879
23880 (define_insn "sse2_movapd"
23881   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23882         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23883                      UNSPEC_MOVA))]
23884   "TARGET_SSE2
23885    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23886   "movapd\t{%1, %0|%0, %1}"
23887   [(set_attr "type" "ssemov")
23888    (set_attr "mode" "V2DF")])
23889
23890 (define_insn "sse2_movupd"
23891   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23892         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23893                      UNSPEC_MOVU))]
23894   "TARGET_SSE2
23895    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23896   "movupd\t{%1, %0|%0, %1}"
23897   [(set_attr "type" "ssecvt")
23898    (set_attr "mode" "V2DF")])
23899
23900 (define_insn "sse2_movdqa"
23901   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23902         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23903                        UNSPEC_MOVA))]
23904   "TARGET_SSE2
23905    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23906   "movdqa\t{%1, %0|%0, %1}"
23907   [(set_attr "type" "ssemov")
23908    (set_attr "mode" "TI")])
23909
23910 (define_insn "sse2_movdqu"
23911   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23912         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23913                        UNSPEC_MOVU))]
23914   "TARGET_SSE2
23915    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23916   "movdqu\t{%1, %0|%0, %1}"
23917   [(set_attr "type" "ssecvt")
23918    (set_attr "mode" "TI")])
23919
23920 (define_insn "sse2_movdq2q"
23921   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23922         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23923                        (parallel [(const_int 0)])))]
23924   "TARGET_SSE2 && !TARGET_64BIT"
23925   "@
23926    movq\t{%1, %0|%0, %1}
23927    movdq2q\t{%1, %0|%0, %1}"
23928   [(set_attr "type" "ssecvt")
23929    (set_attr "mode" "TI")])
23930
23931 (define_insn "sse2_movdq2q_rex64"
23932   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23933         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23934                        (parallel [(const_int 0)])))]
23935   "TARGET_SSE2 && TARGET_64BIT"
23936   "@
23937    movq\t{%1, %0|%0, %1}
23938    movdq2q\t{%1, %0|%0, %1}
23939    movd\t{%1, %0|%0, %1}"
23940   [(set_attr "type" "ssecvt")
23941    (set_attr "mode" "TI")])
23942
23943 (define_insn "sse2_movq2dq"
23944   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23945         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23946                          (const_int 0)))]
23947   "TARGET_SSE2 && !TARGET_64BIT"
23948   "@
23949    movq\t{%1, %0|%0, %1}
23950    movq2dq\t{%1, %0|%0, %1}"
23951   [(set_attr "type" "ssecvt,ssemov")
23952    (set_attr "mode" "TI")])
23953
23954 (define_insn "sse2_movq2dq_rex64"
23955   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23956         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23957                          (const_int 0)))]
23958   "TARGET_SSE2 && TARGET_64BIT"
23959   "@
23960    movq\t{%1, %0|%0, %1}
23961    movq2dq\t{%1, %0|%0, %1}
23962    movd\t{%1, %0|%0, %1}"
23963   [(set_attr "type" "ssecvt,ssemov,ssecvt")
23964    (set_attr "mode" "TI")])
23965
23966 (define_insn "sse2_movq"
23967   [(set (match_operand:V2DI 0 "register_operand" "=x")
23968         (vec_concat:V2DI (vec_select:DI
23969                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23970                           (parallel [(const_int 0)]))
23971                          (const_int 0)))]
23972   "TARGET_SSE2"
23973   "movq\t{%1, %0|%0, %1}"
23974   [(set_attr "type" "ssemov")
23975    (set_attr "mode" "TI")])
23976
23977 (define_insn "sse2_loadd"
23978   [(set (match_operand:V4SI 0 "register_operand" "=x")
23979         (vec_merge:V4SI
23980          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23981          (const_vector:V4SI [(const_int 0)
23982                              (const_int 0)
23983                              (const_int 0)
23984                              (const_int 0)])
23985          (const_int 1)))]
23986   "TARGET_SSE2"
23987   "movd\t{%1, %0|%0, %1}"
23988   [(set_attr "type" "ssemov")
23989    (set_attr "mode" "TI")])
23990
23991 (define_insn "sse2_stored"
23992   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23993         (vec_select:SI
23994          (match_operand:V4SI 1 "register_operand" "x")
23995          (parallel [(const_int 0)])))]
23996   "TARGET_SSE2"
23997   "movd\t{%1, %0|%0, %1}"
23998   [(set_attr "type" "ssemov")
23999    (set_attr "mode" "TI")])
24000
24001 (define_insn "sse2_movhpd"
24002   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24003         (vec_merge:V2DF
24004          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
24005          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
24006          (const_int 1)))]
24007   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
24008   "movhpd\t{%2, %0|%0, %2}"
24009   [(set_attr "type" "ssecvt")
24010    (set_attr "mode" "V2DF")])
24011
24012 (define_expand "sse2_loadsd"
24013   [(match_operand:V2DF 0 "register_operand" "")
24014    (match_operand:DF 1 "memory_operand" "")]
24015   "TARGET_SSE2"
24016 {
24017   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
24018                                 CONST0_RTX (V2DFmode)));
24019   DONE;
24020 })
24021
24022 (define_insn "sse2_loadsd_1"
24023   [(set (match_operand:V2DF 0 "register_operand" "=x")
24024         (vec_merge:V2DF
24025          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
24026          (match_operand:V2DF 2 "const0_operand" "X")
24027          (const_int 1)))]
24028   "TARGET_SSE2"
24029   "movsd\t{%1, %0|%0, %1}"
24030   [(set_attr "type" "ssecvt")
24031    (set_attr "mode" "DF")])
24032
24033 (define_insn "sse2_movsd"
24034   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
24035         (vec_merge:V2DF
24036          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
24037          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
24038          (const_int 2)))]
24039   "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
24040   "@movsd\t{%2, %0|%0, %2}
24041     movlpd\t{%2, %0|%0, %2}
24042     movlpd\t{%2, %0|%0, %2}"
24043   [(set_attr "type" "ssecvt")
24044    (set_attr "mode" "DF,V2DF,V2DF")])
24045
24046 (define_insn "sse2_storesd"
24047   [(set (match_operand:DF 0 "memory_operand" "=m")
24048         (vec_select:DF
24049          (match_operand:V2DF 1 "register_operand" "x")
24050          (parallel [(const_int 0)])))]
24051   "TARGET_SSE2"
24052   "movsd\t{%1, %0|%0, %1}"
24053   [(set_attr "type" "ssecvt")
24054    (set_attr "mode" "DF")])
24055
24056 (define_insn "sse2_shufpd"
24057   [(set (match_operand:V2DF 0 "register_operand" "=x")
24058         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24059                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
24060                       (match_operand:SI 3 "immediate_operand" "i")]
24061                      UNSPEC_SHUFFLE))]
24062   "TARGET_SSE2"
24063   ;; @@@ check operand order for intel/nonintel syntax
24064   "shufpd\t{%3, %2, %0|%0, %2, %3}"
24065   [(set_attr "type" "ssecvt")
24066    (set_attr "mode" "V2DF")])
24067
24068 (define_insn "sse2_clflush"
24069   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
24070                     UNSPECV_CLFLUSH)]
24071   "TARGET_SSE2"
24072   "clflush\t%a0"
24073   [(set_attr "type" "sse")
24074    (set_attr "memory" "unknown")])
24075
24076 (define_expand "sse2_mfence"
24077   [(set (match_dup 0)
24078         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24079   "TARGET_SSE2"
24080 {
24081   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24082   MEM_VOLATILE_P (operands[0]) = 1;
24083 })
24084
24085 (define_insn "*mfence_insn"
24086   [(set (match_operand:BLK 0 "" "")
24087         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24088   "TARGET_SSE2"
24089   "mfence"
24090   [(set_attr "type" "sse")
24091    (set_attr "memory" "unknown")])
24092
24093 (define_expand "sse2_lfence"
24094   [(set (match_dup 0)
24095         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24096   "TARGET_SSE2"
24097 {
24098   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24099   MEM_VOLATILE_P (operands[0]) = 1;
24100 })
24101
24102 (define_insn "*lfence_insn"
24103   [(set (match_operand:BLK 0 "" "")
24104         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24105   "TARGET_SSE2"
24106   "lfence"
24107   [(set_attr "type" "sse")
24108    (set_attr "memory" "unknown")])
24109
24110 ;; SSE3
24111
24112 (define_insn "mwait"
24113   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24114                      (match_operand:SI 1 "register_operand" "c")]
24115                     UNSPECV_MWAIT)]
24116   "TARGET_SSE3"
24117   "mwait\t%0, %1"
24118   [(set_attr "length" "3")])
24119
24120 (define_insn "monitor"
24121   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24122                      (match_operand:SI 1 "register_operand" "c")
24123                      (match_operand:SI 2 "register_operand" "d")]
24124                     UNSPECV_MONITOR)]
24125   "TARGET_SSE3"
24126   "monitor\t%0, %1, %2"
24127   [(set_attr "length" "3")])
24128
24129 ;; SSE3 arithmetic
24130
24131 (define_insn "addsubv4sf3"
24132   [(set (match_operand:V4SF 0 "register_operand" "=x")
24133         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24134                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24135                      UNSPEC_ADDSUB))]
24136   "TARGET_SSE3"
24137   "addsubps\t{%2, %0|%0, %2}"
24138   [(set_attr "type" "sseadd")
24139    (set_attr "mode" "V4SF")])
24140
24141 (define_insn "addsubv2df3"
24142   [(set (match_operand:V2DF 0 "register_operand" "=x")
24143         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24144                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24145                      UNSPEC_ADDSUB))]
24146   "TARGET_SSE3"
24147   "addsubpd\t{%2, %0|%0, %2}"
24148   [(set_attr "type" "sseadd")
24149    (set_attr "mode" "V2DF")])
24150
24151 (define_insn "haddv4sf3"
24152   [(set (match_operand:V4SF 0 "register_operand" "=x")
24153         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24154                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24155                      UNSPEC_HADD))]
24156   "TARGET_SSE3"
24157   "haddps\t{%2, %0|%0, %2}"
24158   [(set_attr "type" "sseadd")
24159    (set_attr "mode" "V4SF")])
24160
24161 (define_insn "haddv2df3"
24162   [(set (match_operand:V2DF 0 "register_operand" "=x")
24163         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24164                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24165                      UNSPEC_HADD))]
24166   "TARGET_SSE3"
24167   "haddpd\t{%2, %0|%0, %2}"
24168   [(set_attr "type" "sseadd")
24169    (set_attr "mode" "V2DF")])
24170
24171 (define_insn "hsubv4sf3"
24172   [(set (match_operand:V4SF 0 "register_operand" "=x")
24173         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24174                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24175                      UNSPEC_HSUB))]
24176   "TARGET_SSE3"
24177   "hsubps\t{%2, %0|%0, %2}"
24178   [(set_attr "type" "sseadd")
24179    (set_attr "mode" "V4SF")])
24180
24181 (define_insn "hsubv2df3"
24182   [(set (match_operand:V2DF 0 "register_operand" "=x")
24183         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24184                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24185                      UNSPEC_HSUB))]
24186   "TARGET_SSE3"
24187   "hsubpd\t{%2, %0|%0, %2}"
24188   [(set_attr "type" "sseadd")
24189    (set_attr "mode" "V2DF")])
24190
24191 (define_insn "movshdup"
24192   [(set (match_operand:V4SF 0 "register_operand" "=x")
24193         (unspec:V4SF
24194          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
24195   "TARGET_SSE3"
24196   "movshdup\t{%1, %0|%0, %1}"
24197   [(set_attr "type" "sse")
24198    (set_attr "mode" "V4SF")])
24199
24200 (define_insn "movsldup"
24201   [(set (match_operand:V4SF 0 "register_operand" "=x")
24202         (unspec:V4SF
24203          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
24204   "TARGET_SSE3"
24205   "movsldup\t{%1, %0|%0, %1}"
24206   [(set_attr "type" "sse")
24207    (set_attr "mode" "V4SF")])
24208
24209 (define_insn "lddqu"
24210   [(set (match_operand:V16QI 0 "register_operand" "=x")
24211         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
24212                        UNSPEC_LDQQU))]
24213   "TARGET_SSE3"
24214   "lddqu\t{%1, %0|%0, %1}"
24215   [(set_attr "type" "ssecvt")
24216    (set_attr "mode" "TI")])
24217
24218 (define_insn "loadddup"
24219   [(set (match_operand:V2DF 0 "register_operand" "=x")
24220         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
24221   "TARGET_SSE3"
24222   "movddup\t{%1, %0|%0, %1}"
24223   [(set_attr "type" "ssecvt")
24224    (set_attr "mode" "DF")])
24225
24226 (define_insn "movddup"
24227   [(set (match_operand:V2DF 0 "register_operand" "=x")
24228         (vec_duplicate:V2DF
24229          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
24230                         (parallel [(const_int 0)]))))]
24231   "TARGET_SSE3"
24232   "movddup\t{%1, %0|%0, %1}"
24233   [(set_attr "type" "ssecvt")
24234    (set_attr "mode" "DF")])