OSDN Git Service

* config/i386/i386.c (x86_64_reg_class_name): Re-indent.
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69
70    ; TLS support
71    (UNSPEC_TP                   15)
72    (UNSPEC_TLS_GD               16)
73    (UNSPEC_TLS_LD_BASE          17)
74
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_SIN                  21)
78    (UNSPEC_COS                  22)
79    (UNSPEC_FNSTSW               24)
80    (UNSPEC_SAHF                 25)
81    (UNSPEC_FSTCW                26)
82    (UNSPEC_ADD_CARRY            27)
83    (UNSPEC_FLDCW                28)
84
85    ; For SSE/MMX support:
86    (UNSPEC_FIX                  30)
87    (UNSPEC_MASKMOV              32)
88    (UNSPEC_MOVMSK               33)
89    (UNSPEC_MOVNT                34)
90    (UNSPEC_MOVA                 38)
91    (UNSPEC_MOVU                 39)
92    (UNSPEC_SHUFFLE              41)
93    (UNSPEC_RCP                  42)
94    (UNSPEC_RSQRT                43)
95    (UNSPEC_SFENCE               44)
96    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
97    (UNSPEC_PAVGUSB              49)
98    (UNSPEC_PFRCP                50)
99    (UNSPEC_PFRCPIT1             51)
100    (UNSPEC_PFRCPIT2             52)
101    (UNSPEC_PFRSQRT              53)
102    (UNSPEC_PFRSQIT1             54)
103    (UNSPEC_PSHUFLW              55)
104    (UNSPEC_PSHUFHW              56)
105    (UNSPEC_MFENCE               59)
106    (UNSPEC_LFENCE               60)
107    (UNSPEC_PSADBW               61)
108    (UNSPEC_ADDSUB               71)
109    (UNSPEC_HADD                 72)
110    (UNSPEC_HSUB                 73)
111    (UNSPEC_MOVSHDUP             74)
112    (UNSPEC_MOVSLDUP             75)
113    (UNSPEC_LDQQU                76)
114    (UNSPEC_MOVDDUP              77)
115
116    ; x87 Floating point
117    (UNSPEC_FPATAN               65)
118    (UNSPEC_FYL2X                66)
119    (UNSPEC_FYL2XP1              67)
120    (UNSPEC_FRNDINT              68)
121    (UNSPEC_F2XM1                69)
122
123    ; x87 Double output FP
124    (UNSPEC_SINCOS_COS           80)
125    (UNSPEC_SINCOS_SIN           81)
126    (UNSPEC_TAN_ONE              82)
127    (UNSPEC_TAN_TAN              83)
128    (UNSPEC_XTRACT_FRACT         84)
129    (UNSPEC_XTRACT_EXP           85)
130    (UNSPEC_FSCALE_FRACT         86)
131    (UNSPEC_FSCALE_EXP           87)
132    (UNSPEC_FPREM_F              88)
133    (UNSPEC_FPREM_U              89)
134    (UNSPEC_FPREM1_F             90)
135    (UNSPEC_FPREM1_U             91)
136
137    ; x87 Rounding
138    (UNSPEC_FRNDINT_FLOOR        96)
139    (UNSPEC_FRNDINT_CEIL         97)
140    (UNSPEC_FRNDINT_TRUNC        98)
141    (UNSPEC_FRNDINT_MASK_PM      99)
142
143    ; REP instruction
144    (UNSPEC_REP                  75)
145
146    (UNSPEC_EH_RETURN            76)
147   ])
148
149 (define_constants
150   [(UNSPECV_BLOCKAGE            0)
151    (UNSPECV_STACK_PROBE         10)
152    (UNSPECV_EMMS                31)
153    (UNSPECV_LDMXCSR             37)
154    (UNSPECV_STMXCSR             40)
155    (UNSPECV_FEMMS               46)
156    (UNSPECV_CLFLUSH             57)
157    (UNSPECV_ALIGN               68)
158    (UNSPECV_MONITOR             69)
159    (UNSPECV_MWAIT               70)
160   ])
161
162 ;; Registers by name.
163 (define_constants
164   [(BP_REG                       6)
165    (SP_REG                       7)
166    (FLAGS_REG                   17)
167    (FPSR_REG                    18)
168    (DIRFLAG_REG                 19)
169   ])
170
171 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
172 ;; from i386.c.
173
174 ;; In C guard expressions, put expressions which may be compile-time
175 ;; constants first.  This allows for better optimization.  For
176 ;; example, write "TARGET_64BIT && reload_completed", not
177 ;; "reload_completed && TARGET_64BIT".
178
179 \f
180 ;; Processor type.  This attribute must exactly match the processor_type
181 ;; enumeration in i386.h.
182 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
183   (const (symbol_ref "ix86_tune")))
184
185 ;; A basic instruction type.  Refinements due to arguments to be
186 ;; provided in other attributes.
187 (define_attr "type"
188   "other,multi,
189    alu,alu1,negnot,imov,imovx,lea,
190    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
191    icmp,test,ibr,setcc,icmov,
192    push,pop,call,callv,leave,
193    str,cld,
194    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint,
195    sselog,sseiadd,sseishft,sseimul,
196    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
197    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
198   (const_string "other"))
199
200 ;; Main data type used by the insn
201 (define_attr "mode"
202   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
203   (const_string "unknown"))
204
205 ;; The CPU unit operations uses.
206 (define_attr "unit" "integer,i387,sse,mmx,unknown"
207   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint")
208            (const_string "i387")
209          (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
210                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
211            (const_string "sse")
212          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
213            (const_string "mmx")
214          (eq_attr "type" "other")
215            (const_string "unknown")]
216          (const_string "integer")))
217
218 ;; The (bounding maximum) length of an instruction immediate.
219 (define_attr "length_immediate" ""
220   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
221            (const_int 0)
222          (eq_attr "unit" "i387,sse,mmx")
223            (const_int 0)
224          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
225                           imul,icmp,push,pop")
226            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
227          (eq_attr "type" "imov,test")
228            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
229          (eq_attr "type" "call")
230            (if_then_else (match_operand 0 "constant_call_address_operand" "")
231              (const_int 4)
232              (const_int 0))
233          (eq_attr "type" "callv")
234            (if_then_else (match_operand 1 "constant_call_address_operand" "")
235              (const_int 4)
236              (const_int 0))
237          ;; We don't know the size before shorten_branches.  Expect
238          ;; the instruction to fit for better scheduling.
239          (eq_attr "type" "ibr")
240            (const_int 1)
241          ]
242          (symbol_ref "/* Update immediate_length and other attributes! */
243                       abort(),1")))
244
245 ;; The (bounding maximum) length of an instruction address.
246 (define_attr "length_address" ""
247   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
248            (const_int 0)
249          (and (eq_attr "type" "call")
250               (match_operand 0 "constant_call_address_operand" ""))
251              (const_int 0)
252          (and (eq_attr "type" "callv")
253               (match_operand 1 "constant_call_address_operand" ""))
254              (const_int 0)
255          ]
256          (symbol_ref "ix86_attr_length_address_default (insn)")))
257
258 ;; Set when length prefix is used.
259 (define_attr "prefix_data16" ""
260   (if_then_else (ior (eq_attr "mode" "HI")
261                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
262     (const_int 1)
263     (const_int 0)))
264
265 ;; Set when string REP prefix is used.
266 (define_attr "prefix_rep" "" 
267   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
268     (const_int 1)
269     (const_int 0)))
270
271 ;; Set when 0f opcode prefix is used.
272 (define_attr "prefix_0f" ""
273   (if_then_else 
274     (ior (eq_attr "type" "imovx,setcc,icmov")
275          (eq_attr "unit" "sse,mmx"))
276     (const_int 1)
277     (const_int 0)))
278
279 ;; Set when REX opcode prefix is used.
280 (define_attr "prefix_rex" ""
281   (cond [(and (eq_attr "mode" "DI")
282               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
283            (const_int 1)
284          (and (eq_attr "mode" "QI")
285               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
286                   (const_int 0)))
287            (const_int 1)
288          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
289              (const_int 0))
290            (const_int 1)
291         ]
292         (const_int 0)))
293
294 ;; Set when modrm byte is used.
295 (define_attr "modrm" ""
296   (cond [(eq_attr "type" "str,cld,leave")
297            (const_int 0)
298          (eq_attr "unit" "i387")
299            (const_int 0)
300          (and (eq_attr "type" "incdec")
301               (ior (match_operand:SI 1 "register_operand" "")
302                    (match_operand:HI 1 "register_operand" "")))
303            (const_int 0)
304          (and (eq_attr "type" "push")
305               (not (match_operand 1 "memory_operand" "")))
306            (const_int 0)
307          (and (eq_attr "type" "pop")
308               (not (match_operand 0 "memory_operand" "")))
309            (const_int 0)
310          (and (eq_attr "type" "imov")
311               (and (match_operand 0 "register_operand" "")
312                    (match_operand 1 "immediate_operand" "")))
313            (const_int 0)
314          (and (eq_attr "type" "call")
315               (match_operand 0 "constant_call_address_operand" ""))
316              (const_int 0)
317          (and (eq_attr "type" "callv")
318               (match_operand 1 "constant_call_address_operand" ""))
319              (const_int 0)
320          ]
321          (const_int 1)))
322
323 ;; The (bounding maximum) length of an instruction in bytes.
324 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
325 ;; Later we may want to split them and compute proper length as for
326 ;; other insns.
327 (define_attr "length" ""
328   (cond [(eq_attr "type" "other,multi,fistp,frndint")
329            (const_int 16)
330          (eq_attr "type" "fcmp")
331            (const_int 4)
332          (eq_attr "unit" "i387")
333            (plus (const_int 2)
334                  (plus (attr "prefix_data16")
335                        (attr "length_address")))]
336          (plus (plus (attr "modrm")
337                      (plus (attr "prefix_0f")
338                            (plus (attr "prefix_rex")
339                                  (const_int 1))))
340                (plus (attr "prefix_rep")
341                      (plus (attr "prefix_data16")
342                            (plus (attr "length_immediate")
343                                  (attr "length_address")))))))
344
345 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
346 ;; `store' if there is a simple memory reference therein, or `unknown'
347 ;; if the instruction is complex.
348
349 (define_attr "memory" "none,load,store,both,unknown"
350   (cond [(eq_attr "type" "other,multi,str")
351            (const_string "unknown")
352          (eq_attr "type" "lea,fcmov,fpspc,cld")
353            (const_string "none")
354          (eq_attr "type" "fistp,leave")
355            (const_string "both")
356          (eq_attr "type" "frndint")
357            (const_string "load")
358          (eq_attr "type" "push")
359            (if_then_else (match_operand 1 "memory_operand" "")
360              (const_string "both")
361              (const_string "store"))
362          (eq_attr "type" "pop")
363            (if_then_else (match_operand 0 "memory_operand" "")
364              (const_string "both")
365              (const_string "load"))
366          (eq_attr "type" "setcc")
367            (if_then_else (match_operand 0 "memory_operand" "")
368              (const_string "store")
369              (const_string "none"))
370          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
371            (if_then_else (ior (match_operand 0 "memory_operand" "")
372                               (match_operand 1 "memory_operand" ""))
373              (const_string "load")
374              (const_string "none"))
375          (eq_attr "type" "ibr")
376            (if_then_else (match_operand 0 "memory_operand" "")
377              (const_string "load")
378              (const_string "none"))
379          (eq_attr "type" "call")
380            (if_then_else (match_operand 0 "constant_call_address_operand" "")
381              (const_string "none")
382              (const_string "load"))
383          (eq_attr "type" "callv")
384            (if_then_else (match_operand 1 "constant_call_address_operand" "")
385              (const_string "none")
386              (const_string "load"))
387          (and (eq_attr "type" "alu1,negnot,ishift1")
388               (match_operand 1 "memory_operand" ""))
389            (const_string "both")
390          (and (match_operand 0 "memory_operand" "")
391               (match_operand 1 "memory_operand" ""))
392            (const_string "both")
393          (match_operand 0 "memory_operand" "")
394            (const_string "store")
395          (match_operand 1 "memory_operand" "")
396            (const_string "load")
397          (and (eq_attr "type"
398                  "!alu1,negnot,ishift1,
399                    imov,imovx,icmp,test,
400                    fmov,fcmp,fsgn,
401                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
402                    mmx,mmxmov,mmxcmp,mmxcvt")
403               (match_operand 2 "memory_operand" ""))
404            (const_string "load")
405          (and (eq_attr "type" "icmov")
406               (match_operand 3 "memory_operand" ""))
407            (const_string "load")
408         ]
409         (const_string "none")))
410
411 ;; Indicates if an instruction has both an immediate and a displacement.
412
413 (define_attr "imm_disp" "false,true,unknown"
414   (cond [(eq_attr "type" "other,multi")
415            (const_string "unknown")
416          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
417               (and (match_operand 0 "memory_displacement_operand" "")
418                    (match_operand 1 "immediate_operand" "")))
419            (const_string "true")
420          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
421               (and (match_operand 0 "memory_displacement_operand" "")
422                    (match_operand 2 "immediate_operand" "")))
423            (const_string "true")
424         ]
425         (const_string "false")))
426
427 ;; Indicates if an FP operation has an integer source.
428
429 (define_attr "fp_int_src" "false,true"
430   (const_string "false"))
431
432 ;; Defines rounding mode of an FP operation.
433
434 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
435   (const_string "any"))
436
437 ;; Describe a user's asm statement.
438 (define_asm_attributes
439   [(set_attr "length" "128")
440    (set_attr "type" "multi")])
441 \f
442 ;; Scheduling descriptions
443
444 (include "pentium.md")
445 (include "ppro.md")
446 (include "k6.md")
447 (include "athlon.md")
448
449 \f
450 ;; Operand and operator predicates
451
452 (include "predicates.md")
453
454 \f
455 ;; Compare instructions.
456
457 ;; All compare insns have expanders that save the operands away without
458 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
459 ;; after the cmp) will actually emit the cmpM.
460
461 (define_expand "cmpdi"
462   [(set (reg:CC FLAGS_REG)
463         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
464                     (match_operand:DI 1 "x86_64_general_operand" "")))]
465   ""
466 {
467   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
468     operands[0] = force_reg (DImode, operands[0]);
469   ix86_compare_op0 = operands[0];
470   ix86_compare_op1 = operands[1];
471   DONE;
472 })
473
474 (define_expand "cmpsi"
475   [(set (reg:CC FLAGS_REG)
476         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
477                     (match_operand:SI 1 "general_operand" "")))]
478   ""
479 {
480   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
481     operands[0] = force_reg (SImode, operands[0]);
482   ix86_compare_op0 = operands[0];
483   ix86_compare_op1 = operands[1];
484   DONE;
485 })
486
487 (define_expand "cmphi"
488   [(set (reg:CC FLAGS_REG)
489         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
490                     (match_operand:HI 1 "general_operand" "")))]
491   ""
492 {
493   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494     operands[0] = force_reg (HImode, operands[0]);
495   ix86_compare_op0 = operands[0];
496   ix86_compare_op1 = operands[1];
497   DONE;
498 })
499
500 (define_expand "cmpqi"
501   [(set (reg:CC FLAGS_REG)
502         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
503                     (match_operand:QI 1 "general_operand" "")))]
504   "TARGET_QIMODE_MATH"
505 {
506   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
507     operands[0] = force_reg (QImode, operands[0]);
508   ix86_compare_op0 = operands[0];
509   ix86_compare_op1 = operands[1];
510   DONE;
511 })
512
513 (define_insn "cmpdi_ccno_1_rex64"
514   [(set (reg FLAGS_REG)
515         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
516                  (match_operand:DI 1 "const0_operand" "n,n")))]
517   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
518   "@
519    test{q}\t{%0, %0|%0, %0}
520    cmp{q}\t{%1, %0|%0, %1}"
521   [(set_attr "type" "test,icmp")
522    (set_attr "length_immediate" "0,1")
523    (set_attr "mode" "DI")])
524
525 (define_insn "*cmpdi_minus_1_rex64"
526   [(set (reg FLAGS_REG)
527         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
528                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
529                  (const_int 0)))]
530   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
531   "cmp{q}\t{%1, %0|%0, %1}"
532   [(set_attr "type" "icmp")
533    (set_attr "mode" "DI")])
534
535 (define_expand "cmpdi_1_rex64"
536   [(set (reg:CC FLAGS_REG)
537         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
538                     (match_operand:DI 1 "general_operand" "")))]
539   "TARGET_64BIT"
540   "")
541
542 (define_insn "cmpdi_1_insn_rex64"
543   [(set (reg FLAGS_REG)
544         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
545                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
546   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
547   "cmp{q}\t{%1, %0|%0, %1}"
548   [(set_attr "type" "icmp")
549    (set_attr "mode" "DI")])
550
551
552 (define_insn "*cmpsi_ccno_1"
553   [(set (reg FLAGS_REG)
554         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
555                  (match_operand:SI 1 "const0_operand" "n,n")))]
556   "ix86_match_ccmode (insn, CCNOmode)"
557   "@
558    test{l}\t{%0, %0|%0, %0}
559    cmp{l}\t{%1, %0|%0, %1}"
560   [(set_attr "type" "test,icmp")
561    (set_attr "length_immediate" "0,1")
562    (set_attr "mode" "SI")])
563
564 (define_insn "*cmpsi_minus_1"
565   [(set (reg FLAGS_REG)
566         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
567                            (match_operand:SI 1 "general_operand" "ri,mr"))
568                  (const_int 0)))]
569   "ix86_match_ccmode (insn, CCGOCmode)"
570   "cmp{l}\t{%1, %0|%0, %1}"
571   [(set_attr "type" "icmp")
572    (set_attr "mode" "SI")])
573
574 (define_expand "cmpsi_1"
575   [(set (reg:CC FLAGS_REG)
576         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
577                     (match_operand:SI 1 "general_operand" "ri,mr")))]
578   ""
579   "")
580
581 (define_insn "*cmpsi_1_insn"
582   [(set (reg FLAGS_REG)
583         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
584                  (match_operand:SI 1 "general_operand" "ri,mr")))]
585   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
586     && ix86_match_ccmode (insn, CCmode)"
587   "cmp{l}\t{%1, %0|%0, %1}"
588   [(set_attr "type" "icmp")
589    (set_attr "mode" "SI")])
590
591 (define_insn "*cmphi_ccno_1"
592   [(set (reg FLAGS_REG)
593         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
594                  (match_operand:HI 1 "const0_operand" "n,n")))]
595   "ix86_match_ccmode (insn, CCNOmode)"
596   "@
597    test{w}\t{%0, %0|%0, %0}
598    cmp{w}\t{%1, %0|%0, %1}"
599   [(set_attr "type" "test,icmp")
600    (set_attr "length_immediate" "0,1")
601    (set_attr "mode" "HI")])
602
603 (define_insn "*cmphi_minus_1"
604   [(set (reg FLAGS_REG)
605         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
606                            (match_operand:HI 1 "general_operand" "ri,mr"))
607                  (const_int 0)))]
608   "ix86_match_ccmode (insn, CCGOCmode)"
609   "cmp{w}\t{%1, %0|%0, %1}"
610   [(set_attr "type" "icmp")
611    (set_attr "mode" "HI")])
612
613 (define_insn "*cmphi_1"
614   [(set (reg FLAGS_REG)
615         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
616                  (match_operand:HI 1 "general_operand" "ri,mr")))]
617   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
618    && ix86_match_ccmode (insn, CCmode)"
619   "cmp{w}\t{%1, %0|%0, %1}"
620   [(set_attr "type" "icmp")
621    (set_attr "mode" "HI")])
622
623 (define_insn "*cmpqi_ccno_1"
624   [(set (reg FLAGS_REG)
625         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
626                  (match_operand:QI 1 "const0_operand" "n,n")))]
627   "ix86_match_ccmode (insn, CCNOmode)"
628   "@
629    test{b}\t{%0, %0|%0, %0}
630    cmp{b}\t{$0, %0|%0, 0}"
631   [(set_attr "type" "test,icmp")
632    (set_attr "length_immediate" "0,1")
633    (set_attr "mode" "QI")])
634
635 (define_insn "*cmpqi_1"
636   [(set (reg FLAGS_REG)
637         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
638                  (match_operand:QI 1 "general_operand" "qi,mq")))]
639   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
640     && ix86_match_ccmode (insn, CCmode)"
641   "cmp{b}\t{%1, %0|%0, %1}"
642   [(set_attr "type" "icmp")
643    (set_attr "mode" "QI")])
644
645 (define_insn "*cmpqi_minus_1"
646   [(set (reg FLAGS_REG)
647         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
648                            (match_operand:QI 1 "general_operand" "qi,mq"))
649                  (const_int 0)))]
650   "ix86_match_ccmode (insn, CCGOCmode)"
651   "cmp{b}\t{%1, %0|%0, %1}"
652   [(set_attr "type" "icmp")
653    (set_attr "mode" "QI")])
654
655 (define_insn "*cmpqi_ext_1"
656   [(set (reg FLAGS_REG)
657         (compare
658           (match_operand:QI 0 "general_operand" "Qm")
659           (subreg:QI
660             (zero_extract:SI
661               (match_operand 1 "ext_register_operand" "Q")
662               (const_int 8)
663               (const_int 8)) 0)))]
664   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
665   "cmp{b}\t{%h1, %0|%0, %h1}"
666   [(set_attr "type" "icmp")
667    (set_attr "mode" "QI")])
668
669 (define_insn "*cmpqi_ext_1_rex64"
670   [(set (reg FLAGS_REG)
671         (compare
672           (match_operand:QI 0 "register_operand" "Q")
673           (subreg:QI
674             (zero_extract:SI
675               (match_operand 1 "ext_register_operand" "Q")
676               (const_int 8)
677               (const_int 8)) 0)))]
678   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
679   "cmp{b}\t{%h1, %0|%0, %h1}"
680   [(set_attr "type" "icmp")
681    (set_attr "mode" "QI")])
682
683 (define_insn "*cmpqi_ext_2"
684   [(set (reg FLAGS_REG)
685         (compare
686           (subreg:QI
687             (zero_extract:SI
688               (match_operand 0 "ext_register_operand" "Q")
689               (const_int 8)
690               (const_int 8)) 0)
691           (match_operand:QI 1 "const0_operand" "n")))]
692   "ix86_match_ccmode (insn, CCNOmode)"
693   "test{b}\t%h0, %h0"
694   [(set_attr "type" "test")
695    (set_attr "length_immediate" "0")
696    (set_attr "mode" "QI")])
697
698 (define_expand "cmpqi_ext_3"
699   [(set (reg:CC FLAGS_REG)
700         (compare:CC
701           (subreg:QI
702             (zero_extract:SI
703               (match_operand 0 "ext_register_operand" "")
704               (const_int 8)
705               (const_int 8)) 0)
706           (match_operand:QI 1 "general_operand" "")))]
707   ""
708   "")
709
710 (define_insn "cmpqi_ext_3_insn"
711   [(set (reg FLAGS_REG)
712         (compare
713           (subreg:QI
714             (zero_extract:SI
715               (match_operand 0 "ext_register_operand" "Q")
716               (const_int 8)
717               (const_int 8)) 0)
718           (match_operand:QI 1 "general_operand" "Qmn")))]
719   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720   "cmp{b}\t{%1, %h0|%h0, %1}"
721   [(set_attr "type" "icmp")
722    (set_attr "mode" "QI")])
723
724 (define_insn "cmpqi_ext_3_insn_rex64"
725   [(set (reg FLAGS_REG)
726         (compare
727           (subreg:QI
728             (zero_extract:SI
729               (match_operand 0 "ext_register_operand" "Q")
730               (const_int 8)
731               (const_int 8)) 0)
732           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
733   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
734   "cmp{b}\t{%1, %h0|%h0, %1}"
735   [(set_attr "type" "icmp")
736    (set_attr "mode" "QI")])
737
738 (define_insn "*cmpqi_ext_4"
739   [(set (reg FLAGS_REG)
740         (compare
741           (subreg:QI
742             (zero_extract:SI
743               (match_operand 0 "ext_register_operand" "Q")
744               (const_int 8)
745               (const_int 8)) 0)
746           (subreg:QI
747             (zero_extract:SI
748               (match_operand 1 "ext_register_operand" "Q")
749               (const_int 8)
750               (const_int 8)) 0)))]
751   "ix86_match_ccmode (insn, CCmode)"
752   "cmp{b}\t{%h1, %h0|%h0, %h1}"
753   [(set_attr "type" "icmp")
754    (set_attr "mode" "QI")])
755
756 ;; These implement float point compares.
757 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
758 ;; which would allow mix and match FP modes on the compares.  Which is what
759 ;; the old patterns did, but with many more of them.
760
761 (define_expand "cmpxf"
762   [(set (reg:CC FLAGS_REG)
763         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
764                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
765   "TARGET_80387"
766 {
767   ix86_compare_op0 = operands[0];
768   ix86_compare_op1 = operands[1];
769   DONE;
770 })
771
772 (define_expand "cmpdf"
773   [(set (reg:CC FLAGS_REG)
774         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
775                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
776   "TARGET_80387 || TARGET_SSE2"
777 {
778   ix86_compare_op0 = operands[0];
779   ix86_compare_op1 = operands[1];
780   DONE;
781 })
782
783 (define_expand "cmpsf"
784   [(set (reg:CC FLAGS_REG)
785         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
786                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
787   "TARGET_80387 || TARGET_SSE"
788 {
789   ix86_compare_op0 = operands[0];
790   ix86_compare_op1 = operands[1];
791   DONE;
792 })
793
794 ;; FP compares, step 1:
795 ;; Set the FP condition codes.
796 ;;
797 ;; CCFPmode     compare with exceptions
798 ;; CCFPUmode    compare with no exceptions
799
800 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
801 ;; used to manage the reg stack popping would not be preserved.
802
803 (define_insn "*cmpfp_0_sf"
804   [(set (match_operand:HI 0 "register_operand" "=a")
805         (unspec:HI
806           [(compare:CCFP
807              (match_operand:SF 1 "register_operand" "f")
808              (match_operand:SF 2 "const0_operand" "X"))]
809         UNSPEC_FNSTSW))]
810   "TARGET_80387"
811   "* return output_fp_compare (insn, operands, 0, 0);"
812   [(set_attr "type" "multi")
813    (set_attr "mode" "SF")])
814
815 (define_insn "*cmpfp_0_df"
816   [(set (match_operand:HI 0 "register_operand" "=a")
817         (unspec:HI
818           [(compare:CCFP
819              (match_operand:DF 1 "register_operand" "f")
820              (match_operand:DF 2 "const0_operand" "X"))]
821         UNSPEC_FNSTSW))]
822   "TARGET_80387"
823   "* return output_fp_compare (insn, operands, 0, 0);"
824   [(set_attr "type" "multi")
825    (set_attr "mode" "DF")])
826
827 (define_insn "*cmpfp_0_xf"
828   [(set (match_operand:HI 0 "register_operand" "=a")
829         (unspec:HI
830           [(compare:CCFP
831              (match_operand:XF 1 "register_operand" "f")
832              (match_operand:XF 2 "const0_operand" "X"))]
833         UNSPEC_FNSTSW))]
834   "TARGET_80387"
835   "* return output_fp_compare (insn, operands, 0, 0);"
836   [(set_attr "type" "multi")
837    (set_attr "mode" "XF")])
838
839 (define_insn "*cmpfp_sf"
840   [(set (match_operand:HI 0 "register_operand" "=a")
841         (unspec:HI
842           [(compare:CCFP
843              (match_operand:SF 1 "register_operand" "f")
844              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
845           UNSPEC_FNSTSW))]
846   "TARGET_80387"
847   "* return output_fp_compare (insn, operands, 0, 0);"
848   [(set_attr "type" "multi")
849    (set_attr "mode" "SF")])
850
851 (define_insn "*cmpfp_df"
852   [(set (match_operand:HI 0 "register_operand" "=a")
853         (unspec:HI
854           [(compare:CCFP
855              (match_operand:DF 1 "register_operand" "f")
856              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
857           UNSPEC_FNSTSW))]
858   "TARGET_80387"
859   "* return output_fp_compare (insn, operands, 0, 0);"
860   [(set_attr "type" "multi")
861    (set_attr "mode" "DF")])
862
863 (define_insn "*cmpfp_xf"
864   [(set (match_operand:HI 0 "register_operand" "=a")
865         (unspec:HI
866           [(compare:CCFP
867              (match_operand:XF 1 "register_operand" "f")
868              (match_operand:XF 2 "register_operand" "f"))]
869           UNSPEC_FNSTSW))]
870   "TARGET_80387"
871   "* return output_fp_compare (insn, operands, 0, 0);"
872   [(set_attr "type" "multi")
873    (set_attr "mode" "XF")])
874
875 (define_insn "*cmpfp_u"
876   [(set (match_operand:HI 0 "register_operand" "=a")
877         (unspec:HI
878           [(compare:CCFPU
879              (match_operand 1 "register_operand" "f")
880              (match_operand 2 "register_operand" "f"))]
881           UNSPEC_FNSTSW))]
882   "TARGET_80387
883    && FLOAT_MODE_P (GET_MODE (operands[1]))
884    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
885   "* return output_fp_compare (insn, operands, 0, 1);"
886   [(set_attr "type" "multi")
887    (set (attr "mode")
888      (cond [(match_operand:SF 1 "" "")
889               (const_string "SF")
890             (match_operand:DF 1 "" "")
891               (const_string "DF")
892            ]
893            (const_string "XF")))])
894
895 (define_insn "*cmpfp_si"
896   [(set (match_operand:HI 0 "register_operand" "=a")
897         (unspec:HI
898           [(compare:CCFP
899              (match_operand 1 "register_operand" "f")
900              (match_operator 3 "float_operator"
901                [(match_operand:SI 2 "memory_operand" "m")]))]
902           UNSPEC_FNSTSW))]
903   "TARGET_80387 && TARGET_USE_FIOP
904    && FLOAT_MODE_P (GET_MODE (operands[1]))
905    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
906   "* return output_fp_compare (insn, operands, 0, 0);"
907   [(set_attr "type" "multi")
908    (set_attr "fp_int_src" "true")
909    (set_attr "mode" "SI")])
910
911 ;; FP compares, step 2
912 ;; Move the fpsw to ax.
913
914 (define_insn "x86_fnstsw_1"
915   [(set (match_operand:HI 0 "register_operand" "=a")
916         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
917   "TARGET_80387"
918   "fnstsw\t%0"
919   [(set_attr "length" "2")
920    (set_attr "mode" "SI")
921    (set_attr "unit" "i387")])
922
923 ;; FP compares, step 3
924 ;; Get ax into flags, general case.
925
926 (define_insn "x86_sahf_1"
927   [(set (reg:CC FLAGS_REG)
928         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
929   "!TARGET_64BIT"
930   "sahf"
931   [(set_attr "length" "1")
932    (set_attr "athlon_decode" "vector")
933    (set_attr "mode" "SI")])
934
935 ;; Pentium Pro can do steps 1 through 3 in one go.
936
937 (define_insn "*cmpfp_i"
938   [(set (reg:CCFP FLAGS_REG)
939         (compare:CCFP (match_operand 0 "register_operand" "f")
940                       (match_operand 1 "register_operand" "f")))]
941   "TARGET_80387 && TARGET_CMOVE
942    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
943    && FLOAT_MODE_P (GET_MODE (operands[0]))
944    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
945   "* return output_fp_compare (insn, operands, 1, 0);"
946   [(set_attr "type" "fcmp")
947    (set (attr "mode")
948      (cond [(match_operand:SF 1 "" "")
949               (const_string "SF")
950             (match_operand:DF 1 "" "")
951               (const_string "DF")
952            ]
953            (const_string "XF")))
954    (set_attr "athlon_decode" "vector")])
955
956 (define_insn "*cmpfp_i_sse"
957   [(set (reg:CCFP FLAGS_REG)
958         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
959                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
960   "TARGET_80387
961    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
962    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
963   "* return output_fp_compare (insn, operands, 1, 0);"
964   [(set_attr "type" "fcmp,ssecomi")
965    (set (attr "mode")
966      (if_then_else (match_operand:SF 1 "" "")
967         (const_string "SF")
968         (const_string "DF")))
969    (set_attr "athlon_decode" "vector")])
970
971 (define_insn "*cmpfp_i_sse_only"
972   [(set (reg:CCFP FLAGS_REG)
973         (compare:CCFP (match_operand 0 "register_operand" "x")
974                       (match_operand 1 "nonimmediate_operand" "xm")))]
975   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
976    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
977   "* return output_fp_compare (insn, operands, 1, 0);"
978   [(set_attr "type" "ssecomi")
979    (set (attr "mode")
980      (if_then_else (match_operand:SF 1 "" "")
981         (const_string "SF")
982         (const_string "DF")))
983    (set_attr "athlon_decode" "vector")])
984
985 (define_insn "*cmpfp_iu"
986   [(set (reg:CCFPU FLAGS_REG)
987         (compare:CCFPU (match_operand 0 "register_operand" "f")
988                        (match_operand 1 "register_operand" "f")))]
989   "TARGET_80387 && TARGET_CMOVE
990    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
991    && FLOAT_MODE_P (GET_MODE (operands[0]))
992    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
993   "* return output_fp_compare (insn, operands, 1, 1);"
994   [(set_attr "type" "fcmp")
995    (set (attr "mode")
996      (cond [(match_operand:SF 1 "" "")
997               (const_string "SF")
998             (match_operand:DF 1 "" "")
999               (const_string "DF")
1000            ]
1001            (const_string "XF")))
1002    (set_attr "athlon_decode" "vector")])
1003
1004 (define_insn "*cmpfp_iu_sse"
1005   [(set (reg:CCFPU FLAGS_REG)
1006         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1007                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1008   "TARGET_80387
1009    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1010    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1011   "* return output_fp_compare (insn, operands, 1, 1);"
1012   [(set_attr "type" "fcmp,ssecomi")
1013    (set (attr "mode")
1014      (if_then_else (match_operand:SF 1 "" "")
1015         (const_string "SF")
1016         (const_string "DF")))
1017    (set_attr "athlon_decode" "vector")])
1018
1019 (define_insn "*cmpfp_iu_sse_only"
1020   [(set (reg:CCFPU FLAGS_REG)
1021         (compare:CCFPU (match_operand 0 "register_operand" "x")
1022                        (match_operand 1 "nonimmediate_operand" "xm")))]
1023   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1024    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025   "* return output_fp_compare (insn, operands, 1, 1);"
1026   [(set_attr "type" "ssecomi")
1027    (set (attr "mode")
1028      (if_then_else (match_operand:SF 1 "" "")
1029         (const_string "SF")
1030         (const_string "DF")))
1031    (set_attr "athlon_decode" "vector")])
1032 \f
1033 ;; Move instructions.
1034
1035 ;; General case of fullword move.
1036
1037 (define_expand "movsi"
1038   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1039         (match_operand:SI 1 "general_operand" ""))]
1040   ""
1041   "ix86_expand_move (SImode, operands); DONE;")
1042
1043 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1044 ;; general_operand.
1045 ;;
1046 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1047 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1048 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1049 ;; targets without our curiosities, and it is just as easy to represent
1050 ;; this differently.
1051
1052 (define_insn "*pushsi2"
1053   [(set (match_operand:SI 0 "push_operand" "=<")
1054         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1055   "!TARGET_64BIT"
1056   "push{l}\t%1"
1057   [(set_attr "type" "push")
1058    (set_attr "mode" "SI")])
1059
1060 ;; For 64BIT abi we always round up to 8 bytes.
1061 (define_insn "*pushsi2_rex64"
1062   [(set (match_operand:SI 0 "push_operand" "=X")
1063         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1064   "TARGET_64BIT"
1065   "push{q}\t%q1"
1066   [(set_attr "type" "push")
1067    (set_attr "mode" "SI")])
1068
1069 (define_insn "*pushsi2_prologue"
1070   [(set (match_operand:SI 0 "push_operand" "=<")
1071         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1072    (clobber (mem:BLK (scratch)))]
1073   "!TARGET_64BIT"
1074   "push{l}\t%1"
1075   [(set_attr "type" "push")
1076    (set_attr "mode" "SI")])
1077
1078 (define_insn "*popsi1_epilogue"
1079   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1080         (mem:SI (reg:SI SP_REG)))
1081    (set (reg:SI SP_REG)
1082         (plus:SI (reg:SI SP_REG) (const_int 4)))
1083    (clobber (mem:BLK (scratch)))]
1084   "!TARGET_64BIT"
1085   "pop{l}\t%0"
1086   [(set_attr "type" "pop")
1087    (set_attr "mode" "SI")])
1088
1089 (define_insn "popsi1"
1090   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1091         (mem:SI (reg:SI SP_REG)))
1092    (set (reg:SI SP_REG)
1093         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1094   "!TARGET_64BIT"
1095   "pop{l}\t%0"
1096   [(set_attr "type" "pop")
1097    (set_attr "mode" "SI")])
1098
1099 (define_insn "*movsi_xor"
1100   [(set (match_operand:SI 0 "register_operand" "=r")
1101         (match_operand:SI 1 "const0_operand" "i"))
1102    (clobber (reg:CC FLAGS_REG))]
1103   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1104   "xor{l}\t{%0, %0|%0, %0}"
1105   [(set_attr "type" "alu1")
1106    (set_attr "mode" "SI")
1107    (set_attr "length_immediate" "0")])
1108  
1109 (define_insn "*movsi_or"
1110   [(set (match_operand:SI 0 "register_operand" "=r")
1111         (match_operand:SI 1 "immediate_operand" "i"))
1112    (clobber (reg:CC FLAGS_REG))]
1113   "reload_completed
1114    && operands[1] == constm1_rtx
1115    && (TARGET_PENTIUM || optimize_size)"
1116 {
1117   operands[1] = constm1_rtx;
1118   return "or{l}\t{%1, %0|%0, %1}";
1119 }
1120   [(set_attr "type" "alu1")
1121    (set_attr "mode" "SI")
1122    (set_attr "length_immediate" "1")])
1123
1124 (define_insn "*movsi_1"
1125   [(set (match_operand:SI 0 "nonimmediate_operand"
1126                         "=r  ,m  ,!*y,!rm,!*y,!*x,!rm,!*x")
1127         (match_operand:SI 1 "general_operand"
1128                         "rinm,rin,*y ,*y ,rm ,*x ,*x ,rm"))]
1129   "(TARGET_INTER_UNIT_MOVES || optimize_size)
1130    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1131 {
1132   switch (get_attr_type (insn))
1133     {
1134     case TYPE_SSEMOV:
1135       if (get_attr_mode (insn) == MODE_TI)
1136         return "movdqa\t{%1, %0|%0, %1}";
1137       return "movd\t{%1, %0|%0, %1}";
1138
1139     case TYPE_MMXMOV:
1140       if (get_attr_mode (insn) == MODE_DI)
1141         return "movq\t{%1, %0|%0, %1}";
1142       return "movd\t{%1, %0|%0, %1}";
1143
1144     case TYPE_LEA:
1145       return "lea{l}\t{%1, %0|%0, %1}";
1146
1147     default:
1148       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1149         abort();
1150       return "mov{l}\t{%1, %0|%0, %1}";
1151     }
1152 }
1153   [(set (attr "type")
1154      (cond [(eq_attr "alternative" "2,3,4")
1155               (const_string "mmxmov")
1156             (eq_attr "alternative" "5,6,7")
1157               (const_string "ssemov")
1158             (and (ne (symbol_ref "flag_pic") (const_int 0))
1159                  (match_operand:SI 1 "symbolic_operand" ""))
1160               (const_string "lea")
1161            ]
1162            (const_string "imov")))
1163    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1164
1165 (define_insn "*movsi_1_nointernunit"
1166   [(set (match_operand:SI 0 "nonimmediate_operand"
1167                         "=r  ,m  ,!*y,!m,!*y,!*x,!m,!*x")
1168         (match_operand:SI 1 "general_operand"
1169                         "rinm,rin,*y ,*y,m  ,*x ,*x,m"))]
1170   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1171    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1172 {
1173   switch (get_attr_type (insn))
1174     {
1175     case TYPE_SSEMOV:
1176       if (get_attr_mode (insn) == MODE_TI)
1177         return "movdqa\t{%1, %0|%0, %1}";
1178       return "movd\t{%1, %0|%0, %1}";
1179
1180     case TYPE_MMXMOV:
1181       if (get_attr_mode (insn) == MODE_DI)
1182         return "movq\t{%1, %0|%0, %1}";
1183       return "movd\t{%1, %0|%0, %1}";
1184
1185     case TYPE_LEA:
1186       return "lea{l}\t{%1, %0|%0, %1}";
1187
1188     default:
1189       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1190         abort();
1191       return "mov{l}\t{%1, %0|%0, %1}";
1192     }
1193 }
1194   [(set (attr "type")
1195      (cond [(eq_attr "alternative" "2,3,4")
1196               (const_string "mmxmov")
1197             (eq_attr "alternative" "5,6,7")
1198               (const_string "ssemov")
1199             (and (ne (symbol_ref "flag_pic") (const_int 0))
1200                  (match_operand:SI 1 "symbolic_operand" ""))
1201               (const_string "lea")
1202            ]
1203            (const_string "imov")))
1204    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1205
1206 ;; Stores and loads of ax to arbitrary constant address.
1207 ;; We fake an second form of instruction to force reload to load address
1208 ;; into register when rax is not available
1209 (define_insn "*movabssi_1_rex64"
1210   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1211         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1212   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1213   "@
1214    movabs{l}\t{%1, %P0|%P0, %1}
1215    mov{l}\t{%1, %a0|%a0, %1}"
1216   [(set_attr "type" "imov")
1217    (set_attr "modrm" "0,*")
1218    (set_attr "length_address" "8,0")
1219    (set_attr "length_immediate" "0,*")
1220    (set_attr "memory" "store")
1221    (set_attr "mode" "SI")])
1222
1223 (define_insn "*movabssi_2_rex64"
1224   [(set (match_operand:SI 0 "register_operand" "=a,r")
1225         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1226   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1227   "@
1228    movabs{l}\t{%P1, %0|%0, %P1}
1229    mov{l}\t{%a1, %0|%0, %a1}"
1230   [(set_attr "type" "imov")
1231    (set_attr "modrm" "0,*")
1232    (set_attr "length_address" "8,0")
1233    (set_attr "length_immediate" "0")
1234    (set_attr "memory" "load")
1235    (set_attr "mode" "SI")])
1236
1237 (define_insn "*swapsi"
1238   [(set (match_operand:SI 0 "register_operand" "+r")
1239         (match_operand:SI 1 "register_operand" "+r"))
1240    (set (match_dup 1)
1241         (match_dup 0))]
1242   ""
1243   "xchg{l}\t%1, %0"
1244   [(set_attr "type" "imov")
1245    (set_attr "mode" "SI")
1246    (set_attr "pent_pair" "np")
1247    (set_attr "athlon_decode" "vector")])
1248
1249 (define_expand "movhi"
1250   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1251         (match_operand:HI 1 "general_operand" ""))]
1252   ""
1253   "ix86_expand_move (HImode, operands); DONE;")
1254
1255 (define_insn "*pushhi2"
1256   [(set (match_operand:HI 0 "push_operand" "=<,<")
1257         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1258   "!TARGET_64BIT"
1259   "@
1260    push{w}\t{|WORD PTR }%1
1261    push{w}\t%1"
1262   [(set_attr "type" "push")
1263    (set_attr "mode" "HI")])
1264
1265 ;; For 64BIT abi we always round up to 8 bytes.
1266 (define_insn "*pushhi2_rex64"
1267   [(set (match_operand:HI 0 "push_operand" "=X")
1268         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1269   "TARGET_64BIT"
1270   "push{q}\t%q1"
1271   [(set_attr "type" "push")
1272    (set_attr "mode" "QI")])
1273
1274 (define_insn "*movhi_1"
1275   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1276         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1277   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1278 {
1279   switch (get_attr_type (insn))
1280     {
1281     case TYPE_IMOVX:
1282       /* movzwl is faster than movw on p2 due to partial word stalls,
1283          though not as fast as an aligned movl.  */
1284       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1285     default:
1286       if (get_attr_mode (insn) == MODE_SI)
1287         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1288       else
1289         return "mov{w}\t{%1, %0|%0, %1}";
1290     }
1291 }
1292   [(set (attr "type")
1293      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1294               (const_string "imov")
1295             (and (eq_attr "alternative" "0")
1296                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1297                           (const_int 0))
1298                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1299                           (const_int 0))))
1300               (const_string "imov")
1301             (and (eq_attr "alternative" "1,2")
1302                  (match_operand:HI 1 "aligned_operand" ""))
1303               (const_string "imov")
1304             (and (ne (symbol_ref "TARGET_MOVX")
1305                      (const_int 0))
1306                  (eq_attr "alternative" "0,2"))
1307               (const_string "imovx")
1308            ]
1309            (const_string "imov")))
1310     (set (attr "mode")
1311       (cond [(eq_attr "type" "imovx")
1312                (const_string "SI")
1313              (and (eq_attr "alternative" "1,2")
1314                   (match_operand:HI 1 "aligned_operand" ""))
1315                (const_string "SI")
1316              (and (eq_attr "alternative" "0")
1317                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1318                            (const_int 0))
1319                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1320                            (const_int 0))))
1321                (const_string "SI")
1322             ]
1323             (const_string "HI")))])
1324
1325 ;; Stores and loads of ax to arbitrary constant address.
1326 ;; We fake an second form of instruction to force reload to load address
1327 ;; into register when rax is not available
1328 (define_insn "*movabshi_1_rex64"
1329   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1330         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1331   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1332   "@
1333    movabs{w}\t{%1, %P0|%P0, %1}
1334    mov{w}\t{%1, %a0|%a0, %1}"
1335   [(set_attr "type" "imov")
1336    (set_attr "modrm" "0,*")
1337    (set_attr "length_address" "8,0")
1338    (set_attr "length_immediate" "0,*")
1339    (set_attr "memory" "store")
1340    (set_attr "mode" "HI")])
1341
1342 (define_insn "*movabshi_2_rex64"
1343   [(set (match_operand:HI 0 "register_operand" "=a,r")
1344         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1345   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1346   "@
1347    movabs{w}\t{%P1, %0|%0, %P1}
1348    mov{w}\t{%a1, %0|%0, %a1}"
1349   [(set_attr "type" "imov")
1350    (set_attr "modrm" "0,*")
1351    (set_attr "length_address" "8,0")
1352    (set_attr "length_immediate" "0")
1353    (set_attr "memory" "load")
1354    (set_attr "mode" "HI")])
1355
1356 (define_insn "*swaphi_1"
1357   [(set (match_operand:HI 0 "register_operand" "+r")
1358         (match_operand:HI 1 "register_operand" "+r"))
1359    (set (match_dup 1)
1360         (match_dup 0))]
1361   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1362   "xchg{l}\t%k1, %k0"
1363   [(set_attr "type" "imov")
1364    (set_attr "mode" "SI")
1365    (set_attr "pent_pair" "np")
1366    (set_attr "athlon_decode" "vector")])
1367
1368 (define_insn "*swaphi_2"
1369   [(set (match_operand:HI 0 "register_operand" "+r")
1370         (match_operand:HI 1 "register_operand" "+r"))
1371    (set (match_dup 1)
1372         (match_dup 0))]
1373   "TARGET_PARTIAL_REG_STALL"
1374   "xchg{w}\t%1, %0"
1375   [(set_attr "type" "imov")
1376    (set_attr "mode" "HI")
1377    (set_attr "pent_pair" "np")
1378    (set_attr "athlon_decode" "vector")])
1379
1380 (define_expand "movstricthi"
1381   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1382         (match_operand:HI 1 "general_operand" ""))]
1383   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1384 {
1385   /* Don't generate memory->memory moves, go through a register */
1386   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1387     operands[1] = force_reg (HImode, operands[1]);
1388 })
1389
1390 (define_insn "*movstricthi_1"
1391   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1392         (match_operand:HI 1 "general_operand" "rn,m"))]
1393   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1394    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1395   "mov{w}\t{%1, %0|%0, %1}"
1396   [(set_attr "type" "imov")
1397    (set_attr "mode" "HI")])
1398
1399 (define_insn "*movstricthi_xor"
1400   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1401         (match_operand:HI 1 "const0_operand" "i"))
1402    (clobber (reg:CC FLAGS_REG))]
1403   "reload_completed
1404    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1405   "xor{w}\t{%0, %0|%0, %0}"
1406   [(set_attr "type" "alu1")
1407    (set_attr "mode" "HI")
1408    (set_attr "length_immediate" "0")])
1409
1410 (define_expand "movqi"
1411   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1412         (match_operand:QI 1 "general_operand" ""))]
1413   ""
1414   "ix86_expand_move (QImode, operands); DONE;")
1415
1416 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1417 ;; "push a byte".  But actually we use pushw, which has the effect
1418 ;; of rounding the amount pushed up to a halfword.
1419
1420 (define_insn "*pushqi2"
1421   [(set (match_operand:QI 0 "push_operand" "=X,X")
1422         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1423   "!TARGET_64BIT"
1424   "@
1425    push{w}\t{|word ptr }%1
1426    push{w}\t%w1"
1427   [(set_attr "type" "push")
1428    (set_attr "mode" "HI")])
1429
1430 ;; For 64BIT abi we always round up to 8 bytes.
1431 (define_insn "*pushqi2_rex64"
1432   [(set (match_operand:QI 0 "push_operand" "=X")
1433         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1434   "TARGET_64BIT"
1435   "push{q}\t%q1"
1436   [(set_attr "type" "push")
1437    (set_attr "mode" "QI")])
1438
1439 ;; Situation is quite tricky about when to choose full sized (SImode) move
1440 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1441 ;; partial register dependency machines (such as AMD Athlon), where QImode
1442 ;; moves issue extra dependency and for partial register stalls machines
1443 ;; that don't use QImode patterns (and QImode move cause stall on the next
1444 ;; instruction).
1445 ;;
1446 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1447 ;; register stall machines with, where we use QImode instructions, since
1448 ;; partial register stall can be caused there.  Then we use movzx.
1449 (define_insn "*movqi_1"
1450   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1451         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1452   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1453 {
1454   switch (get_attr_type (insn))
1455     {
1456     case TYPE_IMOVX:
1457       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1458         abort ();
1459       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1460     default:
1461       if (get_attr_mode (insn) == MODE_SI)
1462         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1463       else
1464         return "mov{b}\t{%1, %0|%0, %1}";
1465     }
1466 }
1467   [(set (attr "type")
1468      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1469               (const_string "imov")
1470             (and (eq_attr "alternative" "3")
1471                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1472                           (const_int 0))
1473                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1474                           (const_int 0))))
1475               (const_string "imov")
1476             (eq_attr "alternative" "3,5")
1477               (const_string "imovx")
1478             (and (ne (symbol_ref "TARGET_MOVX")
1479                      (const_int 0))
1480                  (eq_attr "alternative" "2"))
1481               (const_string "imovx")
1482            ]
1483            (const_string "imov")))
1484    (set (attr "mode")
1485       (cond [(eq_attr "alternative" "3,4,5")
1486                (const_string "SI")
1487              (eq_attr "alternative" "6")
1488                (const_string "QI")
1489              (eq_attr "type" "imovx")
1490                (const_string "SI")
1491              (and (eq_attr "type" "imov")
1492                   (and (eq_attr "alternative" "0,1,2")
1493                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1494                            (const_int 0))))
1495                (const_string "SI")
1496              ;; Avoid partial register stalls when not using QImode arithmetic
1497              (and (eq_attr "type" "imov")
1498                   (and (eq_attr "alternative" "0,1,2")
1499                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1500                                 (const_int 0))
1501                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1502                                 (const_int 0)))))
1503                (const_string "SI")
1504            ]
1505            (const_string "QI")))])
1506
1507 (define_expand "reload_outqi"
1508   [(parallel [(match_operand:QI 0 "" "=m")
1509               (match_operand:QI 1 "register_operand" "r")
1510               (match_operand:QI 2 "register_operand" "=&q")])]
1511   ""
1512 {
1513   rtx op0, op1, op2;
1514   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1515
1516   if (reg_overlap_mentioned_p (op2, op0))
1517     abort ();
1518   if (! q_regs_operand (op1, QImode))
1519     {
1520       emit_insn (gen_movqi (op2, op1));
1521       op1 = op2;
1522     }
1523   emit_insn (gen_movqi (op0, op1));
1524   DONE;
1525 })
1526
1527 (define_insn "*swapqi_1"
1528   [(set (match_operand:QI 0 "register_operand" "+r")
1529         (match_operand:QI 1 "register_operand" "+r"))
1530    (set (match_dup 1)
1531         (match_dup 0))]
1532   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1533   "xchg{l}\t%k1, %k0"
1534   [(set_attr "type" "imov")
1535    (set_attr "mode" "SI")
1536    (set_attr "pent_pair" "np")
1537    (set_attr "athlon_decode" "vector")])
1538
1539 (define_insn "*swapqi_2"
1540   [(set (match_operand:QI 0 "register_operand" "+q")
1541         (match_operand:QI 1 "register_operand" "+q"))
1542    (set (match_dup 1)
1543         (match_dup 0))]
1544   "TARGET_PARTIAL_REG_STALL"
1545   "xchg{b}\t%1, %0"
1546   [(set_attr "type" "imov")
1547    (set_attr "mode" "QI")
1548    (set_attr "pent_pair" "np")
1549    (set_attr "athlon_decode" "vector")])
1550
1551 (define_expand "movstrictqi"
1552   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1553         (match_operand:QI 1 "general_operand" ""))]
1554   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1555 {
1556   /* Don't generate memory->memory moves, go through a register.  */
1557   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1558     operands[1] = force_reg (QImode, operands[1]);
1559 })
1560
1561 (define_insn "*movstrictqi_1"
1562   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1563         (match_operand:QI 1 "general_operand" "*qn,m"))]
1564   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1565    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1566   "mov{b}\t{%1, %0|%0, %1}"
1567   [(set_attr "type" "imov")
1568    (set_attr "mode" "QI")])
1569
1570 (define_insn "*movstrictqi_xor"
1571   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1572         (match_operand:QI 1 "const0_operand" "i"))
1573    (clobber (reg:CC FLAGS_REG))]
1574   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1575   "xor{b}\t{%0, %0|%0, %0}"
1576   [(set_attr "type" "alu1")
1577    (set_attr "mode" "QI")
1578    (set_attr "length_immediate" "0")])
1579
1580 (define_insn "*movsi_extv_1"
1581   [(set (match_operand:SI 0 "register_operand" "=R")
1582         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1583                          (const_int 8)
1584                          (const_int 8)))]
1585   ""
1586   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1587   [(set_attr "type" "imovx")
1588    (set_attr "mode" "SI")])
1589
1590 (define_insn "*movhi_extv_1"
1591   [(set (match_operand:HI 0 "register_operand" "=R")
1592         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1593                          (const_int 8)
1594                          (const_int 8)))]
1595   ""
1596   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1597   [(set_attr "type" "imovx")
1598    (set_attr "mode" "SI")])
1599
1600 (define_insn "*movqi_extv_1"
1601   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1602         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1603                          (const_int 8)
1604                          (const_int 8)))]
1605   "!TARGET_64BIT"
1606 {
1607   switch (get_attr_type (insn))
1608     {
1609     case TYPE_IMOVX:
1610       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1611     default:
1612       return "mov{b}\t{%h1, %0|%0, %h1}";
1613     }
1614 }
1615   [(set (attr "type")
1616      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1617                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1618                              (ne (symbol_ref "TARGET_MOVX")
1619                                  (const_int 0))))
1620         (const_string "imovx")
1621         (const_string "imov")))
1622    (set (attr "mode")
1623      (if_then_else (eq_attr "type" "imovx")
1624         (const_string "SI")
1625         (const_string "QI")))])
1626
1627 (define_insn "*movqi_extv_1_rex64"
1628   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1629         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1630                          (const_int 8)
1631                          (const_int 8)))]
1632   "TARGET_64BIT"
1633 {
1634   switch (get_attr_type (insn))
1635     {
1636     case TYPE_IMOVX:
1637       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1638     default:
1639       return "mov{b}\t{%h1, %0|%0, %h1}";
1640     }
1641 }
1642   [(set (attr "type")
1643      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1644                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1645                              (ne (symbol_ref "TARGET_MOVX")
1646                                  (const_int 0))))
1647         (const_string "imovx")
1648         (const_string "imov")))
1649    (set (attr "mode")
1650      (if_then_else (eq_attr "type" "imovx")
1651         (const_string "SI")
1652         (const_string "QI")))])
1653
1654 ;; Stores and loads of ax to arbitrary constant address.
1655 ;; We fake an second form of instruction to force reload to load address
1656 ;; into register when rax is not available
1657 (define_insn "*movabsqi_1_rex64"
1658   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1659         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1660   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1661   "@
1662    movabs{b}\t{%1, %P0|%P0, %1}
1663    mov{b}\t{%1, %a0|%a0, %1}"
1664   [(set_attr "type" "imov")
1665    (set_attr "modrm" "0,*")
1666    (set_attr "length_address" "8,0")
1667    (set_attr "length_immediate" "0,*")
1668    (set_attr "memory" "store")
1669    (set_attr "mode" "QI")])
1670
1671 (define_insn "*movabsqi_2_rex64"
1672   [(set (match_operand:QI 0 "register_operand" "=a,r")
1673         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1674   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1675   "@
1676    movabs{b}\t{%P1, %0|%0, %P1}
1677    mov{b}\t{%a1, %0|%0, %a1}"
1678   [(set_attr "type" "imov")
1679    (set_attr "modrm" "0,*")
1680    (set_attr "length_address" "8,0")
1681    (set_attr "length_immediate" "0")
1682    (set_attr "memory" "load")
1683    (set_attr "mode" "QI")])
1684
1685 (define_insn "*movsi_extzv_1"
1686   [(set (match_operand:SI 0 "register_operand" "=R")
1687         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1688                          (const_int 8)
1689                          (const_int 8)))]
1690   ""
1691   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1692   [(set_attr "type" "imovx")
1693    (set_attr "mode" "SI")])
1694
1695 (define_insn "*movqi_extzv_2"
1696   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1697         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1698                                     (const_int 8)
1699                                     (const_int 8)) 0))]
1700   "!TARGET_64BIT"
1701 {
1702   switch (get_attr_type (insn))
1703     {
1704     case TYPE_IMOVX:
1705       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1706     default:
1707       return "mov{b}\t{%h1, %0|%0, %h1}";
1708     }
1709 }
1710   [(set (attr "type")
1711      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1712                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1713                              (ne (symbol_ref "TARGET_MOVX")
1714                                  (const_int 0))))
1715         (const_string "imovx")
1716         (const_string "imov")))
1717    (set (attr "mode")
1718      (if_then_else (eq_attr "type" "imovx")
1719         (const_string "SI")
1720         (const_string "QI")))])
1721
1722 (define_insn "*movqi_extzv_2_rex64"
1723   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1724         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1725                                     (const_int 8)
1726                                     (const_int 8)) 0))]
1727   "TARGET_64BIT"
1728 {
1729   switch (get_attr_type (insn))
1730     {
1731     case TYPE_IMOVX:
1732       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1733     default:
1734       return "mov{b}\t{%h1, %0|%0, %h1}";
1735     }
1736 }
1737   [(set (attr "type")
1738      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1739                         (ne (symbol_ref "TARGET_MOVX")
1740                             (const_int 0)))
1741         (const_string "imovx")
1742         (const_string "imov")))
1743    (set (attr "mode")
1744      (if_then_else (eq_attr "type" "imovx")
1745         (const_string "SI")
1746         (const_string "QI")))])
1747
1748 (define_insn "movsi_insv_1"
1749   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1750                          (const_int 8)
1751                          (const_int 8))
1752         (match_operand:SI 1 "general_operand" "Qmn"))]
1753   "!TARGET_64BIT"
1754   "mov{b}\t{%b1, %h0|%h0, %b1}"
1755   [(set_attr "type" "imov")
1756    (set_attr "mode" "QI")])
1757
1758 (define_insn "movdi_insv_1_rex64"
1759   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1760                          (const_int 8)
1761                          (const_int 8))
1762         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1763   "TARGET_64BIT"
1764   "mov{b}\t{%b1, %h0|%h0, %b1}"
1765   [(set_attr "type" "imov")
1766    (set_attr "mode" "QI")])
1767
1768 (define_insn "*movqi_insv_2"
1769   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1770                          (const_int 8)
1771                          (const_int 8))
1772         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1773                      (const_int 8)))]
1774   ""
1775   "mov{b}\t{%h1, %h0|%h0, %h1}"
1776   [(set_attr "type" "imov")
1777    (set_attr "mode" "QI")])
1778
1779 (define_expand "movdi"
1780   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1781         (match_operand:DI 1 "general_operand" ""))]
1782   ""
1783   "ix86_expand_move (DImode, operands); DONE;")
1784
1785 (define_insn "*pushdi"
1786   [(set (match_operand:DI 0 "push_operand" "=<")
1787         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1788   "!TARGET_64BIT"
1789   "#")
1790
1791 (define_insn "*pushdi2_rex64"
1792   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1793         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1794   "TARGET_64BIT"
1795   "@
1796    push{q}\t%1
1797    #"
1798   [(set_attr "type" "push,multi")
1799    (set_attr "mode" "DI")])
1800
1801 ;; Convert impossible pushes of immediate to existing instructions.
1802 ;; First try to get scratch register and go through it.  In case this
1803 ;; fails, push sign extended lower part first and then overwrite
1804 ;; upper part by 32bit move.
1805 (define_peephole2
1806   [(match_scratch:DI 2 "r")
1807    (set (match_operand:DI 0 "push_operand" "")
1808         (match_operand:DI 1 "immediate_operand" ""))]
1809   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1810    && !x86_64_immediate_operand (operands[1], DImode)"
1811   [(set (match_dup 2) (match_dup 1))
1812    (set (match_dup 0) (match_dup 2))]
1813   "")
1814
1815 ;; We need to define this as both peepholer and splitter for case
1816 ;; peephole2 pass is not run.
1817 ;; "&& 1" is needed to keep it from matching the previous pattern.
1818 (define_peephole2
1819   [(set (match_operand:DI 0 "push_operand" "")
1820         (match_operand:DI 1 "immediate_operand" ""))]
1821   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1822    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1823   [(set (match_dup 0) (match_dup 1))
1824    (set (match_dup 2) (match_dup 3))]
1825   "split_di (operands + 1, 1, operands + 2, operands + 3);
1826    operands[1] = gen_lowpart (DImode, operands[2]);
1827    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1828                                                     GEN_INT (4)));
1829   ")
1830
1831 (define_split
1832   [(set (match_operand:DI 0 "push_operand" "")
1833         (match_operand:DI 1 "immediate_operand" ""))]
1834   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1835    && !symbolic_operand (operands[1], DImode)
1836    && !x86_64_immediate_operand (operands[1], DImode)"
1837   [(set (match_dup 0) (match_dup 1))
1838    (set (match_dup 2) (match_dup 3))]
1839   "split_di (operands + 1, 1, operands + 2, operands + 3);
1840    operands[1] = gen_lowpart (DImode, operands[2]);
1841    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1842                                                     GEN_INT (4)));
1843   ")
1844
1845 (define_insn "*pushdi2_prologue_rex64"
1846   [(set (match_operand:DI 0 "push_operand" "=<")
1847         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1848    (clobber (mem:BLK (scratch)))]
1849   "TARGET_64BIT"
1850   "push{q}\t%1"
1851   [(set_attr "type" "push")
1852    (set_attr "mode" "DI")])
1853
1854 (define_insn "*popdi1_epilogue_rex64"
1855   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1856         (mem:DI (reg:DI SP_REG)))
1857    (set (reg:DI SP_REG)
1858         (plus:DI (reg:DI SP_REG) (const_int 8)))
1859    (clobber (mem:BLK (scratch)))]
1860   "TARGET_64BIT"
1861   "pop{q}\t%0"
1862   [(set_attr "type" "pop")
1863    (set_attr "mode" "DI")])
1864
1865 (define_insn "popdi1"
1866   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1867         (mem:DI (reg:DI SP_REG)))
1868    (set (reg:DI SP_REG)
1869         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1870   "TARGET_64BIT"
1871   "pop{q}\t%0"
1872   [(set_attr "type" "pop")
1873    (set_attr "mode" "DI")])
1874
1875 (define_insn "*movdi_xor_rex64"
1876   [(set (match_operand:DI 0 "register_operand" "=r")
1877         (match_operand:DI 1 "const0_operand" "i"))
1878    (clobber (reg:CC FLAGS_REG))]
1879   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1880    && reload_completed"
1881   "xor{l}\t{%k0, %k0|%k0, %k0}"
1882   [(set_attr "type" "alu1")
1883    (set_attr "mode" "SI")
1884    (set_attr "length_immediate" "0")])
1885
1886 (define_insn "*movdi_or_rex64"
1887   [(set (match_operand:DI 0 "register_operand" "=r")
1888         (match_operand:DI 1 "const_int_operand" "i"))
1889    (clobber (reg:CC FLAGS_REG))]
1890   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1891    && reload_completed
1892    && operands[1] == constm1_rtx"
1893 {
1894   operands[1] = constm1_rtx;
1895   return "or{q}\t{%1, %0|%0, %1}";
1896 }
1897   [(set_attr "type" "alu1")
1898    (set_attr "mode" "DI")
1899    (set_attr "length_immediate" "1")])
1900
1901 (define_insn "*movdi_2"
1902   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*x,!*x")
1903         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*x,*x,m"))]
1904   "!TARGET_64BIT
1905    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1906   "@
1907    #
1908    #
1909    movq\t{%1, %0|%0, %1}
1910    movq\t{%1, %0|%0, %1}
1911    movq\t{%1, %0|%0, %1}
1912    movdqa\t{%1, %0|%0, %1}
1913    movq\t{%1, %0|%0, %1}"
1914   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1915    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1916
1917 (define_split
1918   [(set (match_operand:DI 0 "push_operand" "")
1919         (match_operand:DI 1 "general_operand" ""))]
1920   "!TARGET_64BIT && reload_completed
1921    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1922   [(const_int 0)]
1923   "ix86_split_long_move (operands); DONE;")
1924
1925 ;; %%% This multiword shite has got to go.
1926 (define_split
1927   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1928         (match_operand:DI 1 "general_operand" ""))]
1929   "!TARGET_64BIT && reload_completed
1930    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1931    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1932   [(const_int 0)]
1933   "ix86_split_long_move (operands); DONE;")
1934
1935 (define_insn "*movdi_1_rex64"
1936   [(set (match_operand:DI 0 "nonimmediate_operand"
1937                 "=r,r  ,r,mr,!mr,!*y,!rm,!*y,!*x,!rm,!*x,!*x,!*y")
1938         (match_operand:DI 1 "general_operand"
1939                 "Z ,rem,i,re,n  ,*y ,*y ,rm ,*x ,*x ,rm ,*y ,*x"))]
1940   "TARGET_64BIT
1941    && (TARGET_INTER_UNIT_MOVES || optimize_size)
1942    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1943 {
1944   switch (get_attr_type (insn))
1945     {
1946     case TYPE_SSECVT:
1947       if (which_alternative == 11)
1948         return "movq2dq\t{%1, %0|%0, %1}";
1949       else
1950         return "movdq2q\t{%1, %0|%0, %1}";
1951     case TYPE_SSEMOV:
1952       if (get_attr_mode (insn) == MODE_TI)
1953           return "movdqa\t{%1, %0|%0, %1}";
1954       /* FALLTHRU */
1955     case TYPE_MMXMOV:
1956       /* Moves from and into integer register is done using movd opcode with
1957          REX prefix.  */
1958       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1959           return "movd\t{%1, %0|%0, %1}";
1960       return "movq\t{%1, %0|%0, %1}";
1961     case TYPE_MULTI:
1962       return "#";
1963     case TYPE_LEA:
1964       return "lea{q}\t{%a1, %0|%0, %a1}";
1965     default:
1966       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1967         abort ();
1968       if (get_attr_mode (insn) == MODE_SI)
1969         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1970       else if (which_alternative == 2)
1971         return "movabs{q}\t{%1, %0|%0, %1}";
1972       else
1973         return "mov{q}\t{%1, %0|%0, %1}";
1974     }
1975 }
1976   [(set (attr "type")
1977      (cond [(eq_attr "alternative" "5,6,7")
1978               (const_string "mmxmov")
1979             (eq_attr "alternative" "8,9,10")
1980               (const_string "ssemov")
1981             (eq_attr "alternative" "11,12")
1982               (const_string "ssecvt")
1983             (eq_attr "alternative" "4")
1984               (const_string "multi")
1985             (and (ne (symbol_ref "flag_pic") (const_int 0))
1986                  (match_operand:DI 1 "symbolic_operand" ""))
1987               (const_string "lea")
1988            ]
1989            (const_string "imov")))
1990    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
1991    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
1992    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
1993
1994 (define_insn "*movdi_1_rex64_nointerunit"
1995   [(set (match_operand:DI 0 "nonimmediate_operand"
1996                 "=r,r ,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
1997         (match_operand:DI 1 "general_operand"
1998                 "Z,rem,i,re,n  ,*y ,*y,m  ,*Y ,*Y,m"))]
1999   "TARGET_64BIT
2000    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2001    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2002 {
2003   switch (get_attr_type (insn))
2004     {
2005     case TYPE_SSEMOV:
2006       if (get_attr_mode (insn) == MODE_TI)
2007           return "movdqa\t{%1, %0|%0, %1}";
2008       /* FALLTHRU */
2009     case TYPE_MMXMOV:
2010       return "movq\t{%1, %0|%0, %1}";
2011     case TYPE_MULTI:
2012       return "#";
2013     case TYPE_LEA:
2014       return "lea{q}\t{%a1, %0|%0, %a1}";
2015     default:
2016       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2017         abort ();
2018       if (get_attr_mode (insn) == MODE_SI)
2019         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2020       else if (which_alternative == 2)
2021         return "movabs{q}\t{%1, %0|%0, %1}";
2022       else
2023         return "mov{q}\t{%1, %0|%0, %1}";
2024     }
2025 }
2026   [(set (attr "type")
2027      (cond [(eq_attr "alternative" "5,6,7")
2028               (const_string "mmxmov")
2029             (eq_attr "alternative" "8,9,10")
2030               (const_string "ssemov")
2031             (eq_attr "alternative" "4")
2032               (const_string "multi")
2033             (and (ne (symbol_ref "flag_pic") (const_int 0))
2034                  (match_operand:DI 1 "symbolic_operand" ""))
2035               (const_string "lea")
2036            ]
2037            (const_string "imov")))
2038    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2039    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2040    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2041
2042 ;; Stores and loads of ax to arbitrary constant address.
2043 ;; We fake an second form of instruction to force reload to load address
2044 ;; into register when rax is not available
2045 (define_insn "*movabsdi_1_rex64"
2046   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2047         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2048   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2049   "@
2050    movabs{q}\t{%1, %P0|%P0, %1}
2051    mov{q}\t{%1, %a0|%a0, %1}"
2052   [(set_attr "type" "imov")
2053    (set_attr "modrm" "0,*")
2054    (set_attr "length_address" "8,0")
2055    (set_attr "length_immediate" "0,*")
2056    (set_attr "memory" "store")
2057    (set_attr "mode" "DI")])
2058
2059 (define_insn "*movabsdi_2_rex64"
2060   [(set (match_operand:DI 0 "register_operand" "=a,r")
2061         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2062   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2063   "@
2064    movabs{q}\t{%P1, %0|%0, %P1}
2065    mov{q}\t{%a1, %0|%0, %a1}"
2066   [(set_attr "type" "imov")
2067    (set_attr "modrm" "0,*")
2068    (set_attr "length_address" "8,0")
2069    (set_attr "length_immediate" "0")
2070    (set_attr "memory" "load")
2071    (set_attr "mode" "DI")])
2072
2073 ;; Convert impossible stores of immediate to existing instructions.
2074 ;; First try to get scratch register and go through it.  In case this
2075 ;; fails, move by 32bit parts.
2076 (define_peephole2
2077   [(match_scratch:DI 2 "r")
2078    (set (match_operand:DI 0 "memory_operand" "")
2079         (match_operand:DI 1 "immediate_operand" ""))]
2080   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2081    && !x86_64_immediate_operand (operands[1], DImode)"
2082   [(set (match_dup 2) (match_dup 1))
2083    (set (match_dup 0) (match_dup 2))]
2084   "")
2085
2086 ;; We need to define this as both peepholer and splitter for case
2087 ;; peephole2 pass is not run.
2088 ;; "&& 1" is needed to keep it from matching the previous pattern.
2089 (define_peephole2
2090   [(set (match_operand:DI 0 "memory_operand" "")
2091         (match_operand:DI 1 "immediate_operand" ""))]
2092   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2093    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2094   [(set (match_dup 2) (match_dup 3))
2095    (set (match_dup 4) (match_dup 5))]
2096   "split_di (operands, 2, operands + 2, operands + 4);")
2097
2098 (define_split
2099   [(set (match_operand:DI 0 "memory_operand" "")
2100         (match_operand:DI 1 "immediate_operand" ""))]
2101   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2102    && !symbolic_operand (operands[1], DImode)
2103    && !x86_64_immediate_operand (operands[1], DImode)"
2104   [(set (match_dup 2) (match_dup 3))
2105    (set (match_dup 4) (match_dup 5))]
2106   "split_di (operands, 2, operands + 2, operands + 4);")
2107
2108 (define_insn "*swapdi_rex64"
2109   [(set (match_operand:DI 0 "register_operand" "+r")
2110         (match_operand:DI 1 "register_operand" "+r"))
2111    (set (match_dup 1)
2112         (match_dup 0))]
2113   "TARGET_64BIT"
2114   "xchg{q}\t%1, %0"
2115   [(set_attr "type" "imov")
2116    (set_attr "mode" "DI")
2117    (set_attr "pent_pair" "np")
2118    (set_attr "athlon_decode" "vector")])
2119
2120 (define_expand "movsf"
2121   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2122         (match_operand:SF 1 "general_operand" ""))]
2123   ""
2124   "ix86_expand_move (SFmode, operands); DONE;")
2125
2126 (define_insn "*pushsf"
2127   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2128         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2129   "!TARGET_64BIT"
2130 {
2131   switch (which_alternative)
2132     {
2133     case 1:
2134       return "push{l}\t%1";
2135
2136     default:
2137       /* This insn should be already split before reg-stack.  */
2138       abort ();
2139     }
2140 }
2141   [(set_attr "type" "multi,push,multi")
2142    (set_attr "mode" "SF,SI,SF")])
2143
2144 (define_insn "*pushsf_rex64"
2145   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2146         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2147   "TARGET_64BIT"
2148 {
2149   switch (which_alternative)
2150     {
2151     case 1:
2152       return "push{q}\t%q1";
2153
2154     default:
2155       /* This insn should be already split before reg-stack.  */
2156       abort ();
2157     }
2158 }
2159   [(set_attr "type" "multi,push,multi")
2160    (set_attr "mode" "SF,DI,SF")])
2161
2162 (define_split
2163   [(set (match_operand:SF 0 "push_operand" "")
2164         (match_operand:SF 1 "memory_operand" ""))]
2165   "reload_completed
2166    && GET_CODE (operands[1]) == MEM
2167    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2168    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2169   [(set (match_dup 0)
2170         (match_dup 1))]
2171   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2172
2173
2174 ;; %%% Kill this when call knows how to work this out.
2175 (define_split
2176   [(set (match_operand:SF 0 "push_operand" "")
2177         (match_operand:SF 1 "any_fp_register_operand" ""))]
2178   "!TARGET_64BIT"
2179   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2180    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2181
2182 (define_split
2183   [(set (match_operand:SF 0 "push_operand" "")
2184         (match_operand:SF 1 "any_fp_register_operand" ""))]
2185   "TARGET_64BIT"
2186   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2187    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2188
2189 (define_insn "*movsf_1"
2190   [(set (match_operand:SF 0 "nonimmediate_operand"
2191           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2192         (match_operand:SF 1 "general_operand"
2193           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2194   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2195    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2196    && (reload_in_progress || reload_completed
2197        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2198        || GET_CODE (operands[1]) != CONST_DOUBLE
2199        || memory_operand (operands[0], SFmode))" 
2200 {
2201   switch (which_alternative)
2202     {
2203     case 0:
2204       return output_387_reg_move (insn, operands);
2205
2206     case 1:
2207       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2208         return "fstp%z0\t%y0";
2209       else
2210         return "fst%z0\t%y0";
2211
2212     case 2:
2213       return standard_80387_constant_opcode (operands[1]);
2214
2215     case 3:
2216     case 4:
2217       return "mov{l}\t{%1, %0|%0, %1}";
2218     case 5:
2219       if (get_attr_mode (insn) == MODE_TI)
2220         return "pxor\t%0, %0";
2221       else
2222         return "xorps\t%0, %0";
2223     case 6:
2224       if (get_attr_mode (insn) == MODE_V4SF)
2225         return "movaps\t{%1, %0|%0, %1}";
2226       else
2227         return "movss\t{%1, %0|%0, %1}";
2228     case 7:
2229     case 8:
2230       return "movss\t{%1, %0|%0, %1}";
2231
2232     case 9:
2233     case 10:
2234       return "movd\t{%1, %0|%0, %1}";
2235
2236     case 11:
2237       return "movq\t{%1, %0|%0, %1}";
2238
2239     default:
2240       abort();
2241     }
2242 }
2243   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2244    (set (attr "mode")
2245         (cond [(eq_attr "alternative" "3,4,9,10")
2246                  (const_string "SI")
2247                (eq_attr "alternative" "5")
2248                  (if_then_else
2249                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2250                                  (const_int 0))
2251                              (ne (symbol_ref "TARGET_SSE2")
2252                                  (const_int 0)))
2253                         (eq (symbol_ref "optimize_size")
2254                             (const_int 0)))
2255                    (const_string "TI")
2256                    (const_string "V4SF"))
2257                /* For architectures resolving dependencies on
2258                   whole SSE registers use APS move to break dependency
2259                   chains, otherwise use short move to avoid extra work. 
2260
2261                   Do the same for architectures resolving dependencies on
2262                   the parts.  While in DF mode it is better to always handle
2263                   just register parts, the SF mode is different due to lack
2264                   of instructions to load just part of the register.  It is
2265                   better to maintain the whole registers in single format
2266                   to avoid problems on using packed logical operations.  */
2267                (eq_attr "alternative" "6")
2268                  (if_then_else
2269                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2270                             (const_int 0))
2271                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2272                             (const_int 0)))
2273                    (const_string "V4SF")
2274                    (const_string "SF"))
2275                (eq_attr "alternative" "11")
2276                  (const_string "DI")]
2277                (const_string "SF")))])
2278
2279 (define_insn "*movsf_1_nointerunit"
2280   [(set (match_operand:SF 0 "nonimmediate_operand"
2281           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!m,!*y")
2282         (match_operand:SF 1 "general_operand"
2283           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,m  ,*y,*y"))]
2284   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2285    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2286    && (reload_in_progress || reload_completed
2287        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2288        || GET_CODE (operands[1]) != CONST_DOUBLE
2289        || memory_operand (operands[0], SFmode))" 
2290 {
2291   switch (which_alternative)
2292     {
2293     case 0:
2294       return output_387_reg_move (insn, operands);
2295
2296     case 1:
2297       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2298         return "fstp%z0\t%y0";
2299       else
2300         return "fst%z0\t%y0";
2301
2302     case 2:
2303       return standard_80387_constant_opcode (operands[1]);
2304
2305     case 3:
2306     case 4:
2307       return "mov{l}\t{%1, %0|%0, %1}";
2308     case 5:
2309       if (get_attr_mode (insn) == MODE_TI)
2310         return "pxor\t%0, %0";
2311       else
2312         return "xorps\t%0, %0";
2313     case 6:
2314       if (get_attr_mode (insn) == MODE_V4SF)
2315         return "movaps\t{%1, %0|%0, %1}";
2316       else
2317         return "movss\t{%1, %0|%0, %1}";
2318     case 7:
2319     case 8:
2320       return "movss\t{%1, %0|%0, %1}";
2321
2322     case 9:
2323     case 10:
2324       return "movd\t{%1, %0|%0, %1}";
2325
2326     case 11:
2327       return "movq\t{%1, %0|%0, %1}";
2328
2329     default:
2330       abort();
2331     }
2332 }
2333   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2334    (set (attr "mode")
2335         (cond [(eq_attr "alternative" "3,4,9,10")
2336                  (const_string "SI")
2337                (eq_attr "alternative" "5")
2338                  (if_then_else
2339                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2340                                  (const_int 0))
2341                              (ne (symbol_ref "TARGET_SSE2")
2342                                  (const_int 0)))
2343                         (eq (symbol_ref "optimize_size")
2344                             (const_int 0)))
2345                    (const_string "TI")
2346                    (const_string "V4SF"))
2347                /* For architectures resolving dependencies on
2348                   whole SSE registers use APS move to break dependency
2349                   chains, otherwise use short move to avoid extra work. 
2350
2351                   Do the same for architectures resolving dependencies on
2352                   the parts.  While in DF mode it is better to always handle
2353                   just register parts, the SF mode is different due to lack
2354                   of instructions to load just part of the register.  It is
2355                   better to maintain the whole registers in single format
2356                   to avoid problems on using packed logical operations.  */
2357                (eq_attr "alternative" "6")
2358                  (if_then_else
2359                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2360                             (const_int 0))
2361                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2362                             (const_int 0)))
2363                    (const_string "V4SF")
2364                    (const_string "SF"))
2365                (eq_attr "alternative" "11")
2366                  (const_string "DI")]
2367                (const_string "SF")))])
2368
2369 (define_insn "*swapsf"
2370   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2371         (match_operand:SF 1 "fp_register_operand" "+f"))
2372    (set (match_dup 1)
2373         (match_dup 0))]
2374   "reload_completed || TARGET_80387"
2375 {
2376   if (STACK_TOP_P (operands[0]))
2377     return "fxch\t%1";
2378   else
2379     return "fxch\t%0";
2380 }
2381   [(set_attr "type" "fxch")
2382    (set_attr "mode" "SF")])
2383
2384 (define_expand "movdf"
2385   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2386         (match_operand:DF 1 "general_operand" ""))]
2387   ""
2388   "ix86_expand_move (DFmode, operands); DONE;")
2389
2390 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2391 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2392 ;; On the average, pushdf using integers can be still shorter.  Allow this
2393 ;; pattern for optimize_size too.
2394
2395 (define_insn "*pushdf_nointeger"
2396   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2397         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2398   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2399 {
2400   /* This insn should be already split before reg-stack.  */
2401   abort ();
2402 }
2403   [(set_attr "type" "multi")
2404    (set_attr "mode" "DF,SI,SI,DF")])
2405
2406 (define_insn "*pushdf_integer"
2407   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2408         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2409   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2410 {
2411   /* This insn should be already split before reg-stack.  */
2412   abort ();
2413 }
2414   [(set_attr "type" "multi")
2415    (set_attr "mode" "DF,SI,DF")])
2416
2417 ;; %%% Kill this when call knows how to work this out.
2418 (define_split
2419   [(set (match_operand:DF 0 "push_operand" "")
2420         (match_operand:DF 1 "any_fp_register_operand" ""))]
2421   "!TARGET_64BIT && reload_completed"
2422   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2423    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2424   "")
2425
2426 (define_split
2427   [(set (match_operand:DF 0 "push_operand" "")
2428         (match_operand:DF 1 "any_fp_register_operand" ""))]
2429   "TARGET_64BIT && reload_completed"
2430   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2431    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2432   "")
2433
2434 (define_split
2435   [(set (match_operand:DF 0 "push_operand" "")
2436         (match_operand:DF 1 "general_operand" ""))]
2437   "reload_completed"
2438   [(const_int 0)]
2439   "ix86_split_long_move (operands); DONE;")
2440
2441 ;; Moving is usually shorter when only FP registers are used. This separate
2442 ;; movdf pattern avoids the use of integer registers for FP operations
2443 ;; when optimizing for size.
2444
2445 (define_insn "*movdf_nointeger"
2446   [(set (match_operand:DF 0 "nonimmediate_operand"
2447                                 "=f#x,m  ,f#x,*r  ,o  ,x#f,x#f,x#f  ,m")
2448         (match_operand:DF 1 "general_operand"
2449                                 "fm#x,f#x,G  ,*roF,F*r,C  ,x#f,xHm#f,x#f"))]
2450   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2451    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2452    && (reload_in_progress || reload_completed
2453        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2454        || GET_CODE (operands[1]) != CONST_DOUBLE
2455        || memory_operand (operands[0], DFmode))" 
2456 {
2457   switch (which_alternative)
2458     {
2459     case 0:
2460       return output_387_reg_move (insn, operands);
2461
2462     case 1:
2463       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2464         return "fstp%z0\t%y0";
2465       else
2466         return "fst%z0\t%y0";
2467
2468     case 2:
2469       return standard_80387_constant_opcode (operands[1]);
2470
2471     case 3:
2472     case 4:
2473       return "#";
2474     case 5:
2475       switch (get_attr_mode (insn))
2476         {
2477         case MODE_V4SF:
2478           return "xorps\t%0, %0";
2479         case MODE_V2DF:
2480           return "xorpd\t%0, %0";
2481         case MODE_TI:
2482           return "pxor\t%0, %0";
2483         default:
2484           abort ();
2485         }
2486     case 6:
2487     case 7:
2488     case 8:
2489       switch (get_attr_mode (insn))
2490         {
2491         case MODE_V4SF:
2492           return "movaps\t{%1, %0|%0, %1}";
2493         case MODE_V2DF:
2494           return "movapd\t{%1, %0|%0, %1}";
2495         case MODE_TI:
2496           return "movdqa\t{%1, %0|%0, %1}";
2497         case MODE_DI:
2498           return "movq\t{%1, %0|%0, %1}";
2499         case MODE_DF:
2500           return "movsd\t{%1, %0|%0, %1}";
2501         case MODE_V1DF:
2502           return "movlpd\t{%1, %0|%0, %1}";
2503         default:
2504           abort ();
2505         }
2506
2507     default:
2508       abort();
2509     }
2510 }
2511   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2512    (set (attr "mode")
2513         (cond [(eq_attr "alternative" "3,4")
2514                  (const_string "SI")
2515
2516                /* For SSE1, we have many fewer alternatives.  */
2517                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2518                  (cond [(eq_attr "alternative" "5,6")
2519                           (if_then_else
2520                             (ne (symbol_ref "optimize_size") (const_int 0))
2521                             (const_string "V4SF")
2522                             (const_string "TI"))
2523                        ]
2524                    (const_string "DI"))
2525
2526                /* xorps is one byte shorter.  */
2527                (eq_attr "alternative" "5")
2528                  (cond [(ne (symbol_ref "optimize_size")
2529                             (const_int 0))
2530                           (const_string "V4SF")
2531                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2532                             (const_int 0))
2533                           (const_string "TI")
2534                        ]
2535                        (const_string "V2DF"))
2536
2537                /* For architectures resolving dependencies on
2538                   whole SSE registers use APD move to break dependency
2539                   chains, otherwise use short move to avoid extra work.
2540
2541                   movaps encodes one byte shorter.  */
2542                (eq_attr "alternative" "6")
2543                  (cond
2544                    [(ne (symbol_ref "optimize_size")
2545                         (const_int 0))
2546                       (const_string "V4SF")
2547                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2548                         (const_int 0))
2549                       (const_string "V2DF")
2550                    ]
2551                    (const_string "DF"))
2552                /* For architectures resolving dependencies on register
2553                   parts we may avoid extra work to zero out upper part
2554                   of register.  */
2555                (eq_attr "alternative" "7")
2556                  (if_then_else
2557                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2558                        (const_int 0))
2559                    (const_string "V1DF")
2560                    (const_string "DF"))
2561               ]
2562               (const_string "DF")))])
2563
2564 (define_insn "*movdf_integer"
2565   [(set (match_operand:DF 0 "nonimmediate_operand"
2566                         "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y#rf,Y#rf,Y#rf ,m")
2567         (match_operand:DF 1 "general_operand"
2568                         "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C   ,Y#rf,Ym#rf,Y#rf"))]
2569   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2570    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2571    && (reload_in_progress || reload_completed
2572        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2573        || GET_CODE (operands[1]) != CONST_DOUBLE
2574        || memory_operand (operands[0], DFmode))" 
2575 {
2576   switch (which_alternative)
2577     {
2578     case 0:
2579       return output_387_reg_move (insn, operands);
2580
2581     case 1:
2582       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2583         return "fstp%z0\t%y0";
2584       else
2585         return "fst%z0\t%y0";
2586
2587     case 2:
2588       return standard_80387_constant_opcode (operands[1]);
2589
2590     case 3:
2591     case 4:
2592       return "#";
2593
2594     case 5:
2595       switch (get_attr_mode (insn))
2596         {
2597         case MODE_V4SF:
2598           return "xorps\t%0, %0";
2599         case MODE_V2DF:
2600           return "xorpd\t%0, %0";
2601         case MODE_TI:
2602           return "pxor\t%0, %0";
2603         default:
2604           abort ();
2605         }
2606     case 6:
2607     case 7:
2608     case 8:
2609       switch (get_attr_mode (insn))
2610         {
2611         case MODE_V4SF:
2612           return "movaps\t{%1, %0|%0, %1}";
2613         case MODE_V2DF:
2614           return "movapd\t{%1, %0|%0, %1}";
2615         case MODE_TI:
2616           return "movdqa\t{%1, %0|%0, %1}";
2617         case MODE_DI:
2618           return "movq\t{%1, %0|%0, %1}";
2619         case MODE_DF:
2620           return "movsd\t{%1, %0|%0, %1}";
2621         case MODE_V1DF:
2622           return "movlpd\t{%1, %0|%0, %1}";
2623         default:
2624           abort ();
2625         }
2626
2627     default:
2628       abort();
2629     }
2630 }
2631   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2632    (set (attr "mode")
2633         (cond [(eq_attr "alternative" "3,4")
2634                  (const_string "SI")
2635
2636                /* For SSE1, we have many fewer alternatives.  */
2637                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2638                  (cond [(eq_attr "alternative" "5,6")
2639                           (if_then_else
2640                             (ne (symbol_ref "optimize_size") (const_int 0))
2641                             (const_string "V4SF")
2642                             (const_string "TI"))
2643                        ]
2644                    (const_string "DI"))
2645
2646                /* xorps is one byte shorter.  */
2647                (eq_attr "alternative" "5")
2648                  (cond [(ne (symbol_ref "optimize_size")
2649                             (const_int 0))
2650                           (const_string "V4SF")
2651                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2652                             (const_int 0))
2653                           (const_string "TI")
2654                        ]
2655                        (const_string "V2DF"))
2656
2657                /* For architectures resolving dependencies on
2658                   whole SSE registers use APD move to break dependency
2659                   chains, otherwise use short move to avoid extra work.
2660
2661                   movaps encodes one byte shorter.  */
2662                (eq_attr "alternative" "6")
2663                  (cond
2664                    [(ne (symbol_ref "optimize_size")
2665                         (const_int 0))
2666                       (const_string "V4SF")
2667                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2668                         (const_int 0))
2669                       (const_string "V2DF")
2670                    ]
2671                    (const_string "DF"))
2672                /* For architectures resolving dependencies on register
2673                   parts we may avoid extra work to zero out upper part
2674                   of register.  */
2675                (eq_attr "alternative" "7")
2676                  (if_then_else
2677                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2678                        (const_int 0))
2679                    (const_string "V1DF")
2680                    (const_string "DF"))
2681               ]
2682               (const_string "DF")))])
2683
2684 (define_split
2685   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2686         (match_operand:DF 1 "general_operand" ""))]
2687   "reload_completed
2688    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2689    && ! (ANY_FP_REG_P (operands[0]) || 
2690          (GET_CODE (operands[0]) == SUBREG
2691           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2692    && ! (ANY_FP_REG_P (operands[1]) || 
2693          (GET_CODE (operands[1]) == SUBREG
2694           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2695   [(const_int 0)]
2696   "ix86_split_long_move (operands); DONE;")
2697
2698 (define_insn "*swapdf"
2699   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2700         (match_operand:DF 1 "fp_register_operand" "+f"))
2701    (set (match_dup 1)
2702         (match_dup 0))]
2703   "reload_completed || TARGET_80387"
2704 {
2705   if (STACK_TOP_P (operands[0]))
2706     return "fxch\t%1";
2707   else
2708     return "fxch\t%0";
2709 }
2710   [(set_attr "type" "fxch")
2711    (set_attr "mode" "DF")])
2712
2713 (define_expand "movxf"
2714   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2715         (match_operand:XF 1 "general_operand" ""))]
2716   ""
2717   "ix86_expand_move (XFmode, operands); DONE;")
2718
2719 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2720 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2721 ;; Pushing using integer instructions is longer except for constants
2722 ;; and direct memory references.
2723 ;; (assuming that any given constant is pushed only once, but this ought to be
2724 ;;  handled elsewhere).
2725
2726 (define_insn "*pushxf_nointeger"
2727   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2728         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2729   "optimize_size"
2730 {
2731   /* This insn should be already split before reg-stack.  */
2732   abort ();
2733 }
2734   [(set_attr "type" "multi")
2735    (set_attr "mode" "XF,SI,SI")])
2736
2737 (define_insn "*pushxf_integer"
2738   [(set (match_operand:XF 0 "push_operand" "=<,<")
2739         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2740   "!optimize_size"
2741 {
2742   /* This insn should be already split before reg-stack.  */
2743   abort ();
2744 }
2745   [(set_attr "type" "multi")
2746    (set_attr "mode" "XF,SI")])
2747
2748 (define_split
2749   [(set (match_operand 0 "push_operand" "")
2750         (match_operand 1 "general_operand" ""))]
2751   "reload_completed
2752    && (GET_MODE (operands[0]) == XFmode
2753        || GET_MODE (operands[0]) == DFmode)
2754    && !ANY_FP_REG_P (operands[1])"
2755   [(const_int 0)]
2756   "ix86_split_long_move (operands); DONE;")
2757
2758 (define_split
2759   [(set (match_operand:XF 0 "push_operand" "")
2760         (match_operand:XF 1 "any_fp_register_operand" ""))]
2761   "!TARGET_64BIT"
2762   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2763    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2764   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2765
2766 (define_split
2767   [(set (match_operand:XF 0 "push_operand" "")
2768         (match_operand:XF 1 "any_fp_register_operand" ""))]
2769   "TARGET_64BIT"
2770   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2771    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2772   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2773
2774 ;; Do not use integer registers when optimizing for size
2775 (define_insn "*movxf_nointeger"
2776   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2777         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2778   "optimize_size
2779    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2780    && (reload_in_progress || reload_completed
2781        || GET_CODE (operands[1]) != CONST_DOUBLE
2782        || memory_operand (operands[0], XFmode))" 
2783 {
2784   switch (which_alternative)
2785     {
2786     case 0:
2787       return output_387_reg_move (insn, operands);
2788
2789     case 1:
2790       /* There is no non-popping store to memory for XFmode.  So if
2791          we need one, follow the store with a load.  */
2792       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2793         return "fstp%z0\t%y0\;fld%z0\t%y0";
2794       else
2795         return "fstp%z0\t%y0";
2796
2797     case 2:
2798       return standard_80387_constant_opcode (operands[1]);
2799
2800     case 3: case 4:
2801       return "#";
2802     }
2803   abort();
2804 }
2805   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2806    (set_attr "mode" "XF,XF,XF,SI,SI")])
2807
2808 (define_insn "*movxf_integer"
2809   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2810         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2811   "!optimize_size
2812    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2813    && (reload_in_progress || reload_completed
2814        || GET_CODE (operands[1]) != CONST_DOUBLE
2815        || memory_operand (operands[0], XFmode))" 
2816 {
2817   switch (which_alternative)
2818     {
2819     case 0:
2820       return output_387_reg_move (insn, operands);
2821
2822     case 1:
2823       /* There is no non-popping store to memory for XFmode.  So if
2824          we need one, follow the store with a load.  */
2825       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2826         return "fstp%z0\t%y0\;fld%z0\t%y0";
2827       else
2828         return "fstp%z0\t%y0";
2829
2830     case 2:
2831       return standard_80387_constant_opcode (operands[1]);
2832
2833     case 3: case 4:
2834       return "#";
2835     }
2836   abort();
2837 }
2838   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2839    (set_attr "mode" "XF,XF,XF,SI,SI")])
2840
2841 (define_split
2842   [(set (match_operand 0 "nonimmediate_operand" "")
2843         (match_operand 1 "general_operand" ""))]
2844   "reload_completed
2845    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2846    && GET_MODE (operands[0]) == XFmode
2847    && ! (ANY_FP_REG_P (operands[0]) || 
2848          (GET_CODE (operands[0]) == SUBREG
2849           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2850    && ! (ANY_FP_REG_P (operands[1]) || 
2851          (GET_CODE (operands[1]) == SUBREG
2852           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2853   [(const_int 0)]
2854   "ix86_split_long_move (operands); DONE;")
2855
2856 (define_split
2857   [(set (match_operand 0 "register_operand" "")
2858         (match_operand 1 "memory_operand" ""))]
2859   "reload_completed
2860    && GET_CODE (operands[1]) == MEM
2861    && (GET_MODE (operands[0]) == XFmode
2862        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2863    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2864    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2865   [(set (match_dup 0) (match_dup 1))]
2866 {
2867   rtx c = get_pool_constant (XEXP (operands[1], 0));
2868   rtx r = operands[0];
2869
2870   if (GET_CODE (r) == SUBREG)
2871     r = SUBREG_REG (r);
2872
2873   if (SSE_REG_P (r))
2874     {
2875       if (!standard_sse_constant_p (c))
2876         FAIL;
2877     }
2878   else if (FP_REG_P (r))
2879     {
2880       if (!standard_80387_constant_p (c))
2881         FAIL;
2882     }
2883   else if (MMX_REG_P (r))
2884     FAIL;
2885
2886   operands[1] = c;
2887 })
2888
2889 (define_insn "swapxf"
2890   [(set (match_operand:XF 0 "register_operand" "+f")
2891         (match_operand:XF 1 "register_operand" "+f"))
2892    (set (match_dup 1)
2893         (match_dup 0))]
2894   "TARGET_80387"
2895 {
2896   if (STACK_TOP_P (operands[0]))
2897     return "fxch\t%1";
2898   else
2899     return "fxch\t%0";
2900 }
2901   [(set_attr "type" "fxch")
2902    (set_attr "mode" "XF")])
2903 \f
2904 ;; Zero extension instructions
2905
2906 (define_expand "zero_extendhisi2"
2907   [(set (match_operand:SI 0 "register_operand" "")
2908      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2909   ""
2910 {
2911   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2912     {
2913       operands[1] = force_reg (HImode, operands[1]);
2914       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2915       DONE;
2916     }
2917 })
2918
2919 (define_insn "zero_extendhisi2_and"
2920   [(set (match_operand:SI 0 "register_operand" "=r")
2921      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2922    (clobber (reg:CC FLAGS_REG))]
2923   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2924   "#"
2925   [(set_attr "type" "alu1")
2926    (set_attr "mode" "SI")])
2927
2928 (define_split
2929   [(set (match_operand:SI 0 "register_operand" "")
2930         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2931    (clobber (reg:CC FLAGS_REG))]
2932   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2933   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2934               (clobber (reg:CC FLAGS_REG))])]
2935   "")
2936
2937 (define_insn "*zero_extendhisi2_movzwl"
2938   [(set (match_operand:SI 0 "register_operand" "=r")
2939      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2940   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2941   "movz{wl|x}\t{%1, %0|%0, %1}"
2942   [(set_attr "type" "imovx")
2943    (set_attr "mode" "SI")])
2944
2945 (define_expand "zero_extendqihi2"
2946   [(parallel
2947     [(set (match_operand:HI 0 "register_operand" "")
2948        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2949      (clobber (reg:CC FLAGS_REG))])]
2950   ""
2951   "")
2952
2953 (define_insn "*zero_extendqihi2_and"
2954   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2955      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2956    (clobber (reg:CC FLAGS_REG))]
2957   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2958   "#"
2959   [(set_attr "type" "alu1")
2960    (set_attr "mode" "HI")])
2961
2962 (define_insn "*zero_extendqihi2_movzbw_and"
2963   [(set (match_operand:HI 0 "register_operand" "=r,r")
2964      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2965    (clobber (reg:CC FLAGS_REG))]
2966   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2967   "#"
2968   [(set_attr "type" "imovx,alu1")
2969    (set_attr "mode" "HI")])
2970
2971 (define_insn "*zero_extendqihi2_movzbw"
2972   [(set (match_operand:HI 0 "register_operand" "=r")
2973      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2974   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2975   "movz{bw|x}\t{%1, %0|%0, %1}"
2976   [(set_attr "type" "imovx")
2977    (set_attr "mode" "HI")])
2978
2979 ;; For the movzbw case strip only the clobber
2980 (define_split
2981   [(set (match_operand:HI 0 "register_operand" "")
2982         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2983    (clobber (reg:CC FLAGS_REG))]
2984   "reload_completed 
2985    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2986    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2987   [(set (match_operand:HI 0 "register_operand" "")
2988         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2989
2990 ;; When source and destination does not overlap, clear destination
2991 ;; first and then do the movb
2992 (define_split
2993   [(set (match_operand:HI 0 "register_operand" "")
2994         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2995    (clobber (reg:CC FLAGS_REG))]
2996   "reload_completed
2997    && ANY_QI_REG_P (operands[0])
2998    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2999    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3000   [(set (match_dup 0) (const_int 0))
3001    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3002   "operands[2] = gen_lowpart (QImode, operands[0]);")
3003
3004 ;; Rest is handled by single and.
3005 (define_split
3006   [(set (match_operand:HI 0 "register_operand" "")
3007         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3008    (clobber (reg:CC FLAGS_REG))]
3009   "reload_completed
3010    && true_regnum (operands[0]) == true_regnum (operands[1])"
3011   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3012               (clobber (reg:CC FLAGS_REG))])]
3013   "")
3014
3015 (define_expand "zero_extendqisi2"
3016   [(parallel
3017     [(set (match_operand:SI 0 "register_operand" "")
3018        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3019      (clobber (reg:CC FLAGS_REG))])]
3020   ""
3021   "")
3022
3023 (define_insn "*zero_extendqisi2_and"
3024   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3025      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3026    (clobber (reg:CC FLAGS_REG))]
3027   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3028   "#"
3029   [(set_attr "type" "alu1")
3030    (set_attr "mode" "SI")])
3031
3032 (define_insn "*zero_extendqisi2_movzbw_and"
3033   [(set (match_operand:SI 0 "register_operand" "=r,r")
3034      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3035    (clobber (reg:CC FLAGS_REG))]
3036   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3037   "#"
3038   [(set_attr "type" "imovx,alu1")
3039    (set_attr "mode" "SI")])
3040
3041 (define_insn "*zero_extendqisi2_movzbw"
3042   [(set (match_operand:SI 0 "register_operand" "=r")
3043      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3044   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3045   "movz{bl|x}\t{%1, %0|%0, %1}"
3046   [(set_attr "type" "imovx")
3047    (set_attr "mode" "SI")])
3048
3049 ;; For the movzbl case strip only the clobber
3050 (define_split
3051   [(set (match_operand:SI 0 "register_operand" "")
3052         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3053    (clobber (reg:CC FLAGS_REG))]
3054   "reload_completed 
3055    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3056    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3057   [(set (match_dup 0)
3058         (zero_extend:SI (match_dup 1)))])
3059
3060 ;; When source and destination does not overlap, clear destination
3061 ;; first and then do the movb
3062 (define_split
3063   [(set (match_operand:SI 0 "register_operand" "")
3064         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3065    (clobber (reg:CC FLAGS_REG))]
3066   "reload_completed
3067    && ANY_QI_REG_P (operands[0])
3068    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3069    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3070    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3071   [(set (match_dup 0) (const_int 0))
3072    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3073   "operands[2] = gen_lowpart (QImode, operands[0]);")
3074
3075 ;; Rest is handled by single and.
3076 (define_split
3077   [(set (match_operand:SI 0 "register_operand" "")
3078         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3079    (clobber (reg:CC FLAGS_REG))]
3080   "reload_completed
3081    && true_regnum (operands[0]) == true_regnum (operands[1])"
3082   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3083               (clobber (reg:CC FLAGS_REG))])]
3084   "")
3085
3086 ;; %%% Kill me once multi-word ops are sane.
3087 (define_expand "zero_extendsidi2"
3088   [(set (match_operand:DI 0 "register_operand" "=r")
3089      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3090   ""
3091   "if (!TARGET_64BIT)
3092      {
3093        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3094        DONE;
3095      }
3096   ")
3097
3098 (define_insn "zero_extendsidi2_32"
3099   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3100         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3101    (clobber (reg:CC FLAGS_REG))]
3102   "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3103   "@
3104    #
3105    #
3106    #
3107    movd\t{%1, %0|%0, %1}
3108    movd\t{%1, %0|%0, %1}"
3109   [(set_attr "mode" "SI,SI,SI,DI,TI")
3110    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3111
3112 (define_insn "*zero_extendsidi2_32_1"
3113   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3114         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3115    (clobber (reg:CC FLAGS_REG))]
3116   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3117   "@
3118    #
3119    #
3120    #
3121    movd\t{%1, %0|%0, %1}
3122    movd\t{%1, %0|%0, %1}"
3123   [(set_attr "mode" "SI,SI,SI,DI,TI")
3124    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3125
3126 (define_insn "zero_extendsidi2_rex64"
3127   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3128      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3129   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3130   "@
3131    mov\t{%k1, %k0|%k0, %k1}
3132    #
3133    movd\t{%1, %0|%0, %1}
3134    movd\t{%1, %0|%0, %1}"
3135   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3136    (set_attr "mode" "SI,DI,DI,TI")])
3137
3138 (define_insn "*zero_extendsidi2_rex64_1"
3139   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3140      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3141   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3142   "@
3143    mov\t{%k1, %k0|%k0, %k1}
3144    #
3145    movd\t{%1, %0|%0, %1}
3146    movd\t{%1, %0|%0, %1}"
3147   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3148    (set_attr "mode" "SI,DI,SI,SI")])
3149
3150 (define_split
3151   [(set (match_operand:DI 0 "memory_operand" "")
3152      (zero_extend:DI (match_dup 0)))]
3153   "TARGET_64BIT"
3154   [(set (match_dup 4) (const_int 0))]
3155   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3156
3157 (define_split 
3158   [(set (match_operand:DI 0 "register_operand" "")
3159         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3160    (clobber (reg:CC FLAGS_REG))]
3161   "!TARGET_64BIT && reload_completed
3162    && true_regnum (operands[0]) == true_regnum (operands[1])"
3163   [(set (match_dup 4) (const_int 0))]
3164   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3165
3166 (define_split 
3167   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3168         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3169    (clobber (reg:CC FLAGS_REG))]
3170   "!TARGET_64BIT && reload_completed
3171    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3172   [(set (match_dup 3) (match_dup 1))
3173    (set (match_dup 4) (const_int 0))]
3174   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3175
3176 (define_insn "zero_extendhidi2"
3177   [(set (match_operand:DI 0 "register_operand" "=r,r")
3178      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3179   "TARGET_64BIT"
3180   "@
3181    movz{wl|x}\t{%1, %k0|%k0, %1}
3182    movz{wq|x}\t{%1, %0|%0, %1}"
3183   [(set_attr "type" "imovx")
3184    (set_attr "mode" "SI,DI")])
3185
3186 (define_insn "zero_extendqidi2"
3187   [(set (match_operand:DI 0 "register_operand" "=r,r")
3188      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3189   "TARGET_64BIT"
3190   "@
3191    movz{bl|x}\t{%1, %k0|%k0, %1}
3192    movz{bq|x}\t{%1, %0|%0, %1}"
3193   [(set_attr "type" "imovx")
3194    (set_attr "mode" "SI,DI")])
3195 \f
3196 ;; Sign extension instructions
3197
3198 (define_expand "extendsidi2"
3199   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3200                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3201               (clobber (reg:CC FLAGS_REG))
3202               (clobber (match_scratch:SI 2 ""))])]
3203   ""
3204 {
3205   if (TARGET_64BIT)
3206     {
3207       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3208       DONE;
3209     }
3210 })
3211
3212 (define_insn "*extendsidi2_1"
3213   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3214         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3215    (clobber (reg:CC FLAGS_REG))
3216    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3217   "!TARGET_64BIT"
3218   "#")
3219
3220 (define_insn "extendsidi2_rex64"
3221   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3222         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3223   "TARGET_64BIT"
3224   "@
3225    {cltq|cdqe}
3226    movs{lq|x}\t{%1,%0|%0, %1}"
3227   [(set_attr "type" "imovx")
3228    (set_attr "mode" "DI")
3229    (set_attr "prefix_0f" "0")
3230    (set_attr "modrm" "0,1")])
3231
3232 (define_insn "extendhidi2"
3233   [(set (match_operand:DI 0 "register_operand" "=r")
3234         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3235   "TARGET_64BIT"
3236   "movs{wq|x}\t{%1,%0|%0, %1}"
3237   [(set_attr "type" "imovx")
3238    (set_attr "mode" "DI")])
3239
3240 (define_insn "extendqidi2"
3241   [(set (match_operand:DI 0 "register_operand" "=r")
3242         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3243   "TARGET_64BIT"
3244   "movs{bq|x}\t{%1,%0|%0, %1}"
3245    [(set_attr "type" "imovx")
3246     (set_attr "mode" "DI")])
3247
3248 ;; Extend to memory case when source register does die.
3249 (define_split 
3250   [(set (match_operand:DI 0 "memory_operand" "")
3251         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3252    (clobber (reg:CC FLAGS_REG))
3253    (clobber (match_operand:SI 2 "register_operand" ""))]
3254   "(reload_completed
3255     && dead_or_set_p (insn, operands[1])
3256     && !reg_mentioned_p (operands[1], operands[0]))"
3257   [(set (match_dup 3) (match_dup 1))
3258    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3259               (clobber (reg:CC FLAGS_REG))])
3260    (set (match_dup 4) (match_dup 1))]
3261   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3262
3263 ;; Extend to memory case when source register does not die.
3264 (define_split 
3265   [(set (match_operand:DI 0 "memory_operand" "")
3266         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3267    (clobber (reg:CC FLAGS_REG))
3268    (clobber (match_operand:SI 2 "register_operand" ""))]
3269   "reload_completed"
3270   [(const_int 0)]
3271 {
3272   split_di (&operands[0], 1, &operands[3], &operands[4]);
3273
3274   emit_move_insn (operands[3], operands[1]);
3275
3276   /* Generate a cltd if possible and doing so it profitable.  */
3277   if (true_regnum (operands[1]) == 0
3278       && true_regnum (operands[2]) == 1
3279       && (optimize_size || TARGET_USE_CLTD))
3280     {
3281       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3282     }
3283   else
3284     {
3285       emit_move_insn (operands[2], operands[1]);
3286       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3287     }
3288   emit_move_insn (operands[4], operands[2]);
3289   DONE;
3290 })
3291
3292 ;; Extend to register case.  Optimize case where source and destination
3293 ;; registers match and cases where we can use cltd.
3294 (define_split 
3295   [(set (match_operand:DI 0 "register_operand" "")
3296         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3297    (clobber (reg:CC FLAGS_REG))
3298    (clobber (match_scratch:SI 2 ""))]
3299   "reload_completed"
3300   [(const_int 0)]
3301 {
3302   split_di (&operands[0], 1, &operands[3], &operands[4]);
3303
3304   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3305     emit_move_insn (operands[3], operands[1]);
3306
3307   /* Generate a cltd if possible and doing so it profitable.  */
3308   if (true_regnum (operands[3]) == 0
3309       && (optimize_size || TARGET_USE_CLTD))
3310     {
3311       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3312       DONE;
3313     }
3314
3315   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3316     emit_move_insn (operands[4], operands[1]);
3317
3318   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3319   DONE;
3320 })
3321
3322 (define_insn "extendhisi2"
3323   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3324         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3325   ""
3326 {
3327   switch (get_attr_prefix_0f (insn))
3328     {
3329     case 0:
3330       return "{cwtl|cwde}";
3331     default:
3332       return "movs{wl|x}\t{%1,%0|%0, %1}";
3333     }
3334 }
3335   [(set_attr "type" "imovx")
3336    (set_attr "mode" "SI")
3337    (set (attr "prefix_0f")
3338      ;; movsx is short decodable while cwtl is vector decoded.
3339      (if_then_else (and (eq_attr "cpu" "!k6")
3340                         (eq_attr "alternative" "0"))
3341         (const_string "0")
3342         (const_string "1")))
3343    (set (attr "modrm")
3344      (if_then_else (eq_attr "prefix_0f" "0")
3345         (const_string "0")
3346         (const_string "1")))])
3347
3348 (define_insn "*extendhisi2_zext"
3349   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3350         (zero_extend:DI
3351           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3352   "TARGET_64BIT"
3353 {
3354   switch (get_attr_prefix_0f (insn))
3355     {
3356     case 0:
3357       return "{cwtl|cwde}";
3358     default:
3359       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3360     }
3361 }
3362   [(set_attr "type" "imovx")
3363    (set_attr "mode" "SI")
3364    (set (attr "prefix_0f")
3365      ;; movsx is short decodable while cwtl is vector decoded.
3366      (if_then_else (and (eq_attr "cpu" "!k6")
3367                         (eq_attr "alternative" "0"))
3368         (const_string "0")
3369         (const_string "1")))
3370    (set (attr "modrm")
3371      (if_then_else (eq_attr "prefix_0f" "0")
3372         (const_string "0")
3373         (const_string "1")))])
3374
3375 (define_insn "extendqihi2"
3376   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3377         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3378   ""
3379 {
3380   switch (get_attr_prefix_0f (insn))
3381     {
3382     case 0:
3383       return "{cbtw|cbw}";
3384     default:
3385       return "movs{bw|x}\t{%1,%0|%0, %1}";
3386     }
3387 }
3388   [(set_attr "type" "imovx")
3389    (set_attr "mode" "HI")
3390    (set (attr "prefix_0f")
3391      ;; movsx is short decodable while cwtl is vector decoded.
3392      (if_then_else (and (eq_attr "cpu" "!k6")
3393                         (eq_attr "alternative" "0"))
3394         (const_string "0")
3395         (const_string "1")))
3396    (set (attr "modrm")
3397      (if_then_else (eq_attr "prefix_0f" "0")
3398         (const_string "0")
3399         (const_string "1")))])
3400
3401 (define_insn "extendqisi2"
3402   [(set (match_operand:SI 0 "register_operand" "=r")
3403         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3404   ""
3405   "movs{bl|x}\t{%1,%0|%0, %1}"
3406    [(set_attr "type" "imovx")
3407     (set_attr "mode" "SI")])
3408
3409 (define_insn "*extendqisi2_zext"
3410   [(set (match_operand:DI 0 "register_operand" "=r")
3411         (zero_extend:DI
3412           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3413   "TARGET_64BIT"
3414   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3415    [(set_attr "type" "imovx")
3416     (set_attr "mode" "SI")])
3417 \f
3418 ;; Conversions between float and double.
3419
3420 ;; These are all no-ops in the model used for the 80387.  So just
3421 ;; emit moves.
3422
3423 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3424 (define_insn "*dummy_extendsfdf2"
3425   [(set (match_operand:DF 0 "push_operand" "=<")
3426         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3427   "0"
3428   "#")
3429
3430 (define_split
3431   [(set (match_operand:DF 0 "push_operand" "")
3432         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3433   "!TARGET_64BIT"
3434   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3435    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3436
3437 (define_split
3438   [(set (match_operand:DF 0 "push_operand" "")
3439         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3440   "TARGET_64BIT"
3441   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3442    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3443
3444 (define_insn "*dummy_extendsfxf2"
3445   [(set (match_operand:XF 0 "push_operand" "=<")
3446         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3447   "0"
3448   "#")
3449
3450 (define_split
3451   [(set (match_operand:XF 0 "push_operand" "")
3452         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3453   ""
3454   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3455    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3456   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3457
3458 (define_split
3459   [(set (match_operand:XF 0 "push_operand" "")
3460         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3461   "TARGET_64BIT"
3462   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3463    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3464   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3465
3466 (define_split
3467   [(set (match_operand:XF 0 "push_operand" "")
3468         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3469   ""
3470   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3471    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3472   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3473
3474 (define_split
3475   [(set (match_operand:XF 0 "push_operand" "")
3476         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3477   "TARGET_64BIT"
3478   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3479    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3480   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3481
3482 (define_expand "extendsfdf2"
3483   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3484         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3485   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3486 {
3487   /* ??? Needed for compress_float_constant since all fp constants
3488      are LEGITIMATE_CONSTANT_P.  */
3489   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3490     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3491   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3492     operands[1] = force_reg (SFmode, operands[1]);
3493 })
3494
3495 (define_insn "*extendsfdf2_mixed"
3496   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3497         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3498   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3499    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3500 {
3501   switch (which_alternative)
3502     {
3503     case 0:
3504       return output_387_reg_move (insn, operands);
3505
3506     case 1:
3507       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3508         return "fstp%z0\t%y0";
3509       else
3510         return "fst%z0\t%y0";
3511
3512     case 2:
3513       return "cvtss2sd\t{%1, %0|%0, %1}";
3514
3515     default:
3516       abort ();
3517     }
3518 }
3519   [(set_attr "type" "fmov,fmov,ssecvt")
3520    (set_attr "mode" "SF,XF,DF")])
3521
3522 (define_insn "*extendsfdf2_sse"
3523   [(set (match_operand:DF 0 "register_operand" "=Y")
3524         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3525   "TARGET_SSE2 && TARGET_SSE_MATH
3526    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3527   "cvtss2sd\t{%1, %0|%0, %1}"
3528   [(set_attr "type" "ssecvt")
3529    (set_attr "mode" "DF")])
3530
3531 (define_insn "*extendsfdf2_i387"
3532   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3533         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3534   "TARGET_80387
3535    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3536 {
3537   switch (which_alternative)
3538     {
3539     case 0:
3540       return output_387_reg_move (insn, operands);
3541
3542     case 1:
3543       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3544         return "fstp%z0\t%y0";
3545       else
3546         return "fst%z0\t%y0";
3547
3548     default:
3549       abort ();
3550     }
3551 }
3552   [(set_attr "type" "fmov")
3553    (set_attr "mode" "SF,XF")])
3554
3555 (define_expand "extendsfxf2"
3556   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3557         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3558   "TARGET_80387"
3559 {
3560   /* ??? Needed for compress_float_constant since all fp constants
3561      are LEGITIMATE_CONSTANT_P.  */
3562   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3563     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3564   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3565     operands[1] = force_reg (SFmode, operands[1]);
3566 })
3567
3568 (define_insn "*extendsfxf2_i387"
3569   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3570         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3571   "TARGET_80387
3572    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3573 {
3574   switch (which_alternative)
3575     {
3576     case 0:
3577       return output_387_reg_move (insn, operands);
3578
3579     case 1:
3580       /* There is no non-popping store to memory for XFmode.  So if
3581          we need one, follow the store with a load.  */
3582       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3583         return "fstp%z0\t%y0";
3584       else
3585         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3586
3587     default:
3588       abort ();
3589     }
3590 }
3591   [(set_attr "type" "fmov")
3592    (set_attr "mode" "SF,XF")])
3593
3594 (define_expand "extenddfxf2"
3595   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3596         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3597   "TARGET_80387"
3598 {
3599   /* ??? Needed for compress_float_constant since all fp constants
3600      are LEGITIMATE_CONSTANT_P.  */
3601   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3602     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3603   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3604     operands[1] = force_reg (DFmode, operands[1]);
3605 })
3606
3607 (define_insn "*extenddfxf2_i387"
3608   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3609         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3610   "TARGET_80387
3611    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3612 {
3613   switch (which_alternative)
3614     {
3615     case 0:
3616       return output_387_reg_move (insn, operands);
3617
3618     case 1:
3619       /* There is no non-popping store to memory for XFmode.  So if
3620          we need one, follow the store with a load.  */
3621       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3622         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3623       else
3624         return "fstp%z0\t%y0";
3625
3626     default:
3627       abort ();
3628     }
3629 }
3630   [(set_attr "type" "fmov")
3631    (set_attr "mode" "DF,XF")])
3632
3633 ;; %%% This seems bad bad news.
3634 ;; This cannot output into an f-reg because there is no way to be sure
3635 ;; of truncating in that case.  Otherwise this is just like a simple move
3636 ;; insn.  So we pretend we can output to a reg in order to get better
3637 ;; register preferencing, but we really use a stack slot.
3638
3639 (define_expand "truncdfsf2"
3640   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3641                    (float_truncate:SF
3642                     (match_operand:DF 1 "register_operand" "")))
3643               (clobber (match_dup 2))])]
3644   "TARGET_80387 || TARGET_SSE2"
3645   "
3646    if (!TARGET_80387)
3647      {
3648         emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3649         DONE;
3650      }
3651    else if (flag_unsafe_math_optimizations)
3652      {
3653         rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3654         emit_insn (gen_truncdfsf2_noop (reg, operands[1]));
3655         if (reg != operands[0])
3656           emit_move_insn (operands[0], reg);
3657         DONE;
3658      }
3659    else
3660      operands[2] = assign_386_stack_local (SFmode, 0);
3661 ")
3662
3663 (define_insn "truncdfsf2_noop"
3664   [(set (match_operand:SF 0 "register_operand" "=f")
3665         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3666   "TARGET_80387 && flag_unsafe_math_optimizations"
3667 {
3668   return output_387_reg_move (insn, operands);
3669 }
3670   [(set_attr "type" "fmov")
3671    (set_attr "mode" "SF")])
3672
3673 (define_insn "*truncdfsf2_1"
3674   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3675         (float_truncate:SF
3676          (match_operand:DF 1 "register_operand" "f,f,f,f")))
3677    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3678   "TARGET_80387 && !TARGET_SSE2"
3679 {
3680   switch (which_alternative)
3681     {
3682     case 0:
3683       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3684         return "fstp%z0\t%y0";
3685       else
3686         return "fst%z0\t%y0";
3687     default:
3688       abort ();
3689     }
3690 }
3691   [(set_attr "type" "fmov,multi,multi,multi")
3692    (set_attr "mode" "SF,SF,SF,SF")])
3693
3694 (define_insn "*truncdfsf2_1_sse"
3695   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3696         (float_truncate:SF
3697          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3698    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3699   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3700 {
3701   switch (which_alternative)
3702     {
3703     case 0:
3704       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3705         return "fstp%z0\t%y0";
3706       else
3707         return "fst%z0\t%y0";
3708     case 4:
3709       return "#";
3710     default:
3711       abort ();
3712     }
3713 }
3714   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3715    (set_attr "mode" "SF,SF,SF,SF,DF")])
3716
3717 (define_insn "*truncdfsf2_1_sse_nooverlap"
3718   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3719         (float_truncate:SF
3720          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3721    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3722   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3723 {
3724   switch (which_alternative)
3725     {
3726     case 0:
3727       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3728         return "fstp%z0\t%y0";
3729       else
3730         return "fst%z0\t%y0";
3731     case 4:
3732       return "#";
3733     default:
3734       abort ();
3735     }
3736 }
3737   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3738    (set_attr "mode" "SF,SF,SF,SF,DF")])
3739
3740 (define_insn "*truncdfsf2_2"
3741   [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3742         (float_truncate:SF
3743          (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3744   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3745    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3746 {
3747   switch (which_alternative)
3748     {
3749     case 0:
3750     case 1:
3751       return "cvtsd2ss\t{%1, %0|%0, %1}";
3752     case 2:
3753       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3754         return "fstp%z0\t%y0";
3755       else
3756         return "fst%z0\t%y0";
3757     default:
3758       abort ();
3759     }
3760 }
3761   [(set_attr "type" "ssecvt,ssecvt,fmov")
3762    (set_attr "athlon_decode" "vector,double,*")
3763    (set_attr "mode" "SF,SF,SF")])
3764
3765 (define_insn "*truncdfsf2_2_nooverlap"
3766   [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3767         (float_truncate:SF
3768          (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3769   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3770    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3771 {
3772   switch (which_alternative)
3773     {
3774     case 0:
3775       return "#";
3776     case 1:
3777       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3778         return "fstp%z0\t%y0";
3779       else
3780         return "fst%z0\t%y0";
3781     default:
3782       abort ();
3783     }
3784 }
3785   [(set_attr "type" "ssecvt,fmov")
3786    (set_attr "mode" "DF,SF")])
3787
3788 (define_insn "*truncdfsf2_3"
3789   [(set (match_operand:SF 0 "memory_operand" "=m")
3790         (float_truncate:SF
3791          (match_operand:DF 1 "register_operand" "f")))]
3792   "TARGET_80387"
3793 {
3794   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3795     return "fstp%z0\t%y0";
3796   else
3797     return "fst%z0\t%y0";
3798 }
3799   [(set_attr "type" "fmov")
3800    (set_attr "mode" "SF")])
3801
3802 (define_insn "truncdfsf2_sse_only"
3803   [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3804         (float_truncate:SF
3805          (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3806   "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3807   "cvtsd2ss\t{%1, %0|%0, %1}"
3808   [(set_attr "type" "ssecvt")
3809    (set_attr "athlon_decode" "vector,double")
3810    (set_attr "mode" "SF")])
3811
3812 (define_insn "*truncdfsf2_sse_only_nooverlap"
3813   [(set (match_operand:SF 0 "register_operand" "=&Y")
3814         (float_truncate:SF
3815          (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3816   "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3817   "#"
3818   [(set_attr "type" "ssecvt")
3819    (set_attr "mode" "DF")])
3820
3821 (define_split
3822   [(set (match_operand:SF 0 "memory_operand" "")
3823         (float_truncate:SF
3824          (match_operand:DF 1 "register_operand" "")))
3825    (clobber (match_operand:SF 2 "memory_operand" ""))]
3826   "TARGET_80387"
3827   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3828   "")
3829
3830 ; Avoid possible reformatting penalty on the destination by first
3831 ; zeroing it out
3832 (define_split
3833   [(set (match_operand:SF 0 "register_operand" "")
3834         (float_truncate:SF
3835          (match_operand:DF 1 "nonimmediate_operand" "")))
3836    (clobber (match_operand 2 "" ""))]
3837   "TARGET_80387 && reload_completed
3838    && SSE_REG_P (operands[0])
3839    && !STACK_REG_P (operands[1])"
3840   [(const_int 0)]
3841 {
3842   rtx src, dest;
3843   if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3844     emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3845   else
3846     {
3847       dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3848       src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3849       /* simplify_gen_subreg refuses to widen memory references.  */
3850       if (GET_CODE (src) == SUBREG)
3851         alter_subreg (&src);
3852       if (reg_overlap_mentioned_p (operands[0], operands[1]))
3853         abort ();
3854       emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3855       emit_insn (gen_cvtsd2ss (dest, dest, src));
3856     }
3857   DONE;
3858 })
3859
3860 (define_split
3861   [(set (match_operand:SF 0 "register_operand" "")
3862         (float_truncate:SF
3863          (match_operand:DF 1 "nonimmediate_operand" "")))]
3864   "TARGET_80387 && reload_completed
3865    && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3866   [(const_int 0)]
3867 {
3868   rtx src, dest;
3869   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3870   src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3871   /* simplify_gen_subreg refuses to widen memory references.  */
3872   if (GET_CODE (src) == SUBREG)
3873     alter_subreg (&src);
3874   if (reg_overlap_mentioned_p (operands[0], operands[1]))
3875     abort ();
3876   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3877   emit_insn (gen_cvtsd2ss (dest, dest, src));
3878   DONE;
3879 })
3880
3881 (define_split
3882   [(set (match_operand:SF 0 "register_operand" "")
3883         (float_truncate:SF
3884          (match_operand:DF 1 "fp_register_operand" "")))
3885    (clobber (match_operand:SF 2 "memory_operand" ""))]
3886   "TARGET_80387 && reload_completed"
3887   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3888    (set (match_dup 0) (match_dup 2))]
3889   "")
3890
3891 (define_expand "truncxfsf2"
3892   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3893                    (float_truncate:SF
3894                     (match_operand:XF 1 "register_operand" "")))
3895               (clobber (match_dup 2))])]
3896   "TARGET_80387"
3897   "
3898   if (flag_unsafe_math_optimizations)
3899     {
3900       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3901       emit_insn (gen_truncxfsf2_noop (reg, operands[1]));
3902       if (reg != operands[0])
3903         emit_move_insn (operands[0], reg);
3904       DONE;
3905     }
3906   else
3907     operands[2] = assign_386_stack_local (SFmode, 0);
3908   ")
3909
3910 (define_insn "truncxfsf2_noop"
3911   [(set (match_operand:SF 0 "register_operand" "=f")
3912         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3913   "TARGET_80387 && flag_unsafe_math_optimizations"
3914 {
3915   return output_387_reg_move (insn, operands);
3916 }
3917   [(set_attr "type" "fmov")
3918    (set_attr "mode" "SF")])
3919
3920 (define_insn "*truncxfsf2_1"
3921   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3922         (float_truncate:SF
3923          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3924    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3925   "TARGET_80387"
3926 {
3927   switch (which_alternative)
3928     {
3929     case 0:
3930       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3931         return "fstp%z0\t%y0";
3932       else
3933         return "fst%z0\t%y0";
3934     default:
3935       abort();
3936     }
3937 }
3938   [(set_attr "type" "fmov,multi,multi,multi")
3939    (set_attr "mode" "SF")])
3940
3941 (define_insn "*truncxfsf2_2"
3942   [(set (match_operand:SF 0 "memory_operand" "=m")
3943         (float_truncate:SF
3944          (match_operand:XF 1 "register_operand" "f")))]
3945   "TARGET_80387"
3946 {
3947   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3948     return "fstp%z0\t%y0";
3949   else
3950     return "fst%z0\t%y0";
3951 }
3952   [(set_attr "type" "fmov")
3953    (set_attr "mode" "SF")])
3954
3955 (define_split
3956   [(set (match_operand:SF 0 "memory_operand" "")
3957         (float_truncate:SF
3958          (match_operand:XF 1 "register_operand" "")))
3959    (clobber (match_operand:SF 2 "memory_operand" ""))]
3960   "TARGET_80387"
3961   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3962   "")
3963
3964 (define_split
3965   [(set (match_operand:SF 0 "register_operand" "")
3966         (float_truncate:SF
3967          (match_operand:XF 1 "register_operand" "")))
3968    (clobber (match_operand:SF 2 "memory_operand" ""))]
3969   "TARGET_80387 && reload_completed"
3970   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3971    (set (match_dup 0) (match_dup 2))]
3972   "")
3973
3974 (define_expand "truncxfdf2"
3975   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3976                    (float_truncate:DF
3977                     (match_operand:XF 1 "register_operand" "")))
3978               (clobber (match_dup 2))])]
3979   "TARGET_80387"
3980   "
3981   if (flag_unsafe_math_optimizations)
3982     {
3983       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3984       emit_insn (gen_truncxfdf2_noop (reg, operands[1]));
3985       if (reg != operands[0])
3986         emit_move_insn (operands[0], reg);
3987       DONE;
3988     }
3989   else
3990     operands[2] = assign_386_stack_local (DFmode, 0);
3991   ")
3992
3993 (define_insn "truncxfdf2_noop"
3994   [(set (match_operand:DF 0 "register_operand" "=f")
3995         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3996   "TARGET_80387 && flag_unsafe_math_optimizations"
3997 {
3998   return output_387_reg_move (insn, operands);
3999 }
4000   [(set_attr "type" "fmov")
4001    (set_attr "mode" "DF")])
4002
4003 (define_insn "*truncxfdf2_1"
4004   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4005         (float_truncate:DF
4006          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4007    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4008   "TARGET_80387"
4009 {
4010   switch (which_alternative)
4011     {
4012     case 0:
4013       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4014         return "fstp%z0\t%y0";
4015       else
4016         return "fst%z0\t%y0";
4017     default:
4018       abort();
4019     }
4020   abort ();
4021 }
4022   [(set_attr "type" "fmov,multi,multi,multi")
4023    (set_attr "mode" "DF")])
4024
4025 (define_insn "*truncxfdf2_2"
4026   [(set (match_operand:DF 0 "memory_operand" "=m")
4027         (float_truncate:DF
4028           (match_operand:XF 1 "register_operand" "f")))]
4029   "TARGET_80387"
4030 {
4031   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4032     return "fstp%z0\t%y0";
4033   else
4034     return "fst%z0\t%y0";
4035 }
4036   [(set_attr "type" "fmov")
4037    (set_attr "mode" "DF")])
4038
4039 (define_split
4040   [(set (match_operand:DF 0 "memory_operand" "")
4041         (float_truncate:DF
4042          (match_operand:XF 1 "register_operand" "")))
4043    (clobber (match_operand:DF 2 "memory_operand" ""))]
4044   "TARGET_80387"
4045   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4046   "")
4047
4048 (define_split
4049   [(set (match_operand:DF 0 "register_operand" "")
4050         (float_truncate:DF
4051          (match_operand:XF 1 "register_operand" "")))
4052    (clobber (match_operand:DF 2 "memory_operand" ""))]
4053   "TARGET_80387 && reload_completed"
4054   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4055    (set (match_dup 0) (match_dup 2))]
4056   "")
4057
4058 \f
4059 ;; %%% Break up all these bad boys.
4060
4061 ;; Signed conversion to DImode.
4062
4063 (define_expand "fix_truncxfdi2"
4064   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4065                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4066               (clobber (reg:CC FLAGS_REG))])]
4067   "TARGET_80387"
4068   "")
4069
4070 (define_expand "fix_truncdfdi2"
4071   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4072                    (fix:DI (match_operand:DF 1 "register_operand" "")))
4073               (clobber (reg:CC FLAGS_REG))])]
4074   "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4075 {
4076   if (TARGET_64BIT && TARGET_SSE2)
4077    {
4078      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4079      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4080      if (out != operands[0])
4081         emit_move_insn (operands[0], out);
4082      DONE;
4083    }
4084 })
4085
4086 (define_expand "fix_truncsfdi2"
4087   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4088                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4089               (clobber (reg:CC FLAGS_REG))])] 
4090   "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4091 {
4092   if (TARGET_SSE && TARGET_64BIT)
4093    {
4094      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4095      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4096      if (out != operands[0])
4097         emit_move_insn (operands[0], out);
4098      DONE;
4099    }
4100 })
4101
4102 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4103 ;; of the machinery.
4104 (define_insn_and_split "*fix_truncdi_1"
4105   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4106         (fix:DI (match_operand 1 "register_operand" "f,f")))
4107    (clobber (reg:CC FLAGS_REG))]
4108   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4109    && !reload_completed && !reload_in_progress
4110    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4111   "#"
4112   "&& 1"
4113   [(const_int 0)]
4114 {
4115   ix86_optimize_mode_switching = 1;
4116   operands[2] = assign_386_stack_local (HImode, 1);
4117   operands[3] = assign_386_stack_local (HImode, 2);
4118   if (memory_operand (operands[0], VOIDmode))
4119     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4120                                        operands[2], operands[3]));
4121   else
4122     {
4123       operands[4] = assign_386_stack_local (DImode, 0);
4124       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4125                                            operands[2], operands[3],
4126                                            operands[4]));
4127     }
4128   DONE;
4129 }
4130   [(set_attr "type" "fistp")
4131    (set_attr "i387_cw" "trunc")
4132    (set_attr "mode" "DI")])
4133
4134 (define_insn "fix_truncdi_nomemory"
4135   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4136         (fix:DI (match_operand 1 "register_operand" "f,f")))
4137    (use (match_operand:HI 2 "memory_operand" "m,m"))
4138    (use (match_operand:HI 3 "memory_operand" "m,m"))
4139    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4140    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4141   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4142    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4143   "#"
4144   [(set_attr "type" "fistp")
4145    (set_attr "i387_cw" "trunc")
4146    (set_attr "mode" "DI")])
4147
4148 (define_insn "fix_truncdi_memory"
4149   [(set (match_operand:DI 0 "memory_operand" "=m")
4150         (fix:DI (match_operand 1 "register_operand" "f")))
4151    (use (match_operand:HI 2 "memory_operand" "m"))
4152    (use (match_operand:HI 3 "memory_operand" "m"))
4153    (clobber (match_scratch:DF 4 "=&1f"))]
4154   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4155    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4156   "* return output_fix_trunc (insn, operands);"
4157   [(set_attr "type" "fistp")
4158    (set_attr "i387_cw" "trunc")
4159    (set_attr "mode" "DI")])
4160
4161 (define_split 
4162   [(set (match_operand:DI 0 "register_operand" "")
4163         (fix:DI (match_operand 1 "register_operand" "")))
4164    (use (match_operand:HI 2 "memory_operand" ""))
4165    (use (match_operand:HI 3 "memory_operand" ""))
4166    (clobber (match_operand:DI 4 "memory_operand" ""))
4167    (clobber (match_scratch 5 ""))]
4168   "reload_completed"
4169   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4170               (use (match_dup 2))
4171               (use (match_dup 3))
4172               (clobber (match_dup 5))])
4173    (set (match_dup 0) (match_dup 4))]
4174   "")
4175
4176 (define_split 
4177   [(set (match_operand:DI 0 "memory_operand" "")
4178         (fix:DI (match_operand 1 "register_operand" "")))
4179    (use (match_operand:HI 2 "memory_operand" ""))
4180    (use (match_operand:HI 3 "memory_operand" ""))
4181    (clobber (match_operand:DI 4 "memory_operand" ""))
4182    (clobber (match_scratch 5 ""))]
4183   "reload_completed"
4184   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4185               (use (match_dup 2))
4186               (use (match_dup 3))
4187               (clobber (match_dup 5))])]
4188   "")
4189
4190 ;; When SSE available, it is always faster to use it!
4191 (define_insn "fix_truncsfdi_sse"
4192   [(set (match_operand:DI 0 "register_operand" "=r,r")
4193         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4194   "TARGET_64BIT && TARGET_SSE"
4195   "cvttss2si{q}\t{%1, %0|%0, %1}"
4196   [(set_attr "type" "sseicvt")
4197    (set_attr "mode" "SF")
4198    (set_attr "athlon_decode" "double,vector")])
4199
4200 ;; Avoid vector decoded form of the instruction.
4201 (define_peephole2
4202   [(match_scratch:SF 2 "x")
4203    (set (match_operand:DI 0 "register_operand" "")
4204         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4205   "TARGET_K8 && !optimize_size"
4206   [(set (match_dup 2) (match_dup 1))
4207    (set (match_dup 0) (fix:DI (match_dup 2)))]
4208   "")
4209
4210 (define_insn "fix_truncdfdi_sse"
4211   [(set (match_operand:DI 0 "register_operand" "=r,r")
4212         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4213   "TARGET_64BIT && TARGET_SSE2"
4214   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4215   [(set_attr "type" "sseicvt,sseicvt")
4216    (set_attr "mode" "DF")
4217    (set_attr "athlon_decode" "double,vector")])
4218
4219 ;; Avoid vector decoded form of the instruction.
4220 (define_peephole2
4221   [(match_scratch:DF 2 "Y")
4222    (set (match_operand:DI 0 "register_operand" "")
4223         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4224   "TARGET_K8 && !optimize_size"
4225   [(set (match_dup 2) (match_dup 1))
4226    (set (match_dup 0) (fix:DI (match_dup 2)))]
4227   "")
4228
4229 ;; Signed conversion to SImode.
4230
4231 (define_expand "fix_truncxfsi2"
4232   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4233                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4234               (clobber (reg:CC FLAGS_REG))])]
4235   "TARGET_80387"
4236   "")
4237
4238 (define_expand "fix_truncdfsi2"
4239   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4240                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4241               (clobber (reg:CC FLAGS_REG))])]
4242   "TARGET_80387 || TARGET_SSE2"
4243 {
4244   if (TARGET_SSE2)
4245    {
4246      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4247      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4248      if (out != operands[0])
4249         emit_move_insn (operands[0], out);
4250      DONE;
4251    }
4252 })
4253
4254 (define_expand "fix_truncsfsi2"
4255   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4256                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4257               (clobber (reg:CC FLAGS_REG))])] 
4258   "TARGET_80387 || TARGET_SSE"
4259 {
4260   if (TARGET_SSE)
4261    {
4262      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4263      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4264      if (out != operands[0])
4265         emit_move_insn (operands[0], out);
4266      DONE;
4267    }
4268 })
4269
4270 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4271 ;; of the machinery.
4272 (define_insn_and_split "*fix_truncsi_1"
4273   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4274         (fix:SI (match_operand 1 "register_operand" "f,f")))
4275    (clobber (reg:CC FLAGS_REG))]
4276   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4277    && !reload_completed && !reload_in_progress
4278    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4279   "#"
4280   "&& 1"
4281   [(const_int 0)]
4282 {
4283   ix86_optimize_mode_switching = 1;
4284   operands[2] = assign_386_stack_local (HImode, 1);
4285   operands[3] = assign_386_stack_local (HImode, 2);
4286   if (memory_operand (operands[0], VOIDmode))
4287     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4288                                        operands[2], operands[3]));
4289   else
4290     {
4291       operands[4] = assign_386_stack_local (SImode, 0);
4292       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4293                                            operands[2], operands[3],
4294                                            operands[4]));
4295     }
4296   DONE;
4297 }
4298   [(set_attr "type" "fistp")
4299    (set_attr "i387_cw" "trunc")
4300    (set_attr "mode" "SI")])
4301
4302 (define_insn "fix_truncsi_nomemory"
4303   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4304         (fix:SI (match_operand 1 "register_operand" "f,f")))
4305    (use (match_operand:HI 2 "memory_operand" "m,m"))
4306    (use (match_operand:HI 3 "memory_operand" "m,m"))
4307    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4308   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4309    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4310   "#"
4311   [(set_attr "type" "fistp")
4312    (set_attr "i387_cw" "trunc")
4313    (set_attr "mode" "SI")])
4314
4315 (define_insn "fix_truncsi_memory"
4316   [(set (match_operand:SI 0 "memory_operand" "=m")
4317         (fix:SI (match_operand 1 "register_operand" "f")))
4318    (use (match_operand:HI 2 "memory_operand" "m"))
4319    (use (match_operand:HI 3 "memory_operand" "m"))]
4320   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4321    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4322   "* return output_fix_trunc (insn, operands);"
4323   [(set_attr "type" "fistp")
4324    (set_attr "i387_cw" "trunc")
4325    (set_attr "mode" "SI")])
4326
4327 ;; When SSE available, it is always faster to use it!
4328 (define_insn "fix_truncsfsi_sse"
4329   [(set (match_operand:SI 0 "register_operand" "=r,r")
4330         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4331   "TARGET_SSE"
4332   "cvttss2si\t{%1, %0|%0, %1}"
4333   [(set_attr "type" "sseicvt")
4334    (set_attr "mode" "DF")
4335    (set_attr "athlon_decode" "double,vector")])
4336
4337 ;; Avoid vector decoded form of the instruction.
4338 (define_peephole2
4339   [(match_scratch:SF 2 "x")
4340    (set (match_operand:SI 0 "register_operand" "")
4341         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4342   "TARGET_K8 && !optimize_size"
4343   [(set (match_dup 2) (match_dup 1))
4344    (set (match_dup 0) (fix:SI (match_dup 2)))]
4345   "")
4346
4347 (define_insn "fix_truncdfsi_sse"
4348   [(set (match_operand:SI 0 "register_operand" "=r,r")
4349         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4350   "TARGET_SSE2"
4351   "cvttsd2si\t{%1, %0|%0, %1}"
4352   [(set_attr "type" "sseicvt")
4353    (set_attr "mode" "DF")
4354    (set_attr "athlon_decode" "double,vector")])
4355
4356 ;; Avoid vector decoded form of the instruction.
4357 (define_peephole2
4358   [(match_scratch:DF 2 "Y")
4359    (set (match_operand:SI 0 "register_operand" "")
4360         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4361   "TARGET_K8 && !optimize_size"
4362   [(set (match_dup 2) (match_dup 1))
4363    (set (match_dup 0) (fix:SI (match_dup 2)))]
4364   "")
4365
4366 (define_split 
4367   [(set (match_operand:SI 0 "register_operand" "")
4368         (fix:SI (match_operand 1 "register_operand" "")))
4369    (use (match_operand:HI 2 "memory_operand" ""))
4370    (use (match_operand:HI 3 "memory_operand" ""))
4371    (clobber (match_operand:SI 4 "memory_operand" ""))]
4372   "reload_completed"
4373   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4374               (use (match_dup 2))
4375               (use (match_dup 3))])
4376    (set (match_dup 0) (match_dup 4))]
4377   "")
4378
4379 (define_split 
4380   [(set (match_operand:SI 0 "memory_operand" "")
4381         (fix:SI (match_operand 1 "register_operand" "")))
4382    (use (match_operand:HI 2 "memory_operand" ""))
4383    (use (match_operand:HI 3 "memory_operand" ""))
4384    (clobber (match_operand:SI 4 "memory_operand" ""))]
4385   "reload_completed"
4386   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4387               (use (match_dup 2))
4388               (use (match_dup 3))])]
4389   "")
4390
4391 ;; Signed conversion to HImode.
4392
4393 (define_expand "fix_truncxfhi2"
4394   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4395                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4396               (clobber (reg:CC FLAGS_REG))])] 
4397   "TARGET_80387"
4398   "")
4399
4400 (define_expand "fix_truncdfhi2"
4401   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4402                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4403               (clobber (reg:CC FLAGS_REG))])]
4404   "TARGET_80387 && !TARGET_SSE2"
4405   "")
4406
4407 (define_expand "fix_truncsfhi2"
4408   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4409                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4410                (clobber (reg:CC FLAGS_REG))])]
4411   "TARGET_80387 && !TARGET_SSE"
4412   "")
4413
4414 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4415 ;; of the machinery.
4416 (define_insn_and_split "*fix_trunchi_1"
4417   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4418         (fix:HI (match_operand 1 "register_operand" "f,f")))
4419    (clobber (reg:CC FLAGS_REG))]
4420   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4421    && !reload_completed && !reload_in_progress
4422    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4423   "#"
4424   "&& 1"
4425   [(const_int 0)]
4426 {
4427   ix86_optimize_mode_switching = 1;
4428   operands[2] = assign_386_stack_local (HImode, 1);
4429   operands[3] = assign_386_stack_local (HImode, 2);
4430   if (memory_operand (operands[0], VOIDmode))
4431     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4432                                        operands[2], operands[3]));
4433   else
4434     {
4435       operands[4] = assign_386_stack_local (HImode, 0);
4436       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4437                                            operands[2], operands[3],
4438                                            operands[4]));
4439     }
4440   DONE;
4441 }
4442   [(set_attr "type" "fistp")
4443    (set_attr "i387_cw" "trunc")
4444    (set_attr "mode" "HI")])
4445
4446 (define_insn "fix_trunchi_nomemory"
4447   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4448         (fix:HI (match_operand 1 "register_operand" "f,f")))
4449    (use (match_operand:HI 2 "memory_operand" "m,m"))
4450    (use (match_operand:HI 3 "memory_operand" "m,m"))
4451    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4452   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4453    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4454   "#"
4455   [(set_attr "type" "fistp")
4456    (set_attr "i387_cw" "trunc")
4457    (set_attr "mode" "HI")])
4458
4459 (define_insn "fix_trunchi_memory"
4460   [(set (match_operand:HI 0 "memory_operand" "=m")
4461         (fix:HI (match_operand 1 "register_operand" "f")))
4462    (use (match_operand:HI 2 "memory_operand" "m"))
4463    (use (match_operand:HI 3 "memory_operand" "m"))]
4464   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4465    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4466   "* return output_fix_trunc (insn, operands);"
4467   [(set_attr "type" "fistp")
4468    (set_attr "i387_cw" "trunc")
4469    (set_attr "mode" "HI")])
4470
4471 (define_split 
4472   [(set (match_operand:HI 0 "memory_operand" "")
4473         (fix:HI (match_operand 1 "register_operand" "")))
4474    (use (match_operand:HI 2 "memory_operand" ""))
4475    (use (match_operand:HI 3 "memory_operand" ""))
4476    (clobber (match_operand:HI 4 "memory_operand" ""))]
4477   "reload_completed"
4478   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4479               (use (match_dup 2))
4480               (use (match_dup 3))])]
4481   "")
4482
4483 (define_split 
4484   [(set (match_operand:HI 0 "register_operand" "")
4485         (fix:HI (match_operand 1 "register_operand" "")))
4486    (use (match_operand:HI 2 "memory_operand" ""))
4487    (use (match_operand:HI 3 "memory_operand" ""))
4488    (clobber (match_operand:HI 4 "memory_operand" ""))]
4489   "reload_completed"
4490   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4491               (use (match_dup 2))
4492               (use (match_dup 3))
4493               (clobber (match_dup 4))])
4494    (set (match_dup 0) (match_dup 4))]
4495   "")
4496
4497 (define_insn "x86_fnstcw_1"
4498   [(set (match_operand:HI 0 "memory_operand" "=m")
4499         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4500   "TARGET_80387"
4501   "fnstcw\t%0"
4502   [(set_attr "length" "2")
4503    (set_attr "mode" "HI")
4504    (set_attr "unit" "i387")])
4505
4506 (define_insn "x86_fldcw_1"
4507   [(set (reg:HI FPSR_REG)
4508         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4509   "TARGET_80387"
4510   "fldcw\t%0"
4511   [(set_attr "length" "2")
4512    (set_attr "mode" "HI")
4513    (set_attr "unit" "i387")
4514    (set_attr "athlon_decode" "vector")])
4515 \f
4516 ;; Conversion between fixed point and floating point.
4517
4518 ;; Even though we only accept memory inputs, the backend _really_
4519 ;; wants to be able to do this between registers.
4520
4521 (define_expand "floathisf2"
4522   [(set (match_operand:SF 0 "register_operand" "")
4523         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4524   "TARGET_80387 || TARGET_SSE_MATH"
4525 {
4526   if (TARGET_SSE_MATH)
4527     {
4528       emit_insn (gen_floatsisf2 (operands[0],
4529                                  convert_to_mode (SImode, operands[1], 0)));
4530       DONE;
4531     }
4532 })
4533
4534 (define_insn "*floathisf2_i387"
4535   [(set (match_operand:SF 0 "register_operand" "=f,f")
4536         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4537   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4538   "@
4539    fild%z1\t%1
4540    #"
4541   [(set_attr "type" "fmov,multi")
4542    (set_attr "mode" "SF")
4543    (set_attr "fp_int_src" "true")])
4544
4545 (define_expand "floatsisf2"
4546   [(set (match_operand:SF 0 "register_operand" "")
4547         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4548   "TARGET_80387 || TARGET_SSE_MATH"
4549   "")
4550
4551 (define_insn "*floatsisf2_mixed"
4552   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4553         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4554   "TARGET_MIX_SSE_I387"
4555   "@
4556    fild%z1\t%1
4557    #
4558    cvtsi2ss\t{%1, %0|%0, %1}
4559    cvtsi2ss\t{%1, %0|%0, %1}"
4560   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4561    (set_attr "mode" "SF")
4562    (set_attr "athlon_decode" "*,*,vector,double")
4563    (set_attr "fp_int_src" "true")])
4564
4565 (define_insn "*floatsisf2_sse"
4566   [(set (match_operand:SF 0 "register_operand" "=x,x")
4567         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4568   "TARGET_SSE_MATH"
4569   "cvtsi2ss\t{%1, %0|%0, %1}"
4570   [(set_attr "type" "sseicvt")
4571    (set_attr "mode" "SF")
4572    (set_attr "athlon_decode" "vector,double")
4573    (set_attr "fp_int_src" "true")])
4574
4575 ; Avoid possible reformatting penalty on the destination by first
4576 ; zeroing it out
4577 (define_split
4578   [(set (match_operand:SF 0 "register_operand" "")
4579         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4580   "reload_completed
4581    && TARGET_SSE_MATH && TARGET_SSE_PARTIAL_REGS
4582    && SSE_REG_P (operands[0])"
4583   [(const_int 0)]
4584 {
4585   rtx dest;
4586   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4587   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4588   emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4589   DONE;
4590 })
4591
4592 (define_insn "*floatsisf2_i387"
4593   [(set (match_operand:SF 0 "register_operand" "=f,f")
4594         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4595   "TARGET_80387"
4596   "@
4597    fild%z1\t%1
4598    #"
4599   [(set_attr "type" "fmov,multi")
4600    (set_attr "mode" "SF")
4601    (set_attr "fp_int_src" "true")])
4602
4603 (define_expand "floatdisf2"
4604   [(set (match_operand:SF 0 "register_operand" "")
4605         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4606   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4607   "")
4608
4609 (define_insn "*floatdisf2_mixed"
4610   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4611         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4612   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4613   "@
4614    fild%z1\t%1
4615    #
4616    cvtsi2ss{q}\t{%1, %0|%0, %1}
4617    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4618   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4619    (set_attr "mode" "SF")
4620    (set_attr "athlon_decode" "*,*,vector,double")
4621    (set_attr "fp_int_src" "true")])
4622
4623 (define_insn "*floatdisf2_sse"
4624   [(set (match_operand:SF 0 "register_operand" "=x,x")
4625         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4626   "TARGET_64BIT && TARGET_SSE_MATH"
4627   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4628   [(set_attr "type" "sseicvt")
4629    (set_attr "mode" "SF")
4630    (set_attr "athlon_decode" "vector,double")
4631    (set_attr "fp_int_src" "true")])
4632
4633 ; Avoid possible reformatting penalty on the destination by first
4634 ; zeroing it out
4635 (define_split
4636   [(set (match_operand:SF 0 "register_operand" "")
4637         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4638   "reload_completed
4639    && TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE_PARTIAL_REGS
4640    && SSE_REG_P (operands[0])"
4641   [(const_int 0)]
4642 {
4643   rtx dest;
4644   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4645   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4646   emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4647   DONE;
4648 })
4649
4650 (define_insn "*floatdisf2_i387"
4651   [(set (match_operand:SF 0 "register_operand" "=f,f")
4652         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4653   "TARGET_80387"
4654   "@
4655    fild%z1\t%1
4656    #"
4657   [(set_attr "type" "fmov,multi")
4658    (set_attr "mode" "SF")
4659    (set_attr "fp_int_src" "true")])
4660
4661 (define_expand "floathidf2"
4662   [(set (match_operand:DF 0 "register_operand" "")
4663         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4664   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4665 {
4666   if (TARGET_SSE2 && TARGET_SSE_MATH)
4667     {
4668       emit_insn (gen_floatsidf2 (operands[0],
4669                                  convert_to_mode (SImode, operands[1], 0)));
4670       DONE;
4671     }
4672 })
4673
4674 (define_insn "*floathidf2_i387"
4675   [(set (match_operand:DF 0 "register_operand" "=f,f")
4676         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4677   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4678   "@
4679    fild%z1\t%1
4680    #"
4681   [(set_attr "type" "fmov,multi")
4682    (set_attr "mode" "DF")
4683    (set_attr "fp_int_src" "true")])
4684
4685 (define_expand "floatsidf2"
4686   [(set (match_operand:DF 0 "register_operand" "")
4687         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4688   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4689   "")
4690
4691 (define_insn "*floatsidf2_mixed"
4692   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4693         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4694   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4695   "@
4696    fild%z1\t%1
4697    #
4698    cvtsi2sd\t{%1, %0|%0, %1}
4699    cvtsi2sd\t{%1, %0|%0, %1}"
4700   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4701    (set_attr "mode" "DF")
4702    (set_attr "athlon_decode" "*,*,double,direct")
4703    (set_attr "fp_int_src" "true")])
4704
4705 (define_insn "*floatsidf2_sse"
4706   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4707         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4708   "TARGET_SSE2 && TARGET_SSE_MATH"
4709   "cvtsi2sd\t{%1, %0|%0, %1}"
4710   [(set_attr "type" "sseicvt")
4711    (set_attr "mode" "DF")
4712    (set_attr "athlon_decode" "double,direct")
4713    (set_attr "fp_int_src" "true")])
4714
4715 (define_insn "*floatsidf2_i387"
4716   [(set (match_operand:DF 0 "register_operand" "=f,f")
4717         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4718   "TARGET_80387"
4719   "@
4720    fild%z1\t%1
4721    #"
4722   [(set_attr "type" "fmov,multi")
4723    (set_attr "mode" "DF")
4724    (set_attr "fp_int_src" "true")])
4725
4726 (define_expand "floatdidf2"
4727   [(set (match_operand:DF 0 "register_operand" "")
4728         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4729   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4730   "")
4731
4732 (define_insn "*floatdidf2_mixed"
4733   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4734         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4735   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4736   "@
4737    fild%z1\t%1
4738    #
4739    cvtsi2sd{q}\t{%1, %0|%0, %1}
4740    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4741   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4742    (set_attr "mode" "DF")
4743    (set_attr "athlon_decode" "*,*,double,direct")
4744    (set_attr "fp_int_src" "true")])
4745
4746 (define_insn "*floatdidf2_sse"
4747   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4748         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4749   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4750   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4751   [(set_attr "type" "sseicvt")
4752    (set_attr "mode" "DF")
4753    (set_attr "athlon_decode" "double,direct")
4754    (set_attr "fp_int_src" "true")])
4755
4756 (define_insn "*floatdidf2_i387"
4757   [(set (match_operand:DF 0 "register_operand" "=f,f")
4758         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4759   "TARGET_80387"
4760   "@
4761    fild%z1\t%1
4762    #"
4763   [(set_attr "type" "fmov,multi")
4764    (set_attr "mode" "DF")
4765    (set_attr "fp_int_src" "true")])
4766
4767 (define_insn "floathixf2"
4768   [(set (match_operand:XF 0 "register_operand" "=f,f")
4769         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4770   "TARGET_80387"
4771   "@
4772    fild%z1\t%1
4773    #"
4774   [(set_attr "type" "fmov,multi")
4775    (set_attr "mode" "XF")
4776    (set_attr "fp_int_src" "true")])
4777
4778 (define_insn "floatsixf2"
4779   [(set (match_operand:XF 0 "register_operand" "=f,f")
4780         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4781   "TARGET_80387"
4782   "@
4783    fild%z1\t%1
4784    #"
4785   [(set_attr "type" "fmov,multi")
4786    (set_attr "mode" "XF")
4787    (set_attr "fp_int_src" "true")])
4788
4789 (define_insn "floatdixf2"
4790   [(set (match_operand:XF 0 "register_operand" "=f,f")
4791         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4792   "TARGET_80387"
4793   "@
4794    fild%z1\t%1
4795    #"
4796   [(set_attr "type" "fmov,multi")
4797    (set_attr "mode" "XF")
4798    (set_attr "fp_int_src" "true")])
4799
4800 ;; %%% Kill these when reload knows how to do it.
4801 (define_split
4802   [(set (match_operand 0 "fp_register_operand" "")
4803         (float (match_operand 1 "register_operand" "")))]
4804   "reload_completed
4805    && TARGET_80387
4806    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4807   [(const_int 0)]
4808 {
4809   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4810   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4811   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4812   ix86_free_from_memory (GET_MODE (operands[1]));
4813   DONE;
4814 })
4815
4816 (define_expand "floatunssisf2"
4817   [(use (match_operand:SF 0 "register_operand" ""))
4818    (use (match_operand:SI 1 "register_operand" ""))]
4819   "!TARGET_64BIT && TARGET_SSE_MATH"
4820   "x86_emit_floatuns (operands); DONE;")
4821
4822 (define_expand "floatunsdisf2"
4823   [(use (match_operand:SF 0 "register_operand" ""))
4824    (use (match_operand:DI 1 "register_operand" ""))]
4825   "TARGET_64BIT && TARGET_SSE_MATH"
4826   "x86_emit_floatuns (operands); DONE;")
4827
4828 (define_expand "floatunsdidf2"
4829   [(use (match_operand:DF 0 "register_operand" ""))
4830    (use (match_operand:DI 1 "register_operand" ""))]
4831   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4832   "x86_emit_floatuns (operands); DONE;")
4833 \f
4834 ;; SSE extract/set expanders
4835
4836 (define_expand "vec_setv2df"
4837   [(match_operand:V2DF 0 "register_operand" "")
4838    (match_operand:DF 1 "register_operand" "")
4839    (match_operand 2 "const_int_operand" "")]
4840   "TARGET_SSE2"
4841 {
4842   switch (INTVAL (operands[2]))
4843     {
4844     case 0:
4845       emit_insn (gen_sse2_movsd (operands[0], operands[0],
4846                                  simplify_gen_subreg (V2DFmode, operands[1],
4847                                                       DFmode, 0)));
4848       break;
4849     case 1:
4850       {
4851         rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4852
4853         emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4854       }
4855       break;
4856     default:
4857       abort ();
4858     }
4859   DONE;
4860 })
4861
4862 (define_expand "vec_extractv2df"
4863   [(match_operand:DF 0 "register_operand" "")
4864    (match_operand:V2DF 1 "register_operand" "")
4865    (match_operand 2 "const_int_operand" "")]
4866   "TARGET_SSE2"
4867 {
4868   switch (INTVAL (operands[2]))
4869     {
4870     case 0:
4871       emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4872       break;
4873     case 1:
4874       {
4875         rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4876
4877         emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4878       }
4879       break;
4880     default:
4881       abort ();
4882     }
4883   DONE;
4884 })
4885
4886 (define_expand "vec_initv2df"
4887   [(match_operand:V2DF 0 "register_operand" "")
4888    (match_operand 1 "" "")]
4889   "TARGET_SSE2"
4890 {
4891   ix86_expand_vector_init (operands[0], operands[1]);
4892   DONE;
4893 })
4894
4895 (define_expand "vec_setv4sf"
4896   [(match_operand:V4SF 0 "register_operand" "")
4897    (match_operand:SF 1 "register_operand" "")
4898    (match_operand 2 "const_int_operand" "")]
4899   "TARGET_SSE"
4900 {
4901   switch (INTVAL (operands[2]))
4902     {
4903     case 0:
4904       emit_insn (gen_sse_movss (operands[0], operands[0],
4905                                 simplify_gen_subreg (V4SFmode, operands[1],
4906                                                      SFmode, 0)));
4907       break;
4908     case 1:
4909       {
4910         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4911         rtx tmp = gen_reg_rtx (V4SFmode);
4912  
4913         emit_move_insn (tmp, operands[0]);
4914         emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4915         emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4916         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4917                                    GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4918       }
4919       break;
4920     case 2:
4921       {
4922         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4923         rtx tmp = gen_reg_rtx (V4SFmode);
4924
4925         emit_move_insn (tmp, operands[0]);
4926         emit_insn (gen_sse_movss (tmp, tmp, op1));
4927         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4928                                    GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4929       }
4930       break;
4931     case 3:
4932       {
4933         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4934         rtx tmp = gen_reg_rtx (V4SFmode);
4935
4936         emit_move_insn (tmp, operands[0]);
4937         emit_insn (gen_sse_movss (tmp, tmp, op1));
4938         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4939                                    GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4940       }
4941       break;
4942     default:
4943       abort ();
4944     }
4945   DONE;
4946 })
4947
4948 (define_expand "vec_extractv4sf"
4949   [(match_operand:SF 0 "register_operand" "")
4950    (match_operand:V4SF 1 "register_operand" "")
4951    (match_operand 2 "const_int_operand" "")]
4952   "TARGET_SSE"
4953 {
4954   switch (INTVAL (operands[2]))
4955     {
4956     case 0:
4957       emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4958       break;
4959     case 1:
4960       {
4961         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4962         rtx tmp = gen_reg_rtx (V4SFmode);
4963  
4964         emit_move_insn (tmp, operands[1]);
4965         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4966                                    const1_rtx));
4967       }
4968       break;
4969     case 2:
4970       {
4971         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4972         rtx tmp = gen_reg_rtx (V4SFmode);
4973  
4974         emit_move_insn (tmp, operands[1]);
4975         emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4976       }
4977       break;
4978     case 3:
4979       {
4980         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4981         rtx tmp = gen_reg_rtx (V4SFmode);
4982  
4983         emit_move_insn (tmp, operands[1]);
4984         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4985                                    GEN_INT (3)));
4986       }
4987       break;
4988     default:
4989       abort ();
4990     }
4991   DONE;
4992 })
4993
4994 (define_expand "vec_initv4sf"
4995   [(match_operand:V4SF 0 "register_operand" "")
4996    (match_operand 1 "" "")]
4997   "TARGET_SSE"
4998 {
4999   ix86_expand_vector_init (operands[0], operands[1]);
5000   DONE;
5001 })
5002 \f
5003 ;; Add instructions
5004
5005 ;; %%% splits for addsidi3
5006 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5007 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5008 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5009
5010 (define_expand "adddi3"
5011   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5012         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5013                  (match_operand:DI 2 "x86_64_general_operand" "")))
5014    (clobber (reg:CC FLAGS_REG))]
5015   ""
5016   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5017
5018 (define_insn "*adddi3_1"
5019   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5020         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5021                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5022    (clobber (reg:CC FLAGS_REG))]
5023   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5024   "#")
5025
5026 (define_split
5027   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5028         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5029                  (match_operand:DI 2 "general_operand" "")))
5030    (clobber (reg:CC FLAGS_REG))]
5031   "!TARGET_64BIT && reload_completed"
5032   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5033                                           UNSPEC_ADD_CARRY))
5034               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5035    (parallel [(set (match_dup 3)
5036                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5037                                      (match_dup 4))
5038                             (match_dup 5)))
5039               (clobber (reg:CC FLAGS_REG))])]
5040   "split_di (operands+0, 1, operands+0, operands+3);
5041    split_di (operands+1, 1, operands+1, operands+4);
5042    split_di (operands+2, 1, operands+2, operands+5);")
5043
5044 (define_insn "adddi3_carry_rex64"
5045   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5046           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5047                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5048                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5049    (clobber (reg:CC FLAGS_REG))]
5050   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5051   "adc{q}\t{%2, %0|%0, %2}"
5052   [(set_attr "type" "alu")
5053    (set_attr "pent_pair" "pu")
5054    (set_attr "mode" "DI")])
5055
5056 (define_insn "*adddi3_cc_rex64"
5057   [(set (reg:CC FLAGS_REG)
5058         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5059                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5060                    UNSPEC_ADD_CARRY))
5061    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5062         (plus:DI (match_dup 1) (match_dup 2)))]
5063   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5064   "add{q}\t{%2, %0|%0, %2}"
5065   [(set_attr "type" "alu")
5066    (set_attr "mode" "DI")])
5067
5068 (define_insn "addqi3_carry"
5069   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5070           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5071                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5072                    (match_operand:QI 2 "general_operand" "qi,qm")))
5073    (clobber (reg:CC FLAGS_REG))]
5074   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5075   "adc{b}\t{%2, %0|%0, %2}"
5076   [(set_attr "type" "alu")
5077    (set_attr "pent_pair" "pu")
5078    (set_attr "mode" "QI")])
5079
5080 (define_insn "addhi3_carry"
5081   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5082           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5083                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5084                    (match_operand:HI 2 "general_operand" "ri,rm")))
5085    (clobber (reg:CC FLAGS_REG))]
5086   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5087   "adc{w}\t{%2, %0|%0, %2}"
5088   [(set_attr "type" "alu")
5089    (set_attr "pent_pair" "pu")
5090    (set_attr "mode" "HI")])
5091
5092 (define_insn "addsi3_carry"
5093   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5094           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5095                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5096                    (match_operand:SI 2 "general_operand" "ri,rm")))
5097    (clobber (reg:CC FLAGS_REG))]
5098   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5099   "adc{l}\t{%2, %0|%0, %2}"
5100   [(set_attr "type" "alu")
5101    (set_attr "pent_pair" "pu")
5102    (set_attr "mode" "SI")])
5103
5104 (define_insn "*addsi3_carry_zext"
5105   [(set (match_operand:DI 0 "register_operand" "=r")
5106           (zero_extend:DI 
5107             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5108                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5109                      (match_operand:SI 2 "general_operand" "rim"))))
5110    (clobber (reg:CC FLAGS_REG))]
5111   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5112   "adc{l}\t{%2, %k0|%k0, %2}"
5113   [(set_attr "type" "alu")
5114    (set_attr "pent_pair" "pu")
5115    (set_attr "mode" "SI")])
5116
5117 (define_insn "*addsi3_cc"
5118   [(set (reg:CC FLAGS_REG)
5119         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5120                     (match_operand:SI 2 "general_operand" "ri,rm")]
5121                    UNSPEC_ADD_CARRY))
5122    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5123         (plus:SI (match_dup 1) (match_dup 2)))]
5124   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5125   "add{l}\t{%2, %0|%0, %2}"
5126   [(set_attr "type" "alu")
5127    (set_attr "mode" "SI")])
5128
5129 (define_insn "addqi3_cc"
5130   [(set (reg:CC FLAGS_REG)
5131         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5132                     (match_operand:QI 2 "general_operand" "qi,qm")]
5133                    UNSPEC_ADD_CARRY))
5134    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5135         (plus:QI (match_dup 1) (match_dup 2)))]
5136   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5137   "add{b}\t{%2, %0|%0, %2}"
5138   [(set_attr "type" "alu")
5139    (set_attr "mode" "QI")])
5140
5141 (define_expand "addsi3"
5142   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5143                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5144                             (match_operand:SI 2 "general_operand" "")))
5145               (clobber (reg:CC FLAGS_REG))])]
5146   ""
5147   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5148
5149 (define_insn "*lea_1"
5150   [(set (match_operand:SI 0 "register_operand" "=r")
5151         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5152   "!TARGET_64BIT"
5153   "lea{l}\t{%a1, %0|%0, %a1}"
5154   [(set_attr "type" "lea")
5155    (set_attr "mode" "SI")])
5156
5157 (define_insn "*lea_1_rex64"
5158   [(set (match_operand:SI 0 "register_operand" "=r")
5159         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5160   "TARGET_64BIT"
5161   "lea{l}\t{%a1, %0|%0, %a1}"
5162   [(set_attr "type" "lea")
5163    (set_attr "mode" "SI")])
5164
5165 (define_insn "*lea_1_zext"
5166   [(set (match_operand:DI 0 "register_operand" "=r")
5167         (zero_extend:DI
5168          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5169   "TARGET_64BIT"
5170   "lea{l}\t{%a1, %k0|%k0, %a1}"
5171   [(set_attr "type" "lea")
5172    (set_attr "mode" "SI")])
5173
5174 (define_insn "*lea_2_rex64"
5175   [(set (match_operand:DI 0 "register_operand" "=r")
5176         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5177   "TARGET_64BIT"
5178   "lea{q}\t{%a1, %0|%0, %a1}"
5179   [(set_attr "type" "lea")
5180    (set_attr "mode" "DI")])
5181
5182 ;; The lea patterns for non-Pmodes needs to be matched by several
5183 ;; insns converted to real lea by splitters.
5184
5185 (define_insn_and_split "*lea_general_1"
5186   [(set (match_operand 0 "register_operand" "=r")
5187         (plus (plus (match_operand 1 "index_register_operand" "l")
5188                     (match_operand 2 "register_operand" "r"))
5189               (match_operand 3 "immediate_operand" "i")))]
5190   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5191     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5192    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5193    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5194    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5195    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5196        || GET_MODE (operands[3]) == VOIDmode)"
5197   "#"
5198   "&& reload_completed"
5199   [(const_int 0)]
5200 {
5201   rtx pat;
5202   operands[0] = gen_lowpart (SImode, operands[0]);
5203   operands[1] = gen_lowpart (Pmode, operands[1]);
5204   operands[2] = gen_lowpart (Pmode, operands[2]);
5205   operands[3] = gen_lowpart (Pmode, operands[3]);
5206   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5207                       operands[3]);
5208   if (Pmode != SImode)
5209     pat = gen_rtx_SUBREG (SImode, pat, 0);
5210   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5211   DONE;
5212 }
5213   [(set_attr "type" "lea")
5214    (set_attr "mode" "SI")])
5215
5216 (define_insn_and_split "*lea_general_1_zext"
5217   [(set (match_operand:DI 0 "register_operand" "=r")
5218         (zero_extend:DI
5219           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5220                             (match_operand:SI 2 "register_operand" "r"))
5221                    (match_operand:SI 3 "immediate_operand" "i"))))]
5222   "TARGET_64BIT"
5223   "#"
5224   "&& reload_completed"
5225   [(set (match_dup 0)
5226         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5227                                                      (match_dup 2))
5228                                             (match_dup 3)) 0)))]
5229 {
5230   operands[1] = gen_lowpart (Pmode, operands[1]);
5231   operands[2] = gen_lowpart (Pmode, operands[2]);
5232   operands[3] = gen_lowpart (Pmode, operands[3]);
5233 }
5234   [(set_attr "type" "lea")
5235    (set_attr "mode" "SI")])
5236
5237 (define_insn_and_split "*lea_general_2"
5238   [(set (match_operand 0 "register_operand" "=r")
5239         (plus (mult (match_operand 1 "index_register_operand" "l")
5240                     (match_operand 2 "const248_operand" "i"))
5241               (match_operand 3 "nonmemory_operand" "ri")))]
5242   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5243     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5244    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5245    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5246    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5247        || GET_MODE (operands[3]) == VOIDmode)"
5248   "#"
5249   "&& reload_completed"
5250   [(const_int 0)]
5251 {
5252   rtx pat;
5253   operands[0] = gen_lowpart (SImode, operands[0]);
5254   operands[1] = gen_lowpart (Pmode, operands[1]);
5255   operands[3] = gen_lowpart (Pmode, operands[3]);
5256   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5257                       operands[3]);
5258   if (Pmode != SImode)
5259     pat = gen_rtx_SUBREG (SImode, pat, 0);
5260   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5261   DONE;
5262 }
5263   [(set_attr "type" "lea")
5264    (set_attr "mode" "SI")])
5265
5266 (define_insn_and_split "*lea_general_2_zext"
5267   [(set (match_operand:DI 0 "register_operand" "=r")
5268         (zero_extend:DI
5269           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5270                             (match_operand:SI 2 "const248_operand" "n"))
5271                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5272   "TARGET_64BIT"
5273   "#"
5274   "&& reload_completed"
5275   [(set (match_dup 0)
5276         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5277                                                      (match_dup 2))
5278                                             (match_dup 3)) 0)))]
5279 {
5280   operands[1] = gen_lowpart (Pmode, operands[1]);
5281   operands[3] = gen_lowpart (Pmode, operands[3]);
5282 }
5283   [(set_attr "type" "lea")
5284    (set_attr "mode" "SI")])
5285
5286 (define_insn_and_split "*lea_general_3"
5287   [(set (match_operand 0 "register_operand" "=r")
5288         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5289                           (match_operand 2 "const248_operand" "i"))
5290                     (match_operand 3 "register_operand" "r"))
5291               (match_operand 4 "immediate_operand" "i")))]
5292   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5293     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5294    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5295    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5296    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5297   "#"
5298   "&& reload_completed"
5299   [(const_int 0)]
5300 {
5301   rtx pat;
5302   operands[0] = gen_lowpart (SImode, operands[0]);
5303   operands[1] = gen_lowpart (Pmode, operands[1]);
5304   operands[3] = gen_lowpart (Pmode, operands[3]);
5305   operands[4] = gen_lowpart (Pmode, operands[4]);
5306   pat = gen_rtx_PLUS (Pmode,
5307                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5308                                                          operands[2]),
5309                                     operands[3]),
5310                       operands[4]);
5311   if (Pmode != SImode)
5312     pat = gen_rtx_SUBREG (SImode, pat, 0);
5313   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5314   DONE;
5315 }
5316   [(set_attr "type" "lea")
5317    (set_attr "mode" "SI")])
5318
5319 (define_insn_and_split "*lea_general_3_zext"
5320   [(set (match_operand:DI 0 "register_operand" "=r")
5321         (zero_extend:DI
5322           (plus:SI (plus:SI (mult:SI
5323                               (match_operand:SI 1 "index_register_operand" "l")
5324                               (match_operand:SI 2 "const248_operand" "n"))
5325                             (match_operand:SI 3 "register_operand" "r"))
5326                    (match_operand:SI 4 "immediate_operand" "i"))))]
5327   "TARGET_64BIT"
5328   "#"
5329   "&& reload_completed"
5330   [(set (match_dup 0)
5331         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5332                                                               (match_dup 2))
5333                                                      (match_dup 3))
5334                                             (match_dup 4)) 0)))]
5335 {
5336   operands[1] = gen_lowpart (Pmode, operands[1]);
5337   operands[3] = gen_lowpart (Pmode, operands[3]);
5338   operands[4] = gen_lowpart (Pmode, operands[4]);
5339 }
5340   [(set_attr "type" "lea")
5341    (set_attr "mode" "SI")])
5342
5343 (define_insn "*adddi_1_rex64"
5344   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5345         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5346                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5347    (clobber (reg:CC FLAGS_REG))]
5348   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5349 {
5350   switch (get_attr_type (insn))
5351     {
5352     case TYPE_LEA:
5353       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5354       return "lea{q}\t{%a2, %0|%0, %a2}";
5355
5356     case TYPE_INCDEC:
5357       if (! rtx_equal_p (operands[0], operands[1]))
5358         abort ();
5359       if (operands[2] == const1_rtx)
5360         return "inc{q}\t%0";
5361       else if (operands[2] == constm1_rtx)
5362         return "dec{q}\t%0";
5363       else
5364         abort ();
5365
5366     default:
5367       if (! rtx_equal_p (operands[0], operands[1]))
5368         abort ();
5369
5370       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5371          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5372       if (GET_CODE (operands[2]) == CONST_INT
5373           /* Avoid overflows.  */
5374           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5375           && (INTVAL (operands[2]) == 128
5376               || (INTVAL (operands[2]) < 0
5377                   && INTVAL (operands[2]) != -128)))
5378         {
5379           operands[2] = GEN_INT (-INTVAL (operands[2]));
5380           return "sub{q}\t{%2, %0|%0, %2}";
5381         }
5382       return "add{q}\t{%2, %0|%0, %2}";
5383     }
5384 }
5385   [(set (attr "type")
5386      (cond [(eq_attr "alternative" "2")
5387               (const_string "lea")
5388             ; Current assemblers are broken and do not allow @GOTOFF in
5389             ; ought but a memory context.
5390             (match_operand:DI 2 "pic_symbolic_operand" "")
5391               (const_string "lea")
5392             (match_operand:DI 2 "incdec_operand" "")
5393               (const_string "incdec")
5394            ]
5395            (const_string "alu")))
5396    (set_attr "mode" "DI")])
5397
5398 ;; Convert lea to the lea pattern to avoid flags dependency.
5399 (define_split
5400   [(set (match_operand:DI 0 "register_operand" "")
5401         (plus:DI (match_operand:DI 1 "register_operand" "")
5402                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5403    (clobber (reg:CC FLAGS_REG))]
5404   "TARGET_64BIT && reload_completed
5405    && true_regnum (operands[0]) != true_regnum (operands[1])"
5406   [(set (match_dup 0)
5407         (plus:DI (match_dup 1)
5408                  (match_dup 2)))]
5409   "")
5410
5411 (define_insn "*adddi_2_rex64"
5412   [(set (reg FLAGS_REG)
5413         (compare
5414           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5415                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5416           (const_int 0)))                       
5417    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5418         (plus:DI (match_dup 1) (match_dup 2)))]
5419   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5420    && ix86_binary_operator_ok (PLUS, DImode, operands)
5421    /* Current assemblers are broken and do not allow @GOTOFF in
5422       ought but a memory context.  */
5423    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5424 {
5425   switch (get_attr_type (insn))
5426     {
5427     case TYPE_INCDEC:
5428       if (! rtx_equal_p (operands[0], operands[1]))
5429         abort ();
5430       if (operands[2] == const1_rtx)
5431         return "inc{q}\t%0";
5432       else if (operands[2] == constm1_rtx)
5433         return "dec{q}\t%0";
5434       else
5435         abort ();
5436
5437     default:
5438       if (! rtx_equal_p (operands[0], operands[1]))
5439         abort ();
5440       /* ???? We ought to handle there the 32bit case too
5441          - do we need new constraint?  */
5442       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5443          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5444       if (GET_CODE (operands[2]) == CONST_INT
5445           /* Avoid overflows.  */
5446           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5447           && (INTVAL (operands[2]) == 128
5448               || (INTVAL (operands[2]) < 0
5449                   && INTVAL (operands[2]) != -128)))
5450         {
5451           operands[2] = GEN_INT (-INTVAL (operands[2]));
5452           return "sub{q}\t{%2, %0|%0, %2}";
5453         }
5454       return "add{q}\t{%2, %0|%0, %2}";
5455     }
5456 }
5457   [(set (attr "type")
5458      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5459         (const_string "incdec")
5460         (const_string "alu")))
5461    (set_attr "mode" "DI")])
5462
5463 (define_insn "*adddi_3_rex64"
5464   [(set (reg FLAGS_REG)
5465         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5466                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5467    (clobber (match_scratch:DI 0 "=r"))]
5468   "TARGET_64BIT
5469    && ix86_match_ccmode (insn, CCZmode)
5470    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5471    /* Current assemblers are broken and do not allow @GOTOFF in
5472       ought but a memory context.  */
5473    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5474 {
5475   switch (get_attr_type (insn))
5476     {
5477     case TYPE_INCDEC:
5478       if (! rtx_equal_p (operands[0], operands[1]))
5479         abort ();
5480       if (operands[2] == const1_rtx)
5481         return "inc{q}\t%0";
5482       else if (operands[2] == constm1_rtx)
5483         return "dec{q}\t%0";
5484       else
5485         abort ();
5486
5487     default:
5488       if (! rtx_equal_p (operands[0], operands[1]))
5489         abort ();
5490       /* ???? We ought to handle there the 32bit case too
5491          - do we need new constraint?  */
5492       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5493          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5494       if (GET_CODE (operands[2]) == CONST_INT
5495           /* Avoid overflows.  */
5496           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5497           && (INTVAL (operands[2]) == 128
5498               || (INTVAL (operands[2]) < 0
5499                   && INTVAL (operands[2]) != -128)))
5500         {
5501           operands[2] = GEN_INT (-INTVAL (operands[2]));
5502           return "sub{q}\t{%2, %0|%0, %2}";
5503         }
5504       return "add{q}\t{%2, %0|%0, %2}";
5505     }
5506 }
5507   [(set (attr "type")
5508      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5509         (const_string "incdec")
5510         (const_string "alu")))
5511    (set_attr "mode" "DI")])
5512
5513 ; For comparisons against 1, -1 and 128, we may generate better code
5514 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5515 ; is matched then.  We can't accept general immediate, because for
5516 ; case of overflows,  the result is messed up.
5517 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5518 ; when negated.
5519 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5520 ; only for comparisons not depending on it.
5521 (define_insn "*adddi_4_rex64"
5522   [(set (reg FLAGS_REG)
5523         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5524                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5525    (clobber (match_scratch:DI 0 "=rm"))]
5526   "TARGET_64BIT
5527    &&  ix86_match_ccmode (insn, CCGCmode)"
5528 {
5529   switch (get_attr_type (insn))
5530     {
5531     case TYPE_INCDEC:
5532       if (operands[2] == constm1_rtx)
5533         return "inc{q}\t%0";
5534       else if (operands[2] == const1_rtx)
5535         return "dec{q}\t%0";
5536       else
5537         abort();
5538
5539     default:
5540       if (! rtx_equal_p (operands[0], operands[1]))
5541         abort ();
5542       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5543          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5544       if ((INTVAL (operands[2]) == -128
5545            || (INTVAL (operands[2]) > 0
5546                && INTVAL (operands[2]) != 128))
5547           /* Avoid overflows.  */
5548           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5549         return "sub{q}\t{%2, %0|%0, %2}";
5550       operands[2] = GEN_INT (-INTVAL (operands[2]));
5551       return "add{q}\t{%2, %0|%0, %2}";
5552     }
5553 }
5554   [(set (attr "type")
5555      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5556         (const_string "incdec")
5557         (const_string "alu")))
5558    (set_attr "mode" "DI")])
5559
5560 (define_insn "*adddi_5_rex64"
5561   [(set (reg FLAGS_REG)
5562         (compare
5563           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5564                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5565           (const_int 0)))                       
5566    (clobber (match_scratch:DI 0 "=r"))]
5567   "TARGET_64BIT
5568    && ix86_match_ccmode (insn, CCGOCmode)
5569    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5570    /* Current assemblers are broken and do not allow @GOTOFF in
5571       ought but a memory context.  */
5572    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5573 {
5574   switch (get_attr_type (insn))
5575     {
5576     case TYPE_INCDEC:
5577       if (! rtx_equal_p (operands[0], operands[1]))
5578         abort ();
5579       if (operands[2] == const1_rtx)
5580         return "inc{q}\t%0";
5581       else if (operands[2] == constm1_rtx)
5582         return "dec{q}\t%0";
5583       else
5584         abort();
5585
5586     default:
5587       if (! rtx_equal_p (operands[0], operands[1]))
5588         abort ();
5589       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5590          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5591       if (GET_CODE (operands[2]) == CONST_INT
5592           /* Avoid overflows.  */
5593           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5594           && (INTVAL (operands[2]) == 128
5595               || (INTVAL (operands[2]) < 0
5596                   && INTVAL (operands[2]) != -128)))
5597         {
5598           operands[2] = GEN_INT (-INTVAL (operands[2]));
5599           return "sub{q}\t{%2, %0|%0, %2}";
5600         }
5601       return "add{q}\t{%2, %0|%0, %2}";
5602     }
5603 }
5604   [(set (attr "type")
5605      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5606         (const_string "incdec")
5607         (const_string "alu")))
5608    (set_attr "mode" "DI")])
5609
5610
5611 (define_insn "*addsi_1"
5612   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5613         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5614                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5615    (clobber (reg:CC FLAGS_REG))]
5616   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5617 {
5618   switch (get_attr_type (insn))
5619     {
5620     case TYPE_LEA:
5621       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5622       return "lea{l}\t{%a2, %0|%0, %a2}";
5623
5624     case TYPE_INCDEC:
5625       if (! rtx_equal_p (operands[0], operands[1]))
5626         abort ();
5627       if (operands[2] == const1_rtx)
5628         return "inc{l}\t%0";
5629       else if (operands[2] == constm1_rtx)
5630         return "dec{l}\t%0";
5631       else
5632         abort();
5633
5634     default:
5635       if (! rtx_equal_p (operands[0], operands[1]))
5636         abort ();
5637
5638       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5639          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5640       if (GET_CODE (operands[2]) == CONST_INT
5641           && (INTVAL (operands[2]) == 128
5642               || (INTVAL (operands[2]) < 0
5643                   && INTVAL (operands[2]) != -128)))
5644         {
5645           operands[2] = GEN_INT (-INTVAL (operands[2]));
5646           return "sub{l}\t{%2, %0|%0, %2}";
5647         }
5648       return "add{l}\t{%2, %0|%0, %2}";
5649     }
5650 }
5651   [(set (attr "type")
5652      (cond [(eq_attr "alternative" "2")
5653               (const_string "lea")
5654             ; Current assemblers are broken and do not allow @GOTOFF in
5655             ; ought but a memory context.
5656             (match_operand:SI 2 "pic_symbolic_operand" "")
5657               (const_string "lea")
5658             (match_operand:SI 2 "incdec_operand" "")
5659               (const_string "incdec")
5660            ]
5661            (const_string "alu")))
5662    (set_attr "mode" "SI")])
5663
5664 ;; Convert lea to the lea pattern to avoid flags dependency.
5665 (define_split
5666   [(set (match_operand 0 "register_operand" "")
5667         (plus (match_operand 1 "register_operand" "")
5668               (match_operand 2 "nonmemory_operand" "")))
5669    (clobber (reg:CC FLAGS_REG))]
5670   "reload_completed
5671    && true_regnum (operands[0]) != true_regnum (operands[1])"
5672   [(const_int 0)]
5673 {
5674   rtx pat;
5675   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5676      may confuse gen_lowpart.  */
5677   if (GET_MODE (operands[0]) != Pmode)
5678     {
5679       operands[1] = gen_lowpart (Pmode, operands[1]);
5680       operands[2] = gen_lowpart (Pmode, operands[2]);
5681     }
5682   operands[0] = gen_lowpart (SImode, operands[0]);
5683   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5684   if (Pmode != SImode)
5685     pat = gen_rtx_SUBREG (SImode, pat, 0);
5686   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5687   DONE;
5688 })
5689
5690 ;; It may seem that nonimmediate operand is proper one for operand 1.
5691 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5692 ;; we take care in ix86_binary_operator_ok to not allow two memory
5693 ;; operands so proper swapping will be done in reload.  This allow
5694 ;; patterns constructed from addsi_1 to match.
5695 (define_insn "addsi_1_zext"
5696   [(set (match_operand:DI 0 "register_operand" "=r,r")
5697         (zero_extend:DI
5698           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5699                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5700    (clobber (reg:CC FLAGS_REG))]
5701   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5702 {
5703   switch (get_attr_type (insn))
5704     {
5705     case TYPE_LEA:
5706       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5707       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5708
5709     case TYPE_INCDEC:
5710       if (operands[2] == const1_rtx)
5711         return "inc{l}\t%k0";
5712       else if (operands[2] == constm1_rtx)
5713         return "dec{l}\t%k0";
5714       else
5715         abort();
5716
5717     default:
5718       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5719          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5720       if (GET_CODE (operands[2]) == CONST_INT
5721           && (INTVAL (operands[2]) == 128
5722               || (INTVAL (operands[2]) < 0
5723                   && INTVAL (operands[2]) != -128)))
5724         {
5725           operands[2] = GEN_INT (-INTVAL (operands[2]));
5726           return "sub{l}\t{%2, %k0|%k0, %2}";
5727         }
5728       return "add{l}\t{%2, %k0|%k0, %2}";
5729     }
5730 }
5731   [(set (attr "type")
5732      (cond [(eq_attr "alternative" "1")
5733               (const_string "lea")
5734             ; Current assemblers are broken and do not allow @GOTOFF in
5735             ; ought but a memory context.
5736             (match_operand:SI 2 "pic_symbolic_operand" "")
5737               (const_string "lea")
5738             (match_operand:SI 2 "incdec_operand" "")
5739               (const_string "incdec")
5740            ]
5741            (const_string "alu")))
5742    (set_attr "mode" "SI")])
5743
5744 ;; Convert lea to the lea pattern to avoid flags dependency.
5745 (define_split
5746   [(set (match_operand:DI 0 "register_operand" "")
5747         (zero_extend:DI
5748           (plus:SI (match_operand:SI 1 "register_operand" "")
5749                    (match_operand:SI 2 "nonmemory_operand" ""))))
5750    (clobber (reg:CC FLAGS_REG))]
5751   "TARGET_64BIT && reload_completed
5752    && true_regnum (operands[0]) != true_regnum (operands[1])"
5753   [(set (match_dup 0)
5754         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5755 {
5756   operands[1] = gen_lowpart (Pmode, operands[1]);
5757   operands[2] = gen_lowpart (Pmode, operands[2]);
5758 })
5759
5760 (define_insn "*addsi_2"
5761   [(set (reg FLAGS_REG)
5762         (compare
5763           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5764                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5765           (const_int 0)))                       
5766    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5767         (plus:SI (match_dup 1) (match_dup 2)))]
5768   "ix86_match_ccmode (insn, CCGOCmode)
5769    && ix86_binary_operator_ok (PLUS, SImode, operands)
5770    /* Current assemblers are broken and do not allow @GOTOFF in
5771       ought but a memory context.  */
5772    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5773 {
5774   switch (get_attr_type (insn))
5775     {
5776     case TYPE_INCDEC:
5777       if (! rtx_equal_p (operands[0], operands[1]))
5778         abort ();
5779       if (operands[2] == const1_rtx)
5780         return "inc{l}\t%0";
5781       else if (operands[2] == constm1_rtx)
5782         return "dec{l}\t%0";
5783       else
5784         abort();
5785
5786     default:
5787       if (! rtx_equal_p (operands[0], operands[1]))
5788         abort ();
5789       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5790          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5791       if (GET_CODE (operands[2]) == CONST_INT
5792           && (INTVAL (operands[2]) == 128
5793               || (INTVAL (operands[2]) < 0
5794                   && INTVAL (operands[2]) != -128)))
5795         {
5796           operands[2] = GEN_INT (-INTVAL (operands[2]));
5797           return "sub{l}\t{%2, %0|%0, %2}";
5798         }
5799       return "add{l}\t{%2, %0|%0, %2}";
5800     }
5801 }
5802   [(set (attr "type")
5803      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5804         (const_string "incdec")
5805         (const_string "alu")))
5806    (set_attr "mode" "SI")])
5807
5808 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5809 (define_insn "*addsi_2_zext"
5810   [(set (reg FLAGS_REG)
5811         (compare
5812           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5813                    (match_operand:SI 2 "general_operand" "rmni"))
5814           (const_int 0)))                       
5815    (set (match_operand:DI 0 "register_operand" "=r")
5816         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5817   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5818    && ix86_binary_operator_ok (PLUS, SImode, operands)
5819    /* Current assemblers are broken and do not allow @GOTOFF in
5820       ought but a memory context.  */
5821    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5822 {
5823   switch (get_attr_type (insn))
5824     {
5825     case TYPE_INCDEC:
5826       if (operands[2] == const1_rtx)
5827         return "inc{l}\t%k0";
5828       else if (operands[2] == constm1_rtx)
5829         return "dec{l}\t%k0";
5830       else
5831         abort();
5832
5833     default:
5834       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5835          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5836       if (GET_CODE (operands[2]) == CONST_INT
5837           && (INTVAL (operands[2]) == 128
5838               || (INTVAL (operands[2]) < 0
5839                   && INTVAL (operands[2]) != -128)))
5840         {
5841           operands[2] = GEN_INT (-INTVAL (operands[2]));
5842           return "sub{l}\t{%2, %k0|%k0, %2}";
5843         }
5844       return "add{l}\t{%2, %k0|%k0, %2}";
5845     }
5846 }
5847   [(set (attr "type")
5848      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5849         (const_string "incdec")
5850         (const_string "alu")))
5851    (set_attr "mode" "SI")])
5852
5853 (define_insn "*addsi_3"
5854   [(set (reg FLAGS_REG)
5855         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5856                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5857    (clobber (match_scratch:SI 0 "=r"))]
5858   "ix86_match_ccmode (insn, CCZmode)
5859    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5860    /* Current assemblers are broken and do not allow @GOTOFF in
5861       ought but a memory context.  */
5862    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5863 {
5864   switch (get_attr_type (insn))
5865     {
5866     case TYPE_INCDEC:
5867       if (! rtx_equal_p (operands[0], operands[1]))
5868         abort ();
5869       if (operands[2] == const1_rtx)
5870         return "inc{l}\t%0";
5871       else if (operands[2] == constm1_rtx)
5872         return "dec{l}\t%0";
5873       else
5874         abort();
5875
5876     default:
5877       if (! rtx_equal_p (operands[0], operands[1]))
5878         abort ();
5879       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5880          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5881       if (GET_CODE (operands[2]) == CONST_INT
5882           && (INTVAL (operands[2]) == 128
5883               || (INTVAL (operands[2]) < 0
5884                   && INTVAL (operands[2]) != -128)))
5885         {
5886           operands[2] = GEN_INT (-INTVAL (operands[2]));
5887           return "sub{l}\t{%2, %0|%0, %2}";
5888         }
5889       return "add{l}\t{%2, %0|%0, %2}";
5890     }
5891 }
5892   [(set (attr "type")
5893      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5894         (const_string "incdec")
5895         (const_string "alu")))
5896    (set_attr "mode" "SI")])
5897
5898 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5899 (define_insn "*addsi_3_zext"
5900   [(set (reg FLAGS_REG)
5901         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5902                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5903    (set (match_operand:DI 0 "register_operand" "=r")
5904         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5905   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5906    && ix86_binary_operator_ok (PLUS, SImode, operands)
5907    /* Current assemblers are broken and do not allow @GOTOFF in
5908       ought but a memory context.  */
5909    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5910 {
5911   switch (get_attr_type (insn))
5912     {
5913     case TYPE_INCDEC:
5914       if (operands[2] == const1_rtx)
5915         return "inc{l}\t%k0";
5916       else if (operands[2] == constm1_rtx)
5917         return "dec{l}\t%k0";
5918       else
5919         abort();
5920
5921     default:
5922       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5923          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5924       if (GET_CODE (operands[2]) == CONST_INT
5925           && (INTVAL (operands[2]) == 128
5926               || (INTVAL (operands[2]) < 0
5927                   && INTVAL (operands[2]) != -128)))
5928         {
5929           operands[2] = GEN_INT (-INTVAL (operands[2]));
5930           return "sub{l}\t{%2, %k0|%k0, %2}";
5931         }
5932       return "add{l}\t{%2, %k0|%k0, %2}";
5933     }
5934 }
5935   [(set (attr "type")
5936      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5937         (const_string "incdec")
5938         (const_string "alu")))
5939    (set_attr "mode" "SI")])
5940
5941 ; For comparisons against 1, -1 and 128, we may generate better code
5942 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5943 ; is matched then.  We can't accept general immediate, because for
5944 ; case of overflows,  the result is messed up.
5945 ; This pattern also don't hold of 0x80000000, since the value overflows
5946 ; when negated.
5947 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5948 ; only for comparisons not depending on it.
5949 (define_insn "*addsi_4"
5950   [(set (reg FLAGS_REG)
5951         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5952                  (match_operand:SI 2 "const_int_operand" "n")))
5953    (clobber (match_scratch:SI 0 "=rm"))]
5954   "ix86_match_ccmode (insn, CCGCmode)
5955    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5956 {
5957   switch (get_attr_type (insn))
5958     {
5959     case TYPE_INCDEC:
5960       if (operands[2] == constm1_rtx)
5961         return "inc{l}\t%0";
5962       else if (operands[2] == const1_rtx)
5963         return "dec{l}\t%0";
5964       else
5965         abort();
5966
5967     default:
5968       if (! rtx_equal_p (operands[0], operands[1]))
5969         abort ();
5970       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5971          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5972       if ((INTVAL (operands[2]) == -128
5973            || (INTVAL (operands[2]) > 0
5974                && INTVAL (operands[2]) != 128)))
5975         return "sub{l}\t{%2, %0|%0, %2}";
5976       operands[2] = GEN_INT (-INTVAL (operands[2]));
5977       return "add{l}\t{%2, %0|%0, %2}";
5978     }
5979 }
5980   [(set (attr "type")
5981      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5982         (const_string "incdec")
5983         (const_string "alu")))
5984    (set_attr "mode" "SI")])
5985
5986 (define_insn "*addsi_5"
5987   [(set (reg FLAGS_REG)
5988         (compare
5989           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5990                    (match_operand:SI 2 "general_operand" "rmni"))
5991           (const_int 0)))                       
5992    (clobber (match_scratch:SI 0 "=r"))]
5993   "ix86_match_ccmode (insn, CCGOCmode)
5994    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5995    /* Current assemblers are broken and do not allow @GOTOFF in
5996       ought but a memory context.  */
5997    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5998 {
5999   switch (get_attr_type (insn))
6000     {
6001     case TYPE_INCDEC:
6002       if (! rtx_equal_p (operands[0], operands[1]))
6003         abort ();
6004       if (operands[2] == const1_rtx)
6005         return "inc{l}\t%0";
6006       else if (operands[2] == constm1_rtx)
6007         return "dec{l}\t%0";
6008       else
6009         abort();
6010
6011     default:
6012       if (! rtx_equal_p (operands[0], operands[1]))
6013         abort ();
6014       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6015          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6016       if (GET_CODE (operands[2]) == CONST_INT
6017           && (INTVAL (operands[2]) == 128
6018               || (INTVAL (operands[2]) < 0
6019                   && INTVAL (operands[2]) != -128)))
6020         {
6021           operands[2] = GEN_INT (-INTVAL (operands[2]));
6022           return "sub{l}\t{%2, %0|%0, %2}";
6023         }
6024       return "add{l}\t{%2, %0|%0, %2}";
6025     }
6026 }
6027   [(set (attr "type")
6028      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6029         (const_string "incdec")
6030         (const_string "alu")))
6031    (set_attr "mode" "SI")])
6032
6033 (define_expand "addhi3"
6034   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6035                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6036                             (match_operand:HI 2 "general_operand" "")))
6037               (clobber (reg:CC FLAGS_REG))])]
6038   "TARGET_HIMODE_MATH"
6039   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6040
6041 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6042 ;; type optimizations enabled by define-splits.  This is not important
6043 ;; for PII, and in fact harmful because of partial register stalls.
6044
6045 (define_insn "*addhi_1_lea"
6046   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6047         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6048                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6049    (clobber (reg:CC FLAGS_REG))]
6050   "!TARGET_PARTIAL_REG_STALL
6051    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6052 {
6053   switch (get_attr_type (insn))
6054     {
6055     case TYPE_LEA:
6056       return "#";
6057     case TYPE_INCDEC:
6058       if (operands[2] == const1_rtx)
6059         return "inc{w}\t%0";
6060       else if (operands[2] == constm1_rtx)
6061         return "dec{w}\t%0";
6062       abort();
6063
6064     default:
6065       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6066          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6067       if (GET_CODE (operands[2]) == CONST_INT
6068           && (INTVAL (operands[2]) == 128
6069               || (INTVAL (operands[2]) < 0
6070                   && INTVAL (operands[2]) != -128)))
6071         {
6072           operands[2] = GEN_INT (-INTVAL (operands[2]));
6073           return "sub{w}\t{%2, %0|%0, %2}";
6074         }
6075       return "add{w}\t{%2, %0|%0, %2}";
6076     }
6077 }
6078   [(set (attr "type")
6079      (if_then_else (eq_attr "alternative" "2")
6080         (const_string "lea")
6081         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6082            (const_string "incdec")
6083            (const_string "alu"))))
6084    (set_attr "mode" "HI,HI,SI")])
6085
6086 (define_insn "*addhi_1"
6087   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6088         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6089                  (match_operand:HI 2 "general_operand" "ri,rm")))
6090    (clobber (reg:CC FLAGS_REG))]
6091   "TARGET_PARTIAL_REG_STALL
6092    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6093 {
6094   switch (get_attr_type (insn))
6095     {
6096     case TYPE_INCDEC:
6097       if (operands[2] == const1_rtx)
6098         return "inc{w}\t%0";
6099       else if (operands[2] == constm1_rtx)
6100         return "dec{w}\t%0";
6101       abort();
6102
6103     default:
6104       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6105          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6106       if (GET_CODE (operands[2]) == CONST_INT
6107           && (INTVAL (operands[2]) == 128
6108               || (INTVAL (operands[2]) < 0
6109                   && INTVAL (operands[2]) != -128)))
6110         {
6111           operands[2] = GEN_INT (-INTVAL (operands[2]));
6112           return "sub{w}\t{%2, %0|%0, %2}";
6113         }
6114       return "add{w}\t{%2, %0|%0, %2}";
6115     }
6116 }
6117   [(set (attr "type")
6118      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6119         (const_string "incdec")
6120         (const_string "alu")))
6121    (set_attr "mode" "HI")])
6122
6123 (define_insn "*addhi_2"
6124   [(set (reg FLAGS_REG)
6125         (compare
6126           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6127                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6128           (const_int 0)))                       
6129    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6130         (plus:HI (match_dup 1) (match_dup 2)))]
6131   "ix86_match_ccmode (insn, CCGOCmode)
6132    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6133 {
6134   switch (get_attr_type (insn))
6135     {
6136     case TYPE_INCDEC:
6137       if (operands[2] == const1_rtx)
6138         return "inc{w}\t%0";
6139       else if (operands[2] == constm1_rtx)
6140         return "dec{w}\t%0";
6141       abort();
6142
6143     default:
6144       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6145          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6146       if (GET_CODE (operands[2]) == CONST_INT
6147           && (INTVAL (operands[2]) == 128
6148               || (INTVAL (operands[2]) < 0
6149                   && INTVAL (operands[2]) != -128)))
6150         {
6151           operands[2] = GEN_INT (-INTVAL (operands[2]));
6152           return "sub{w}\t{%2, %0|%0, %2}";
6153         }
6154       return "add{w}\t{%2, %0|%0, %2}";
6155     }
6156 }
6157   [(set (attr "type")
6158      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6159         (const_string "incdec")
6160         (const_string "alu")))
6161    (set_attr "mode" "HI")])
6162
6163 (define_insn "*addhi_3"
6164   [(set (reg FLAGS_REG)
6165         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6166                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6167    (clobber (match_scratch:HI 0 "=r"))]
6168   "ix86_match_ccmode (insn, CCZmode)
6169    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6170 {
6171   switch (get_attr_type (insn))
6172     {
6173     case TYPE_INCDEC:
6174       if (operands[2] == const1_rtx)
6175         return "inc{w}\t%0";
6176       else if (operands[2] == constm1_rtx)
6177         return "dec{w}\t%0";
6178       abort();
6179
6180     default:
6181       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6182          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6183       if (GET_CODE (operands[2]) == CONST_INT
6184           && (INTVAL (operands[2]) == 128
6185               || (INTVAL (operands[2]) < 0
6186                   && INTVAL (operands[2]) != -128)))
6187         {
6188           operands[2] = GEN_INT (-INTVAL (operands[2]));
6189           return "sub{w}\t{%2, %0|%0, %2}";
6190         }
6191       return "add{w}\t{%2, %0|%0, %2}";
6192     }
6193 }
6194   [(set (attr "type")
6195      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6196         (const_string "incdec")
6197         (const_string "alu")))
6198    (set_attr "mode" "HI")])
6199
6200 ; See comments above addsi_3_imm for details.
6201 (define_insn "*addhi_4"
6202   [(set (reg FLAGS_REG)
6203         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6204                  (match_operand:HI 2 "const_int_operand" "n")))
6205    (clobber (match_scratch:HI 0 "=rm"))]
6206   "ix86_match_ccmode (insn, CCGCmode)
6207    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6208 {
6209   switch (get_attr_type (insn))
6210     {
6211     case TYPE_INCDEC:
6212       if (operands[2] == constm1_rtx)
6213         return "inc{w}\t%0";
6214       else if (operands[2] == const1_rtx)
6215         return "dec{w}\t%0";
6216       else
6217         abort();
6218
6219     default:
6220       if (! rtx_equal_p (operands[0], operands[1]))
6221         abort ();
6222       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6223          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6224       if ((INTVAL (operands[2]) == -128
6225            || (INTVAL (operands[2]) > 0
6226                && INTVAL (operands[2]) != 128)))
6227         return "sub{w}\t{%2, %0|%0, %2}";
6228       operands[2] = GEN_INT (-INTVAL (operands[2]));
6229       return "add{w}\t{%2, %0|%0, %2}";
6230     }
6231 }
6232   [(set (attr "type")
6233      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6234         (const_string "incdec")
6235         (const_string "alu")))
6236    (set_attr "mode" "SI")])
6237
6238
6239 (define_insn "*addhi_5"
6240   [(set (reg FLAGS_REG)
6241         (compare
6242           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6243                    (match_operand:HI 2 "general_operand" "rmni"))
6244           (const_int 0)))                       
6245    (clobber (match_scratch:HI 0 "=r"))]
6246   "ix86_match_ccmode (insn, CCGOCmode)
6247    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6248 {
6249   switch (get_attr_type (insn))
6250     {
6251     case TYPE_INCDEC:
6252       if (operands[2] == const1_rtx)
6253         return "inc{w}\t%0";
6254       else if (operands[2] == constm1_rtx)
6255         return "dec{w}\t%0";
6256       abort();
6257
6258     default:
6259       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6260          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6261       if (GET_CODE (operands[2]) == CONST_INT
6262           && (INTVAL (operands[2]) == 128
6263               || (INTVAL (operands[2]) < 0
6264                   && INTVAL (operands[2]) != -128)))
6265         {
6266           operands[2] = GEN_INT (-INTVAL (operands[2]));
6267           return "sub{w}\t{%2, %0|%0, %2}";
6268         }
6269       return "add{w}\t{%2, %0|%0, %2}";
6270     }
6271 }
6272   [(set (attr "type")
6273      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6274         (const_string "incdec")
6275         (const_string "alu")))
6276    (set_attr "mode" "HI")])
6277
6278 (define_expand "addqi3"
6279   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6280                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6281                             (match_operand:QI 2 "general_operand" "")))
6282               (clobber (reg:CC FLAGS_REG))])]
6283   "TARGET_QIMODE_MATH"
6284   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6285
6286 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6287 (define_insn "*addqi_1_lea"
6288   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6289         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6290                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6291    (clobber (reg:CC FLAGS_REG))]
6292   "!TARGET_PARTIAL_REG_STALL
6293    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6294 {
6295   int widen = (which_alternative == 2);
6296   switch (get_attr_type (insn))
6297     {
6298     case TYPE_LEA:
6299       return "#";
6300     case TYPE_INCDEC:
6301       if (operands[2] == const1_rtx)
6302         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6303       else if (operands[2] == constm1_rtx)
6304         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6305       abort();
6306
6307     default:
6308       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6309          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6310       if (GET_CODE (operands[2]) == CONST_INT
6311           && (INTVAL (operands[2]) == 128
6312               || (INTVAL (operands[2]) < 0
6313                   && INTVAL (operands[2]) != -128)))
6314         {
6315           operands[2] = GEN_INT (-INTVAL (operands[2]));
6316           if (widen)
6317             return "sub{l}\t{%2, %k0|%k0, %2}";
6318           else
6319             return "sub{b}\t{%2, %0|%0, %2}";
6320         }
6321       if (widen)
6322         return "add{l}\t{%k2, %k0|%k0, %k2}";
6323       else
6324         return "add{b}\t{%2, %0|%0, %2}";
6325     }
6326 }
6327   [(set (attr "type")
6328      (if_then_else (eq_attr "alternative" "3")
6329         (const_string "lea")
6330         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6331            (const_string "incdec")
6332            (const_string "alu"))))
6333    (set_attr "mode" "QI,QI,SI,SI")])
6334
6335 (define_insn "*addqi_1"
6336   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6337         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6338                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6339    (clobber (reg:CC FLAGS_REG))]
6340   "TARGET_PARTIAL_REG_STALL
6341    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6342 {
6343   int widen = (which_alternative == 2);
6344   switch (get_attr_type (insn))
6345     {
6346     case TYPE_INCDEC:
6347       if (operands[2] == const1_rtx)
6348         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6349       else if (operands[2] == constm1_rtx)
6350         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6351       abort();
6352
6353     default:
6354       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6355          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6356       if (GET_CODE (operands[2]) == CONST_INT
6357           && (INTVAL (operands[2]) == 128
6358               || (INTVAL (operands[2]) < 0
6359                   && INTVAL (operands[2]) != -128)))
6360         {
6361           operands[2] = GEN_INT (-INTVAL (operands[2]));
6362           if (widen)
6363             return "sub{l}\t{%2, %k0|%k0, %2}";
6364           else
6365             return "sub{b}\t{%2, %0|%0, %2}";
6366         }
6367       if (widen)
6368         return "add{l}\t{%k2, %k0|%k0, %k2}";
6369       else
6370         return "add{b}\t{%2, %0|%0, %2}";
6371     }
6372 }
6373   [(set (attr "type")
6374      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6375         (const_string "incdec")
6376         (const_string "alu")))
6377    (set_attr "mode" "QI,QI,SI")])
6378
6379 (define_insn "*addqi_1_slp"
6380   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6381         (plus:QI (match_dup 0)
6382                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6383    (clobber (reg:CC FLAGS_REG))]
6384   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6385    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6386 {
6387   switch (get_attr_type (insn))
6388     {
6389     case TYPE_INCDEC:
6390       if (operands[1] == const1_rtx)
6391         return "inc{b}\t%0";
6392       else if (operands[1] == constm1_rtx)
6393         return "dec{b}\t%0";
6394       abort();
6395
6396     default:
6397       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6398       if (GET_CODE (operands[1]) == CONST_INT
6399           && INTVAL (operands[1]) < 0)
6400         {
6401           operands[1] = GEN_INT (-INTVAL (operands[1]));
6402           return "sub{b}\t{%1, %0|%0, %1}";
6403         }
6404       return "add{b}\t{%1, %0|%0, %1}";
6405     }
6406 }
6407   [(set (attr "type")
6408      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6409         (const_string "incdec")
6410         (const_string "alu1")))
6411    (set_attr "mode" "QI")])
6412
6413 (define_insn "*addqi_2"
6414   [(set (reg FLAGS_REG)
6415         (compare
6416           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6417                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6418           (const_int 0)))
6419    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6420         (plus:QI (match_dup 1) (match_dup 2)))]
6421   "ix86_match_ccmode (insn, CCGOCmode)
6422    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6423 {
6424   switch (get_attr_type (insn))
6425     {
6426     case TYPE_INCDEC:
6427       if (operands[2] == const1_rtx)
6428         return "inc{b}\t%0";
6429       else if (operands[2] == constm1_rtx
6430                || (GET_CODE (operands[2]) == CONST_INT
6431                    && INTVAL (operands[2]) == 255))
6432         return "dec{b}\t%0";
6433       abort();
6434
6435     default:
6436       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6437       if (GET_CODE (operands[2]) == CONST_INT
6438           && INTVAL (operands[2]) < 0)
6439         {
6440           operands[2] = GEN_INT (-INTVAL (operands[2]));
6441           return "sub{b}\t{%2, %0|%0, %2}";
6442         }
6443       return "add{b}\t{%2, %0|%0, %2}";
6444     }
6445 }
6446   [(set (attr "type")
6447      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6448         (const_string "incdec")
6449         (const_string "alu")))
6450    (set_attr "mode" "QI")])
6451
6452 (define_insn "*addqi_3"
6453   [(set (reg FLAGS_REG)
6454         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6455                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6456    (clobber (match_scratch:QI 0 "=q"))]
6457   "ix86_match_ccmode (insn, CCZmode)
6458    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6459 {
6460   switch (get_attr_type (insn))
6461     {
6462     case TYPE_INCDEC:
6463       if (operands[2] == const1_rtx)
6464         return "inc{b}\t%0";
6465       else if (operands[2] == constm1_rtx
6466                || (GET_CODE (operands[2]) == CONST_INT
6467                    && INTVAL (operands[2]) == 255))
6468         return "dec{b}\t%0";
6469       abort();
6470
6471     default:
6472       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6473       if (GET_CODE (operands[2]) == CONST_INT
6474           && INTVAL (operands[2]) < 0)
6475         {
6476           operands[2] = GEN_INT (-INTVAL (operands[2]));
6477           return "sub{b}\t{%2, %0|%0, %2}";
6478         }
6479       return "add{b}\t{%2, %0|%0, %2}";
6480     }
6481 }
6482   [(set (attr "type")
6483      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6484         (const_string "incdec")
6485         (const_string "alu")))
6486    (set_attr "mode" "QI")])
6487
6488 ; See comments above addsi_3_imm for details.
6489 (define_insn "*addqi_4"
6490   [(set (reg FLAGS_REG)
6491         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6492                  (match_operand:QI 2 "const_int_operand" "n")))
6493    (clobber (match_scratch:QI 0 "=qm"))]
6494   "ix86_match_ccmode (insn, CCGCmode)
6495    && (INTVAL (operands[2]) & 0xff) != 0x80"
6496 {
6497   switch (get_attr_type (insn))
6498     {
6499     case TYPE_INCDEC:
6500       if (operands[2] == constm1_rtx
6501           || (GET_CODE (operands[2]) == CONST_INT
6502               && INTVAL (operands[2]) == 255))
6503         return "inc{b}\t%0";
6504       else if (operands[2] == const1_rtx)
6505         return "dec{b}\t%0";
6506       else
6507         abort();
6508
6509     default:
6510       if (! rtx_equal_p (operands[0], operands[1]))
6511         abort ();
6512       if (INTVAL (operands[2]) < 0)
6513         {
6514           operands[2] = GEN_INT (-INTVAL (operands[2]));
6515           return "add{b}\t{%2, %0|%0, %2}";
6516         }
6517       return "sub{b}\t{%2, %0|%0, %2}";
6518     }
6519 }
6520   [(set (attr "type")
6521      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6522         (const_string "incdec")
6523         (const_string "alu")))
6524    (set_attr "mode" "QI")])
6525
6526
6527 (define_insn "*addqi_5"
6528   [(set (reg FLAGS_REG)
6529         (compare
6530           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6531                    (match_operand:QI 2 "general_operand" "qmni"))
6532           (const_int 0)))
6533    (clobber (match_scratch:QI 0 "=q"))]
6534   "ix86_match_ccmode (insn, CCGOCmode)
6535    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6536 {
6537   switch (get_attr_type (insn))
6538     {
6539     case TYPE_INCDEC:
6540       if (operands[2] == const1_rtx)
6541         return "inc{b}\t%0";
6542       else if (operands[2] == constm1_rtx
6543                || (GET_CODE (operands[2]) == CONST_INT
6544                    && INTVAL (operands[2]) == 255))
6545         return "dec{b}\t%0";
6546       abort();
6547
6548     default:
6549       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6550       if (GET_CODE (operands[2]) == CONST_INT
6551           && INTVAL (operands[2]) < 0)
6552         {
6553           operands[2] = GEN_INT (-INTVAL (operands[2]));
6554           return "sub{b}\t{%2, %0|%0, %2}";
6555         }
6556       return "add{b}\t{%2, %0|%0, %2}";
6557     }
6558 }
6559   [(set (attr "type")
6560      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6561         (const_string "incdec")
6562         (const_string "alu")))
6563    (set_attr "mode" "QI")])
6564
6565
6566 (define_insn "addqi_ext_1"
6567   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6568                          (const_int 8)
6569                          (const_int 8))
6570         (plus:SI
6571           (zero_extract:SI
6572             (match_operand 1 "ext_register_operand" "0")
6573             (const_int 8)
6574             (const_int 8))
6575           (match_operand:QI 2 "general_operand" "Qmn")))
6576    (clobber (reg:CC FLAGS_REG))]
6577   "!TARGET_64BIT"
6578 {
6579   switch (get_attr_type (insn))
6580     {
6581     case TYPE_INCDEC:
6582       if (operands[2] == const1_rtx)
6583         return "inc{b}\t%h0";
6584       else if (operands[2] == constm1_rtx
6585                || (GET_CODE (operands[2]) == CONST_INT
6586                    && INTVAL (operands[2]) == 255))
6587         return "dec{b}\t%h0";
6588       abort();
6589
6590     default:
6591       return "add{b}\t{%2, %h0|%h0, %2}";
6592     }
6593 }
6594   [(set (attr "type")
6595      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6596         (const_string "incdec")
6597         (const_string "alu")))
6598    (set_attr "mode" "QI")])
6599
6600 (define_insn "*addqi_ext_1_rex64"
6601   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6602                          (const_int 8)
6603                          (const_int 8))
6604         (plus:SI
6605           (zero_extract:SI
6606             (match_operand 1 "ext_register_operand" "0")
6607             (const_int 8)
6608             (const_int 8))
6609           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6610    (clobber (reg:CC FLAGS_REG))]
6611   "TARGET_64BIT"
6612 {
6613   switch (get_attr_type (insn))
6614     {
6615     case TYPE_INCDEC:
6616       if (operands[2] == const1_rtx)
6617         return "inc{b}\t%h0";
6618       else if (operands[2] == constm1_rtx
6619                || (GET_CODE (operands[2]) == CONST_INT
6620                    && INTVAL (operands[2]) == 255))
6621         return "dec{b}\t%h0";
6622       abort();
6623
6624     default:
6625       return "add{b}\t{%2, %h0|%h0, %2}";
6626     }
6627 }
6628   [(set (attr "type")
6629      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6630         (const_string "incdec")
6631         (const_string "alu")))
6632    (set_attr "mode" "QI")])
6633
6634 (define_insn "*addqi_ext_2"
6635   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6636                          (const_int 8)
6637                          (const_int 8))
6638         (plus:SI
6639           (zero_extract:SI
6640             (match_operand 1 "ext_register_operand" "%0")
6641             (const_int 8)
6642             (const_int 8))
6643           (zero_extract:SI
6644             (match_operand 2 "ext_register_operand" "Q")
6645             (const_int 8)
6646             (const_int 8))))
6647    (clobber (reg:CC FLAGS_REG))]
6648   ""
6649   "add{b}\t{%h2, %h0|%h0, %h2}"
6650   [(set_attr "type" "alu")
6651    (set_attr "mode" "QI")])
6652
6653 ;; The patterns that match these are at the end of this file.
6654
6655 (define_expand "addxf3"
6656   [(set (match_operand:XF 0 "register_operand" "")
6657         (plus:XF (match_operand:XF 1 "register_operand" "")
6658                  (match_operand:XF 2 "register_operand" "")))]
6659   "TARGET_80387"
6660   "")
6661
6662 (define_expand "adddf3"
6663   [(set (match_operand:DF 0 "register_operand" "")
6664         (plus:DF (match_operand:DF 1 "register_operand" "")
6665                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6666   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6667   "")
6668
6669 (define_expand "addsf3"
6670   [(set (match_operand:SF 0 "register_operand" "")
6671         (plus:SF (match_operand:SF 1 "register_operand" "")
6672                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6673   "TARGET_80387 || TARGET_SSE_MATH"
6674   "")
6675 \f
6676 ;; Subtract instructions
6677
6678 ;; %%% splits for subsidi3
6679
6680 (define_expand "subdi3"
6681   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6682                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6683                              (match_operand:DI 2 "x86_64_general_operand" "")))
6684               (clobber (reg:CC FLAGS_REG))])]
6685   ""
6686   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6687
6688 (define_insn "*subdi3_1"
6689   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6690         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6691                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6692    (clobber (reg:CC FLAGS_REG))]
6693   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6694   "#")
6695
6696 (define_split
6697   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6698         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6699                   (match_operand:DI 2 "general_operand" "")))
6700    (clobber (reg:CC FLAGS_REG))]
6701   "!TARGET_64BIT && reload_completed"
6702   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6703               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6704    (parallel [(set (match_dup 3)
6705                    (minus:SI (match_dup 4)
6706                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6707                                       (match_dup 5))))
6708               (clobber (reg:CC FLAGS_REG))])]
6709   "split_di (operands+0, 1, operands+0, operands+3);
6710    split_di (operands+1, 1, operands+1, operands+4);
6711    split_di (operands+2, 1, operands+2, operands+5);")
6712
6713 (define_insn "subdi3_carry_rex64"
6714   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6715           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6716             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6717                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6718    (clobber (reg:CC FLAGS_REG))]
6719   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6720   "sbb{q}\t{%2, %0|%0, %2}"
6721   [(set_attr "type" "alu")
6722    (set_attr "pent_pair" "pu")
6723    (set_attr "mode" "DI")])
6724
6725 (define_insn "*subdi_1_rex64"
6726   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6727         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6728                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6729    (clobber (reg:CC FLAGS_REG))]
6730   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6731   "sub{q}\t{%2, %0|%0, %2}"
6732   [(set_attr "type" "alu")
6733    (set_attr "mode" "DI")])
6734
6735 (define_insn "*subdi_2_rex64"
6736   [(set (reg FLAGS_REG)
6737         (compare
6738           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6739                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6740           (const_int 0)))
6741    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6742         (minus:DI (match_dup 1) (match_dup 2)))]
6743   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6744    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6745   "sub{q}\t{%2, %0|%0, %2}"
6746   [(set_attr "type" "alu")
6747    (set_attr "mode" "DI")])
6748
6749 (define_insn "*subdi_3_rex63"
6750   [(set (reg FLAGS_REG)
6751         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6752                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6753    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6754         (minus:DI (match_dup 1) (match_dup 2)))]
6755   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6756    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6757   "sub{q}\t{%2, %0|%0, %2}"
6758   [(set_attr "type" "alu")
6759    (set_attr "mode" "DI")])
6760
6761 (define_insn "subqi3_carry"
6762   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6763           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6764             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6765                (match_operand:QI 2 "general_operand" "qi,qm"))))
6766    (clobber (reg:CC FLAGS_REG))]
6767   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6768   "sbb{b}\t{%2, %0|%0, %2}"
6769   [(set_attr "type" "alu")
6770    (set_attr "pent_pair" "pu")
6771    (set_attr "mode" "QI")])
6772
6773 (define_insn "subhi3_carry"
6774   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6775           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6776             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6777                (match_operand:HI 2 "general_operand" "ri,rm"))))
6778    (clobber (reg:CC FLAGS_REG))]
6779   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6780   "sbb{w}\t{%2, %0|%0, %2}"
6781   [(set_attr "type" "alu")
6782    (set_attr "pent_pair" "pu")
6783    (set_attr "mode" "HI")])
6784
6785 (define_insn "subsi3_carry"
6786   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6787           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6788             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6789                (match_operand:SI 2 "general_operand" "ri,rm"))))
6790    (clobber (reg:CC FLAGS_REG))]
6791   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6792   "sbb{l}\t{%2, %0|%0, %2}"
6793   [(set_attr "type" "alu")
6794    (set_attr "pent_pair" "pu")
6795    (set_attr "mode" "SI")])
6796
6797 (define_insn "subsi3_carry_zext"
6798   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6799           (zero_extend:DI
6800             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6801               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6802                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6803    (clobber (reg:CC FLAGS_REG))]
6804   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6805   "sbb{l}\t{%2, %k0|%k0, %2}"
6806   [(set_attr "type" "alu")
6807    (set_attr "pent_pair" "pu")
6808    (set_attr "mode" "SI")])
6809
6810 (define_expand "subsi3"
6811   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6812                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6813                              (match_operand:SI 2 "general_operand" "")))
6814               (clobber (reg:CC FLAGS_REG))])]
6815   ""
6816   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6817
6818 (define_insn "*subsi_1"
6819   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6820         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6821                   (match_operand:SI 2 "general_operand" "ri,rm")))
6822    (clobber (reg:CC FLAGS_REG))]
6823   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6824   "sub{l}\t{%2, %0|%0, %2}"
6825   [(set_attr "type" "alu")
6826    (set_attr "mode" "SI")])
6827
6828 (define_insn "*subsi_1_zext"
6829   [(set (match_operand:DI 0 "register_operand" "=r")
6830         (zero_extend:DI
6831           (minus:SI (match_operand:SI 1 "register_operand" "0")
6832                     (match_operand:SI 2 "general_operand" "rim"))))
6833    (clobber (reg:CC FLAGS_REG))]
6834   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6835   "sub{l}\t{%2, %k0|%k0, %2}"
6836   [(set_attr "type" "alu")
6837    (set_attr "mode" "SI")])
6838
6839 (define_insn "*subsi_2"
6840   [(set (reg FLAGS_REG)
6841         (compare
6842           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6843                     (match_operand:SI 2 "general_operand" "ri,rm"))
6844           (const_int 0)))
6845    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6846         (minus:SI (match_dup 1) (match_dup 2)))]
6847   "ix86_match_ccmode (insn, CCGOCmode)
6848    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6849   "sub{l}\t{%2, %0|%0, %2}"
6850   [(set_attr "type" "alu")
6851    (set_attr "mode" "SI")])
6852
6853 (define_insn "*subsi_2_zext"
6854   [(set (reg FLAGS_REG)
6855         (compare
6856           (minus:SI (match_operand:SI 1 "register_operand" "0")
6857                     (match_operand:SI 2 "general_operand" "rim"))
6858           (const_int 0)))
6859    (set (match_operand:DI 0 "register_operand" "=r")
6860         (zero_extend:DI
6861           (minus:SI (match_dup 1)
6862                     (match_dup 2))))]
6863   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6864    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6865   "sub{l}\t{%2, %k0|%k0, %2}"
6866   [(set_attr "type" "alu")
6867    (set_attr "mode" "SI")])
6868
6869 (define_insn "*subsi_3"
6870   [(set (reg FLAGS_REG)
6871         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6872                  (match_operand:SI 2 "general_operand" "ri,rm")))
6873    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6874         (minus:SI (match_dup 1) (match_dup 2)))]
6875   "ix86_match_ccmode (insn, CCmode)
6876    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6877   "sub{l}\t{%2, %0|%0, %2}"
6878   [(set_attr "type" "alu")
6879    (set_attr "mode" "SI")])
6880
6881 (define_insn "*subsi_3_zext"
6882   [(set (reg FLAGS_REG)
6883         (compare (match_operand:SI 1 "register_operand" "0")
6884                  (match_operand:SI 2 "general_operand" "rim")))
6885    (set (match_operand:DI 0 "register_operand" "=r")
6886         (zero_extend:DI
6887           (minus:SI (match_dup 1)
6888                     (match_dup 2))))]
6889   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6890    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6891   "sub{q}\t{%2, %0|%0, %2}"
6892   [(set_attr "type" "alu")
6893    (set_attr "mode" "DI")])
6894
6895 (define_expand "subhi3"
6896   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6897                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6898                              (match_operand:HI 2 "general_operand" "")))
6899               (clobber (reg:CC FLAGS_REG))])]
6900   "TARGET_HIMODE_MATH"
6901   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6902
6903 (define_insn "*subhi_1"
6904   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6905         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6906                   (match_operand:HI 2 "general_operand" "ri,rm")))
6907    (clobber (reg:CC FLAGS_REG))]
6908   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6909   "sub{w}\t{%2, %0|%0, %2}"
6910   [(set_attr "type" "alu")
6911    (set_attr "mode" "HI")])
6912
6913 (define_insn "*subhi_2"
6914   [(set (reg FLAGS_REG)
6915         (compare
6916           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6917                     (match_operand:HI 2 "general_operand" "ri,rm"))
6918           (const_int 0)))
6919    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6920         (minus:HI (match_dup 1) (match_dup 2)))]
6921   "ix86_match_ccmode (insn, CCGOCmode)
6922    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6923   "sub{w}\t{%2, %0|%0, %2}"
6924   [(set_attr "type" "alu")
6925    (set_attr "mode" "HI")])
6926
6927 (define_insn "*subhi_3"
6928   [(set (reg FLAGS_REG)
6929         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6930                  (match_operand:HI 2 "general_operand" "ri,rm")))
6931    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6932         (minus:HI (match_dup 1) (match_dup 2)))]
6933   "ix86_match_ccmode (insn, CCmode)
6934    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6935   "sub{w}\t{%2, %0|%0, %2}"
6936   [(set_attr "type" "alu")
6937    (set_attr "mode" "HI")])
6938
6939 (define_expand "subqi3"
6940   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6941                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6942                              (match_operand:QI 2 "general_operand" "")))
6943               (clobber (reg:CC FLAGS_REG))])]
6944   "TARGET_QIMODE_MATH"
6945   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6946
6947 (define_insn "*subqi_1"
6948   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6949         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6950                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6951    (clobber (reg:CC FLAGS_REG))]
6952   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6953   "sub{b}\t{%2, %0|%0, %2}"
6954   [(set_attr "type" "alu")
6955    (set_attr "mode" "QI")])
6956
6957 (define_insn "*subqi_1_slp"
6958   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6959         (minus:QI (match_dup 0)
6960                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6961    (clobber (reg:CC FLAGS_REG))]
6962   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6963    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6964   "sub{b}\t{%1, %0|%0, %1}"
6965   [(set_attr "type" "alu1")
6966    (set_attr "mode" "QI")])
6967
6968 (define_insn "*subqi_2"
6969   [(set (reg FLAGS_REG)
6970         (compare
6971           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6972                     (match_operand:QI 2 "general_operand" "qi,qm"))
6973           (const_int 0)))
6974    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6975         (minus:HI (match_dup 1) (match_dup 2)))]
6976   "ix86_match_ccmode (insn, CCGOCmode)
6977    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6978   "sub{b}\t{%2, %0|%0, %2}"
6979   [(set_attr "type" "alu")
6980    (set_attr "mode" "QI")])
6981
6982 (define_insn "*subqi_3"
6983   [(set (reg FLAGS_REG)
6984         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6985                  (match_operand:QI 2 "general_operand" "qi,qm")))
6986    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6987         (minus:HI (match_dup 1) (match_dup 2)))]
6988   "ix86_match_ccmode (insn, CCmode)
6989    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6990   "sub{b}\t{%2, %0|%0, %2}"
6991   [(set_attr "type" "alu")
6992    (set_attr "mode" "QI")])
6993
6994 ;; The patterns that match these are at the end of this file.
6995
6996 (define_expand "subxf3"
6997   [(set (match_operand:XF 0 "register_operand" "")
6998         (minus:XF (match_operand:XF 1 "register_operand" "")
6999                   (match_operand:XF 2 "register_operand" "")))]
7000   "TARGET_80387"
7001   "")
7002
7003 (define_expand "subdf3"
7004   [(set (match_operand:DF 0 "register_operand" "")
7005         (minus:DF (match_operand:DF 1 "register_operand" "")
7006                   (match_operand:DF 2 "nonimmediate_operand" "")))]
7007   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7008   "")
7009
7010 (define_expand "subsf3"
7011   [(set (match_operand:SF 0 "register_operand" "")
7012         (minus:SF (match_operand:SF 1 "register_operand" "")
7013                   (match_operand:SF 2 "nonimmediate_operand" "")))]
7014   "TARGET_80387 || TARGET_SSE_MATH"
7015   "")
7016 \f
7017 ;; Multiply instructions
7018
7019 (define_expand "muldi3"
7020   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7021                    (mult:DI (match_operand:DI 1 "register_operand" "")
7022                             (match_operand:DI 2 "x86_64_general_operand" "")))
7023               (clobber (reg:CC FLAGS_REG))])]
7024   "TARGET_64BIT"
7025   "")
7026
7027 (define_insn "*muldi3_1_rex64"
7028   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7029         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7030                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7031    (clobber (reg:CC FLAGS_REG))]
7032   "TARGET_64BIT
7033    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7034   "@
7035    imul{q}\t{%2, %1, %0|%0, %1, %2}
7036    imul{q}\t{%2, %1, %0|%0, %1, %2}
7037    imul{q}\t{%2, %0|%0, %2}"
7038   [(set_attr "type" "imul")
7039    (set_attr "prefix_0f" "0,0,1")
7040    (set (attr "athlon_decode")
7041         (cond [(eq_attr "cpu" "athlon")
7042                   (const_string "vector")
7043                (eq_attr "alternative" "1")
7044                   (const_string "vector")
7045                (and (eq_attr "alternative" "2")
7046                     (match_operand 1 "memory_operand" ""))
7047                   (const_string "vector")]
7048               (const_string "direct")))
7049    (set_attr "mode" "DI")])
7050
7051 (define_expand "mulsi3"
7052   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7053                    (mult:SI (match_operand:SI 1 "register_operand" "")
7054                             (match_operand:SI 2 "general_operand" "")))
7055               (clobber (reg:CC FLAGS_REG))])]
7056   ""
7057   "")
7058
7059 (define_insn "*mulsi3_1"
7060   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7061         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7062                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7063    (clobber (reg:CC FLAGS_REG))]
7064   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7065   "@
7066    imul{l}\t{%2, %1, %0|%0, %1, %2}
7067    imul{l}\t{%2, %1, %0|%0, %1, %2}
7068    imul{l}\t{%2, %0|%0, %2}"
7069   [(set_attr "type" "imul")
7070    (set_attr "prefix_0f" "0,0,1")
7071    (set (attr "athlon_decode")
7072         (cond [(eq_attr "cpu" "athlon")
7073                   (const_string "vector")
7074                (eq_attr "alternative" "1")
7075                   (const_string "vector")
7076                (and (eq_attr "alternative" "2")
7077                     (match_operand 1 "memory_operand" ""))
7078                   (const_string "vector")]
7079               (const_string "direct")))
7080    (set_attr "mode" "SI")])
7081
7082 (define_insn "*mulsi3_1_zext"
7083   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7084         (zero_extend:DI
7085           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7086                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7087    (clobber (reg:CC FLAGS_REG))]
7088   "TARGET_64BIT
7089    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7090   "@
7091    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7092    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7093    imul{l}\t{%2, %k0|%k0, %2}"
7094   [(set_attr "type" "imul")
7095    (set_attr "prefix_0f" "0,0,1")
7096    (set (attr "athlon_decode")
7097         (cond [(eq_attr "cpu" "athlon")
7098                   (const_string "vector")
7099                (eq_attr "alternative" "1")
7100                   (const_string "vector")
7101                (and (eq_attr "alternative" "2")
7102                     (match_operand 1 "memory_operand" ""))
7103                   (const_string "vector")]
7104               (const_string "direct")))
7105    (set_attr "mode" "SI")])
7106
7107 (define_expand "mulhi3"
7108   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7109                    (mult:HI (match_operand:HI 1 "register_operand" "")
7110                             (match_operand:HI 2 "general_operand" "")))
7111               (clobber (reg:CC FLAGS_REG))])]
7112   "TARGET_HIMODE_MATH"
7113   "")
7114
7115 (define_insn "*mulhi3_1"
7116   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7117         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7118                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7119    (clobber (reg:CC FLAGS_REG))]
7120   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7121   "@
7122    imul{w}\t{%2, %1, %0|%0, %1, %2}
7123    imul{w}\t{%2, %1, %0|%0, %1, %2}
7124    imul{w}\t{%2, %0|%0, %2}"
7125   [(set_attr "type" "imul")
7126    (set_attr "prefix_0f" "0,0,1")
7127    (set (attr "athlon_decode")
7128         (cond [(eq_attr "cpu" "athlon")
7129                   (const_string "vector")
7130                (eq_attr "alternative" "1,2")
7131                   (const_string "vector")]
7132               (const_string "direct")))
7133    (set_attr "mode" "HI")])
7134
7135 (define_expand "mulqi3"
7136   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7137                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7138                             (match_operand:QI 2 "register_operand" "")))
7139               (clobber (reg:CC FLAGS_REG))])]
7140   "TARGET_QIMODE_MATH"
7141   "")
7142
7143 (define_insn "*mulqi3_1"
7144   [(set (match_operand:QI 0 "register_operand" "=a")
7145         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7146                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7147    (clobber (reg:CC FLAGS_REG))]
7148   "TARGET_QIMODE_MATH
7149    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7150   "mul{b}\t%2"
7151   [(set_attr "type" "imul")
7152    (set_attr "length_immediate" "0")
7153    (set (attr "athlon_decode")
7154      (if_then_else (eq_attr "cpu" "athlon")
7155         (const_string "vector")
7156         (const_string "direct")))
7157    (set_attr "mode" "QI")])
7158
7159 (define_expand "umulqihi3"
7160   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7161                    (mult:HI (zero_extend:HI
7162                               (match_operand:QI 1 "nonimmediate_operand" ""))
7163                             (zero_extend:HI
7164                               (match_operand:QI 2 "register_operand" ""))))
7165               (clobber (reg:CC FLAGS_REG))])]
7166   "TARGET_QIMODE_MATH"
7167   "")
7168
7169 (define_insn "*umulqihi3_1"
7170   [(set (match_operand:HI 0 "register_operand" "=a")
7171         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7172                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7173    (clobber (reg:CC FLAGS_REG))]
7174   "TARGET_QIMODE_MATH
7175    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7176   "mul{b}\t%2"
7177   [(set_attr "type" "imul")
7178    (set_attr "length_immediate" "0")
7179    (set (attr "athlon_decode")
7180      (if_then_else (eq_attr "cpu" "athlon")
7181         (const_string "vector")
7182         (const_string "direct")))
7183    (set_attr "mode" "QI")])
7184
7185 (define_expand "mulqihi3"
7186   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7187                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7188                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7189               (clobber (reg:CC FLAGS_REG))])]
7190   "TARGET_QIMODE_MATH"
7191   "")
7192
7193 (define_insn "*mulqihi3_insn"
7194   [(set (match_operand:HI 0 "register_operand" "=a")
7195         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7196                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7197    (clobber (reg:CC FLAGS_REG))]
7198   "TARGET_QIMODE_MATH
7199    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7200   "imul{b}\t%2"
7201   [(set_attr "type" "imul")
7202    (set_attr "length_immediate" "0")
7203    (set (attr "athlon_decode")
7204      (if_then_else (eq_attr "cpu" "athlon")
7205         (const_string "vector")
7206         (const_string "direct")))
7207    (set_attr "mode" "QI")])
7208
7209 (define_expand "umulditi3"
7210   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7211                    (mult:TI (zero_extend:TI
7212                               (match_operand:DI 1 "nonimmediate_operand" ""))
7213                             (zero_extend:TI
7214                               (match_operand:DI 2 "register_operand" ""))))
7215               (clobber (reg:CC FLAGS_REG))])]
7216   "TARGET_64BIT"
7217   "")
7218
7219 (define_insn "*umulditi3_insn"
7220   [(set (match_operand:TI 0 "register_operand" "=A")
7221         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7222                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7223    (clobber (reg:CC FLAGS_REG))]
7224   "TARGET_64BIT
7225    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7226   "mul{q}\t%2"
7227   [(set_attr "type" "imul")
7228    (set_attr "length_immediate" "0")
7229    (set (attr "athlon_decode")
7230      (if_then_else (eq_attr "cpu" "athlon")
7231         (const_string "vector")
7232         (const_string "double")))
7233    (set_attr "mode" "DI")])
7234
7235 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7236 (define_expand "umulsidi3"
7237   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7238                    (mult:DI (zero_extend:DI
7239                               (match_operand:SI 1 "nonimmediate_operand" ""))
7240                             (zero_extend:DI
7241                               (match_operand:SI 2 "register_operand" ""))))
7242               (clobber (reg:CC FLAGS_REG))])]
7243   "!TARGET_64BIT"
7244   "")
7245
7246 (define_insn "*umulsidi3_insn"
7247   [(set (match_operand:DI 0 "register_operand" "=A")
7248         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7249                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7250    (clobber (reg:CC FLAGS_REG))]
7251   "!TARGET_64BIT
7252    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7253   "mul{l}\t%2"
7254   [(set_attr "type" "imul")
7255    (set_attr "length_immediate" "0")
7256    (set (attr "athlon_decode")
7257      (if_then_else (eq_attr "cpu" "athlon")
7258         (const_string "vector")
7259         (const_string "double")))
7260    (set_attr "mode" "SI")])
7261
7262 (define_expand "mulditi3"
7263   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7264                    (mult:TI (sign_extend:TI
7265                               (match_operand:DI 1 "nonimmediate_operand" ""))
7266                             (sign_extend:TI
7267                               (match_operand:DI 2 "register_operand" ""))))
7268               (clobber (reg:CC FLAGS_REG))])]
7269   "TARGET_64BIT"
7270   "")
7271
7272 (define_insn "*mulditi3_insn"
7273   [(set (match_operand:TI 0 "register_operand" "=A")
7274         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7275                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7276    (clobber (reg:CC FLAGS_REG))]
7277   "TARGET_64BIT
7278    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7279   "imul{q}\t%2"
7280   [(set_attr "type" "imul")
7281    (set_attr "length_immediate" "0")
7282    (set (attr "athlon_decode")
7283      (if_then_else (eq_attr "cpu" "athlon")
7284         (const_string "vector")
7285         (const_string "double")))
7286    (set_attr "mode" "DI")])
7287
7288 (define_expand "mulsidi3"
7289   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7290                    (mult:DI (sign_extend:DI
7291                               (match_operand:SI 1 "nonimmediate_operand" ""))
7292                             (sign_extend:DI
7293                               (match_operand:SI 2 "register_operand" ""))))
7294               (clobber (reg:CC FLAGS_REG))])]
7295   "!TARGET_64BIT"
7296   "")
7297
7298 (define_insn "*mulsidi3_insn"
7299   [(set (match_operand:DI 0 "register_operand" "=A")
7300         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7301                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7302    (clobber (reg:CC FLAGS_REG))]
7303   "!TARGET_64BIT
7304    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7305   "imul{l}\t%2"
7306   [(set_attr "type" "imul")
7307    (set_attr "length_immediate" "0")
7308    (set (attr "athlon_decode")
7309      (if_then_else (eq_attr "cpu" "athlon")
7310         (const_string "vector")
7311         (const_string "double")))
7312    (set_attr "mode" "SI")])
7313
7314 (define_expand "umuldi3_highpart"
7315   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7316                    (truncate:DI
7317                      (lshiftrt:TI
7318                        (mult:TI (zero_extend:TI
7319                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7320                                 (zero_extend:TI
7321                                   (match_operand:DI 2 "register_operand" "")))
7322                        (const_int 64))))
7323               (clobber (match_scratch:DI 3 ""))
7324               (clobber (reg:CC FLAGS_REG))])]
7325   "TARGET_64BIT"
7326   "")
7327
7328 (define_insn "*umuldi3_highpart_rex64"
7329   [(set (match_operand:DI 0 "register_operand" "=d")
7330         (truncate:DI
7331           (lshiftrt:TI
7332             (mult:TI (zero_extend:TI
7333                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7334                      (zero_extend:TI
7335                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7336             (const_int 64))))
7337    (clobber (match_scratch:DI 3 "=1"))
7338    (clobber (reg:CC FLAGS_REG))]
7339   "TARGET_64BIT
7340    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7341   "mul{q}\t%2"
7342   [(set_attr "type" "imul")
7343    (set_attr "length_immediate" "0")
7344    (set (attr "athlon_decode")
7345      (if_then_else (eq_attr "cpu" "athlon")
7346         (const_string "vector")
7347         (const_string "double")))
7348    (set_attr "mode" "DI")])
7349
7350 (define_expand "umulsi3_highpart"
7351   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7352                    (truncate:SI
7353                      (lshiftrt:DI
7354                        (mult:DI (zero_extend:DI
7355                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7356                                 (zero_extend:DI
7357                                   (match_operand:SI 2 "register_operand" "")))
7358                        (const_int 32))))
7359               (clobber (match_scratch:SI 3 ""))
7360               (clobber (reg:CC FLAGS_REG))])]
7361   ""
7362   "")
7363
7364 (define_insn "*umulsi3_highpart_insn"
7365   [(set (match_operand:SI 0 "register_operand" "=d")
7366         (truncate:SI
7367           (lshiftrt:DI
7368             (mult:DI (zero_extend:DI
7369                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7370                      (zero_extend:DI
7371                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7372             (const_int 32))))
7373    (clobber (match_scratch:SI 3 "=1"))
7374    (clobber (reg:CC FLAGS_REG))]
7375   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7376   "mul{l}\t%2"
7377   [(set_attr "type" "imul")
7378    (set_attr "length_immediate" "0")
7379    (set (attr "athlon_decode")
7380      (if_then_else (eq_attr "cpu" "athlon")
7381         (const_string "vector")
7382         (const_string "double")))
7383    (set_attr "mode" "SI")])
7384
7385 (define_insn "*umulsi3_highpart_zext"
7386   [(set (match_operand:DI 0 "register_operand" "=d")
7387         (zero_extend:DI (truncate:SI
7388           (lshiftrt:DI
7389             (mult:DI (zero_extend:DI
7390                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7391                      (zero_extend:DI
7392                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7393             (const_int 32)))))
7394    (clobber (match_scratch:SI 3 "=1"))
7395    (clobber (reg:CC FLAGS_REG))]
7396   "TARGET_64BIT
7397    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7398   "mul{l}\t%2"
7399   [(set_attr "type" "imul")
7400    (set_attr "length_immediate" "0")
7401    (set (attr "athlon_decode")
7402      (if_then_else (eq_attr "cpu" "athlon")
7403         (const_string "vector")
7404         (const_string "double")))
7405    (set_attr "mode" "SI")])
7406
7407 (define_expand "smuldi3_highpart"
7408   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7409                    (truncate:DI
7410                      (lshiftrt:TI
7411                        (mult:TI (sign_extend:TI
7412                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7413                                 (sign_extend:TI
7414                                   (match_operand:DI 2 "register_operand" "")))
7415                        (const_int 64))))
7416               (clobber (match_scratch:DI 3 ""))
7417               (clobber (reg:CC FLAGS_REG))])]
7418   "TARGET_64BIT"
7419   "")
7420
7421 (define_insn "*smuldi3_highpart_rex64"
7422   [(set (match_operand:DI 0 "register_operand" "=d")
7423         (truncate:DI
7424           (lshiftrt:TI
7425             (mult:TI (sign_extend:TI
7426                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7427                      (sign_extend:TI
7428                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7429             (const_int 64))))
7430    (clobber (match_scratch:DI 3 "=1"))
7431    (clobber (reg:CC FLAGS_REG))]
7432   "TARGET_64BIT
7433    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7434   "imul{q}\t%2"
7435   [(set_attr "type" "imul")
7436    (set (attr "athlon_decode")
7437      (if_then_else (eq_attr "cpu" "athlon")
7438         (const_string "vector")
7439         (const_string "double")))
7440    (set_attr "mode" "DI")])
7441
7442 (define_expand "smulsi3_highpart"
7443   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7444                    (truncate:SI
7445                      (lshiftrt:DI
7446                        (mult:DI (sign_extend:DI
7447                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7448                                 (sign_extend:DI
7449                                   (match_operand:SI 2 "register_operand" "")))
7450                        (const_int 32))))
7451               (clobber (match_scratch:SI 3 ""))
7452               (clobber (reg:CC FLAGS_REG))])]
7453   ""
7454   "")
7455
7456 (define_insn "*smulsi3_highpart_insn"
7457   [(set (match_operand:SI 0 "register_operand" "=d")
7458         (truncate:SI
7459           (lshiftrt:DI
7460             (mult:DI (sign_extend:DI
7461                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7462                      (sign_extend:DI
7463                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7464             (const_int 32))))
7465    (clobber (match_scratch:SI 3 "=1"))
7466    (clobber (reg:CC FLAGS_REG))]
7467   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7468   "imul{l}\t%2"
7469   [(set_attr "type" "imul")
7470    (set (attr "athlon_decode")
7471      (if_then_else (eq_attr "cpu" "athlon")
7472         (const_string "vector")
7473         (const_string "double")))
7474    (set_attr "mode" "SI")])
7475
7476 (define_insn "*smulsi3_highpart_zext"
7477   [(set (match_operand:DI 0 "register_operand" "=d")
7478         (zero_extend:DI (truncate:SI
7479           (lshiftrt:DI
7480             (mult:DI (sign_extend:DI
7481                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7482                      (sign_extend:DI
7483                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7484             (const_int 32)))))
7485    (clobber (match_scratch:SI 3 "=1"))
7486    (clobber (reg:CC FLAGS_REG))]
7487   "TARGET_64BIT
7488    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7489   "imul{l}\t%2"
7490   [(set_attr "type" "imul")
7491    (set (attr "athlon_decode")
7492      (if_then_else (eq_attr "cpu" "athlon")
7493         (const_string "vector")
7494         (const_string "double")))
7495    (set_attr "mode" "SI")])
7496
7497 ;; The patterns that match these are at the end of this file.
7498
7499 (define_expand "mulxf3"
7500   [(set (match_operand:XF 0 "register_operand" "")
7501         (mult:XF (match_operand:XF 1 "register_operand" "")
7502                  (match_operand:XF 2 "register_operand" "")))]
7503   "TARGET_80387"
7504   "")
7505
7506 (define_expand "muldf3"
7507   [(set (match_operand:DF 0 "register_operand" "")
7508         (mult:DF (match_operand:DF 1 "register_operand" "")
7509                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7510   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7511   "")
7512
7513 (define_expand "mulsf3"
7514   [(set (match_operand:SF 0 "register_operand" "")
7515         (mult:SF (match_operand:SF 1 "register_operand" "")
7516                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7517   "TARGET_80387 || TARGET_SSE_MATH"
7518   "")
7519 \f
7520 ;; Divide instructions
7521
7522 (define_insn "divqi3"
7523   [(set (match_operand:QI 0 "register_operand" "=a")
7524         (div:QI (match_operand:HI 1 "register_operand" "0")
7525                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7526    (clobber (reg:CC FLAGS_REG))]
7527   "TARGET_QIMODE_MATH"
7528   "idiv{b}\t%2"
7529   [(set_attr "type" "idiv")
7530    (set_attr "mode" "QI")])
7531
7532 (define_insn "udivqi3"
7533   [(set (match_operand:QI 0 "register_operand" "=a")
7534         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7535                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7536    (clobber (reg:CC FLAGS_REG))]
7537   "TARGET_QIMODE_MATH"
7538   "div{b}\t%2"
7539   [(set_attr "type" "idiv")
7540    (set_attr "mode" "QI")])
7541
7542 ;; The patterns that match these are at the end of this file.
7543
7544 (define_expand "divxf3"
7545   [(set (match_operand:XF 0 "register_operand" "")
7546         (div:XF (match_operand:XF 1 "register_operand" "")
7547                 (match_operand:XF 2 "register_operand" "")))]
7548   "TARGET_80387"
7549   "")
7550
7551 (define_expand "divdf3"
7552   [(set (match_operand:DF 0 "register_operand" "")
7553         (div:DF (match_operand:DF 1 "register_operand" "")
7554                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7555    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7556    "")
7557  
7558 (define_expand "divsf3"
7559   [(set (match_operand:SF 0 "register_operand" "")
7560         (div:SF (match_operand:SF 1 "register_operand" "")
7561                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7562   "TARGET_80387 || TARGET_SSE_MATH"
7563   "")
7564 \f
7565 ;; Remainder instructions.
7566
7567 (define_expand "divmoddi4"
7568   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7569                    (div:DI (match_operand:DI 1 "register_operand" "")
7570                            (match_operand:DI 2 "nonimmediate_operand" "")))
7571               (set (match_operand:DI 3 "register_operand" "")
7572                    (mod:DI (match_dup 1) (match_dup 2)))
7573               (clobber (reg:CC FLAGS_REG))])]
7574   "TARGET_64BIT"
7575   "")
7576
7577 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7578 ;; Penalize eax case slightly because it results in worse scheduling
7579 ;; of code.
7580 (define_insn "*divmoddi4_nocltd_rex64"
7581   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7582         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7583                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7584    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7585         (mod:DI (match_dup 2) (match_dup 3)))
7586    (clobber (reg:CC FLAGS_REG))]
7587   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7588   "#"
7589   [(set_attr "type" "multi")])
7590
7591 (define_insn "*divmoddi4_cltd_rex64"
7592   [(set (match_operand:DI 0 "register_operand" "=a")
7593         (div:DI (match_operand:DI 2 "register_operand" "a")
7594                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7595    (set (match_operand:DI 1 "register_operand" "=&d")
7596         (mod:DI (match_dup 2) (match_dup 3)))
7597    (clobber (reg:CC FLAGS_REG))]
7598   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7599   "#"
7600   [(set_attr "type" "multi")])
7601
7602 (define_insn "*divmoddi_noext_rex64"
7603   [(set (match_operand:DI 0 "register_operand" "=a")
7604         (div:DI (match_operand:DI 1 "register_operand" "0")
7605                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7606    (set (match_operand:DI 3 "register_operand" "=d")
7607         (mod:DI (match_dup 1) (match_dup 2)))
7608    (use (match_operand:DI 4 "register_operand" "3"))
7609    (clobber (reg:CC FLAGS_REG))]
7610   "TARGET_64BIT"
7611   "idiv{q}\t%2"
7612   [(set_attr "type" "idiv")
7613    (set_attr "mode" "DI")])
7614
7615 (define_split
7616   [(set (match_operand:DI 0 "register_operand" "")
7617         (div:DI (match_operand:DI 1 "register_operand" "")
7618                 (match_operand:DI 2 "nonimmediate_operand" "")))
7619    (set (match_operand:DI 3 "register_operand" "")
7620         (mod:DI (match_dup 1) (match_dup 2)))
7621    (clobber (reg:CC FLAGS_REG))]
7622   "TARGET_64BIT && reload_completed"
7623   [(parallel [(set (match_dup 3)
7624                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7625               (clobber (reg:CC FLAGS_REG))])
7626    (parallel [(set (match_dup 0)
7627                    (div:DI (reg:DI 0) (match_dup 2)))
7628               (set (match_dup 3)
7629                    (mod:DI (reg:DI 0) (match_dup 2)))
7630               (use (match_dup 3))
7631               (clobber (reg:CC FLAGS_REG))])]
7632 {
7633   /* Avoid use of cltd in favor of a mov+shift.  */
7634   if (!TARGET_USE_CLTD && !optimize_size)
7635     {
7636       if (true_regnum (operands[1]))
7637         emit_move_insn (operands[0], operands[1]);
7638       else
7639         emit_move_insn (operands[3], operands[1]);
7640       operands[4] = operands[3];
7641     }
7642   else
7643     {
7644       if (true_regnum (operands[1]))
7645         abort();
7646       operands[4] = operands[1];
7647     }
7648 })
7649
7650
7651 (define_expand "divmodsi4"
7652   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7653                    (div:SI (match_operand:SI 1 "register_operand" "")
7654                            (match_operand:SI 2 "nonimmediate_operand" "")))
7655               (set (match_operand:SI 3 "register_operand" "")
7656                    (mod:SI (match_dup 1) (match_dup 2)))
7657               (clobber (reg:CC FLAGS_REG))])]
7658   ""
7659   "")
7660
7661 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7662 ;; Penalize eax case slightly because it results in worse scheduling
7663 ;; of code.
7664 (define_insn "*divmodsi4_nocltd"
7665   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7666         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7667                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7668    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7669         (mod:SI (match_dup 2) (match_dup 3)))
7670    (clobber (reg:CC FLAGS_REG))]
7671   "!optimize_size && !TARGET_USE_CLTD"
7672   "#"
7673   [(set_attr "type" "multi")])
7674
7675 (define_insn "*divmodsi4_cltd"
7676   [(set (match_operand:SI 0 "register_operand" "=a")
7677         (div:SI (match_operand:SI 2 "register_operand" "a")
7678                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7679    (set (match_operand:SI 1 "register_operand" "=&d")
7680         (mod:SI (match_dup 2) (match_dup 3)))
7681    (clobber (reg:CC FLAGS_REG))]
7682   "optimize_size || TARGET_USE_CLTD"
7683   "#"
7684   [(set_attr "type" "multi")])
7685
7686 (define_insn "*divmodsi_noext"
7687   [(set (match_operand:SI 0 "register_operand" "=a")
7688         (div:SI (match_operand:SI 1 "register_operand" "0")
7689                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7690    (set (match_operand:SI 3 "register_operand" "=d")
7691         (mod:SI (match_dup 1) (match_dup 2)))
7692    (use (match_operand:SI 4 "register_operand" "3"))
7693    (clobber (reg:CC FLAGS_REG))]
7694   ""
7695   "idiv{l}\t%2"
7696   [(set_attr "type" "idiv")
7697    (set_attr "mode" "SI")])
7698
7699 (define_split
7700   [(set (match_operand:SI 0 "register_operand" "")
7701         (div:SI (match_operand:SI 1 "register_operand" "")
7702                 (match_operand:SI 2 "nonimmediate_operand" "")))
7703    (set (match_operand:SI 3 "register_operand" "")
7704         (mod:SI (match_dup 1) (match_dup 2)))
7705    (clobber (reg:CC FLAGS_REG))]
7706   "reload_completed"
7707   [(parallel [(set (match_dup 3)
7708                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7709               (clobber (reg:CC FLAGS_REG))])
7710    (parallel [(set (match_dup 0)
7711                    (div:SI (reg:SI 0) (match_dup 2)))
7712               (set (match_dup 3)
7713                    (mod:SI (reg:SI 0) (match_dup 2)))
7714               (use (match_dup 3))
7715               (clobber (reg:CC FLAGS_REG))])]
7716 {
7717   /* Avoid use of cltd in favor of a mov+shift.  */
7718   if (!TARGET_USE_CLTD && !optimize_size)
7719     {
7720       if (true_regnum (operands[1]))
7721         emit_move_insn (operands[0], operands[1]);
7722       else
7723         emit_move_insn (operands[3], operands[1]);
7724       operands[4] = operands[3];
7725     }
7726   else
7727     {
7728       if (true_regnum (operands[1]))
7729         abort();
7730       operands[4] = operands[1];
7731     }
7732 })
7733 ;; %%% Split me.
7734 (define_insn "divmodhi4"
7735   [(set (match_operand:HI 0 "register_operand" "=a")
7736         (div:HI (match_operand:HI 1 "register_operand" "0")
7737                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7738    (set (match_operand:HI 3 "register_operand" "=&d")
7739         (mod:HI (match_dup 1) (match_dup 2)))
7740    (clobber (reg:CC FLAGS_REG))]
7741   "TARGET_HIMODE_MATH"
7742   "cwtd\;idiv{w}\t%2"
7743   [(set_attr "type" "multi")
7744    (set_attr "length_immediate" "0")
7745    (set_attr "mode" "SI")])
7746
7747 (define_insn "udivmoddi4"
7748   [(set (match_operand:DI 0 "register_operand" "=a")
7749         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7750                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7751    (set (match_operand:DI 3 "register_operand" "=&d")
7752         (umod:DI (match_dup 1) (match_dup 2)))
7753    (clobber (reg:CC FLAGS_REG))]
7754   "TARGET_64BIT"
7755   "xor{q}\t%3, %3\;div{q}\t%2"
7756   [(set_attr "type" "multi")
7757    (set_attr "length_immediate" "0")
7758    (set_attr "mode" "DI")])
7759
7760 (define_insn "*udivmoddi4_noext"
7761   [(set (match_operand:DI 0 "register_operand" "=a")
7762         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7763                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7764    (set (match_operand:DI 3 "register_operand" "=d")
7765         (umod:DI (match_dup 1) (match_dup 2)))
7766    (use (match_dup 3))
7767    (clobber (reg:CC FLAGS_REG))]
7768   "TARGET_64BIT"
7769   "div{q}\t%2"
7770   [(set_attr "type" "idiv")
7771    (set_attr "mode" "DI")])
7772
7773 (define_split
7774   [(set (match_operand:DI 0 "register_operand" "")
7775         (udiv:DI (match_operand:DI 1 "register_operand" "")
7776                  (match_operand:DI 2 "nonimmediate_operand" "")))
7777    (set (match_operand:DI 3 "register_operand" "")
7778         (umod:DI (match_dup 1) (match_dup 2)))
7779    (clobber (reg:CC FLAGS_REG))]
7780   "TARGET_64BIT && reload_completed"
7781   [(set (match_dup 3) (const_int 0))
7782    (parallel [(set (match_dup 0)
7783                    (udiv:DI (match_dup 1) (match_dup 2)))
7784               (set (match_dup 3)
7785                    (umod:DI (match_dup 1) (match_dup 2)))
7786               (use (match_dup 3))
7787               (clobber (reg:CC FLAGS_REG))])]
7788   "")
7789
7790 (define_insn "udivmodsi4"
7791   [(set (match_operand:SI 0 "register_operand" "=a")
7792         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7793                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7794    (set (match_operand:SI 3 "register_operand" "=&d")
7795         (umod:SI (match_dup 1) (match_dup 2)))
7796    (clobber (reg:CC FLAGS_REG))]
7797   ""
7798   "xor{l}\t%3, %3\;div{l}\t%2"
7799   [(set_attr "type" "multi")
7800    (set_attr "length_immediate" "0")
7801    (set_attr "mode" "SI")])
7802
7803 (define_insn "*udivmodsi4_noext"
7804   [(set (match_operand:SI 0 "register_operand" "=a")
7805         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7806                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7807    (set (match_operand:SI 3 "register_operand" "=d")
7808         (umod:SI (match_dup 1) (match_dup 2)))
7809    (use (match_dup 3))
7810    (clobber (reg:CC FLAGS_REG))]
7811   ""
7812   "div{l}\t%2"
7813   [(set_attr "type" "idiv")
7814    (set_attr "mode" "SI")])
7815
7816 (define_split
7817   [(set (match_operand:SI 0 "register_operand" "")
7818         (udiv:SI (match_operand:SI 1 "register_operand" "")
7819                  (match_operand:SI 2 "nonimmediate_operand" "")))
7820    (set (match_operand:SI 3 "register_operand" "")
7821         (umod:SI (match_dup 1) (match_dup 2)))
7822    (clobber (reg:CC FLAGS_REG))]
7823   "reload_completed"
7824   [(set (match_dup 3) (const_int 0))
7825    (parallel [(set (match_dup 0)
7826                    (udiv:SI (match_dup 1) (match_dup 2)))
7827               (set (match_dup 3)
7828                    (umod:SI (match_dup 1) (match_dup 2)))
7829               (use (match_dup 3))
7830               (clobber (reg:CC FLAGS_REG))])]
7831   "")
7832
7833 (define_expand "udivmodhi4"
7834   [(set (match_dup 4) (const_int 0))
7835    (parallel [(set (match_operand:HI 0 "register_operand" "")
7836                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7837                             (match_operand:HI 2 "nonimmediate_operand" "")))
7838               (set (match_operand:HI 3 "register_operand" "")
7839                    (umod:HI (match_dup 1) (match_dup 2)))
7840               (use (match_dup 4))
7841               (clobber (reg:CC FLAGS_REG))])]
7842   "TARGET_HIMODE_MATH"
7843   "operands[4] = gen_reg_rtx (HImode);")
7844
7845 (define_insn "*udivmodhi_noext"
7846   [(set (match_operand:HI 0 "register_operand" "=a")
7847         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7848                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7849    (set (match_operand:HI 3 "register_operand" "=d")
7850         (umod:HI (match_dup 1) (match_dup 2)))
7851    (use (match_operand:HI 4 "register_operand" "3"))
7852    (clobber (reg:CC FLAGS_REG))]
7853   ""
7854   "div{w}\t%2"
7855   [(set_attr "type" "idiv")
7856    (set_attr "mode" "HI")])
7857
7858 ;; We cannot use div/idiv for double division, because it causes
7859 ;; "division by zero" on the overflow and that's not what we expect
7860 ;; from truncate.  Because true (non truncating) double division is
7861 ;; never generated, we can't create this insn anyway.
7862 ;
7863 ;(define_insn ""
7864 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7865 ;       (truncate:SI
7866 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7867 ;                  (zero_extend:DI
7868 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7869 ;   (set (match_operand:SI 3 "register_operand" "=d")
7870 ;       (truncate:SI
7871 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7872 ;   (clobber (reg:CC FLAGS_REG))]
7873 ;  ""
7874 ;  "div{l}\t{%2, %0|%0, %2}"
7875 ;  [(set_attr "type" "idiv")])
7876 \f
7877 ;;- Logical AND instructions
7878
7879 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7880 ;; Note that this excludes ah.
7881
7882 (define_insn "*testdi_1_rex64"
7883   [(set (reg FLAGS_REG)
7884         (compare
7885           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7886                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7887           (const_int 0)))]
7888   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7889    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7890   "@
7891    test{l}\t{%k1, %k0|%k0, %k1}
7892    test{l}\t{%k1, %k0|%k0, %k1}
7893    test{q}\t{%1, %0|%0, %1}
7894    test{q}\t{%1, %0|%0, %1}
7895    test{q}\t{%1, %0|%0, %1}"
7896   [(set_attr "type" "test")
7897    (set_attr "modrm" "0,1,0,1,1")
7898    (set_attr "mode" "SI,SI,DI,DI,DI")
7899    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7900
7901 (define_insn "testsi_1"
7902   [(set (reg FLAGS_REG)
7903         (compare
7904           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7905                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7906           (const_int 0)))]
7907   "ix86_match_ccmode (insn, CCNOmode)
7908    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7909   "test{l}\t{%1, %0|%0, %1}"
7910   [(set_attr "type" "test")
7911    (set_attr "modrm" "0,1,1")
7912    (set_attr "mode" "SI")
7913    (set_attr "pent_pair" "uv,np,uv")])
7914
7915 (define_expand "testsi_ccno_1"
7916   [(set (reg:CCNO FLAGS_REG)
7917         (compare:CCNO
7918           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7919                   (match_operand:SI 1 "nonmemory_operand" ""))
7920           (const_int 0)))]
7921   ""
7922   "")
7923
7924 (define_insn "*testhi_1"
7925   [(set (reg FLAGS_REG)
7926         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7927                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7928                  (const_int 0)))]
7929   "ix86_match_ccmode (insn, CCNOmode)
7930    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7931   "test{w}\t{%1, %0|%0, %1}"
7932   [(set_attr "type" "test")
7933    (set_attr "modrm" "0,1,1")
7934    (set_attr "mode" "HI")
7935    (set_attr "pent_pair" "uv,np,uv")])
7936
7937 (define_expand "testqi_ccz_1"
7938   [(set (reg:CCZ FLAGS_REG)
7939         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7940                              (match_operand:QI 1 "nonmemory_operand" ""))
7941                  (const_int 0)))]
7942   ""
7943   "")
7944
7945 (define_insn "*testqi_1_maybe_si"
7946   [(set (reg FLAGS_REG)
7947         (compare
7948           (and:QI
7949             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7950             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7951           (const_int 0)))]
7952    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7953     && ix86_match_ccmode (insn,
7954                          GET_CODE (operands[1]) == CONST_INT
7955                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7956 {
7957   if (which_alternative == 3)
7958     {
7959       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7960         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7961       return "test{l}\t{%1, %k0|%k0, %1}";
7962     }
7963   return "test{b}\t{%1, %0|%0, %1}";
7964 }
7965   [(set_attr "type" "test")
7966    (set_attr "modrm" "0,1,1,1")
7967    (set_attr "mode" "QI,QI,QI,SI")
7968    (set_attr "pent_pair" "uv,np,uv,np")])
7969
7970 (define_insn "*testqi_1"
7971   [(set (reg FLAGS_REG)
7972         (compare
7973           (and:QI
7974             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7975             (match_operand:QI 1 "general_operand" "n,n,qn"))
7976           (const_int 0)))]
7977   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7978    && ix86_match_ccmode (insn, CCNOmode)"
7979   "test{b}\t{%1, %0|%0, %1}"
7980   [(set_attr "type" "test")
7981    (set_attr "modrm" "0,1,1")
7982    (set_attr "mode" "QI")
7983    (set_attr "pent_pair" "uv,np,uv")])
7984
7985 (define_expand "testqi_ext_ccno_0"
7986   [(set (reg:CCNO FLAGS_REG)
7987         (compare:CCNO
7988           (and:SI
7989             (zero_extract:SI
7990               (match_operand 0 "ext_register_operand" "")
7991               (const_int 8)
7992               (const_int 8))
7993             (match_operand 1 "const_int_operand" ""))
7994           (const_int 0)))]
7995   ""
7996   "")
7997
7998 (define_insn "*testqi_ext_0"
7999   [(set (reg FLAGS_REG)
8000         (compare
8001           (and:SI
8002             (zero_extract:SI
8003               (match_operand 0 "ext_register_operand" "Q")
8004               (const_int 8)
8005               (const_int 8))
8006             (match_operand 1 "const_int_operand" "n"))
8007           (const_int 0)))]
8008   "ix86_match_ccmode (insn, CCNOmode)"
8009   "test{b}\t{%1, %h0|%h0, %1}"
8010   [(set_attr "type" "test")
8011    (set_attr "mode" "QI")
8012    (set_attr "length_immediate" "1")
8013    (set_attr "pent_pair" "np")])
8014
8015 (define_insn "*testqi_ext_1"
8016   [(set (reg FLAGS_REG)
8017         (compare
8018           (and:SI
8019             (zero_extract:SI
8020               (match_operand 0 "ext_register_operand" "Q")
8021               (const_int 8)
8022               (const_int 8))
8023             (zero_extend:SI
8024               (match_operand:QI 1 "general_operand" "Qm")))
8025           (const_int 0)))]
8026   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8027    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8028   "test{b}\t{%1, %h0|%h0, %1}"
8029   [(set_attr "type" "test")
8030    (set_attr "mode" "QI")])
8031
8032 (define_insn "*testqi_ext_1_rex64"
8033   [(set (reg FLAGS_REG)
8034         (compare
8035           (and:SI
8036             (zero_extract:SI
8037               (match_operand 0 "ext_register_operand" "Q")
8038               (const_int 8)
8039               (const_int 8))
8040             (zero_extend:SI
8041               (match_operand:QI 1 "register_operand" "Q")))
8042           (const_int 0)))]
8043   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8044   "test{b}\t{%1, %h0|%h0, %1}"
8045   [(set_attr "type" "test")
8046    (set_attr "mode" "QI")])
8047
8048 (define_insn "*testqi_ext_2"
8049   [(set (reg FLAGS_REG)
8050         (compare
8051           (and:SI
8052             (zero_extract:SI
8053               (match_operand 0 "ext_register_operand" "Q")
8054               (const_int 8)
8055               (const_int 8))
8056             (zero_extract:SI
8057               (match_operand 1 "ext_register_operand" "Q")
8058               (const_int 8)
8059               (const_int 8)))
8060           (const_int 0)))]
8061   "ix86_match_ccmode (insn, CCNOmode)"
8062   "test{b}\t{%h1, %h0|%h0, %h1}"
8063   [(set_attr "type" "test")
8064    (set_attr "mode" "QI")])
8065
8066 ;; Combine likes to form bit extractions for some tests.  Humor it.
8067 (define_insn "*testqi_ext_3"
8068   [(set (reg FLAGS_REG)
8069         (compare (zero_extract:SI
8070                    (match_operand 0 "nonimmediate_operand" "rm")
8071                    (match_operand:SI 1 "const_int_operand" "")
8072                    (match_operand:SI 2 "const_int_operand" ""))
8073                  (const_int 0)))]
8074   "ix86_match_ccmode (insn, CCNOmode)
8075    && (GET_MODE (operands[0]) == SImode
8076        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8077        || GET_MODE (operands[0]) == HImode
8078        || GET_MODE (operands[0]) == QImode)"
8079   "#")
8080
8081 (define_insn "*testqi_ext_3_rex64"
8082   [(set (reg FLAGS_REG)
8083         (compare (zero_extract:DI
8084                    (match_operand 0 "nonimmediate_operand" "rm")
8085                    (match_operand:DI 1 "const_int_operand" "")
8086                    (match_operand:DI 2 "const_int_operand" ""))
8087                  (const_int 0)))]
8088   "TARGET_64BIT
8089    && ix86_match_ccmode (insn, CCNOmode)
8090    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
8091    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8092    /* Ensure that resulting mask is zero or sign extended operand.  */
8093    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8094        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8095            && INTVAL (operands[1]) > 32))
8096    && (GET_MODE (operands[0]) == SImode
8097        || GET_MODE (operands[0]) == DImode
8098        || GET_MODE (operands[0]) == HImode
8099        || GET_MODE (operands[0]) == QImode)"
8100   "#")
8101
8102 (define_split
8103   [(set (match_operand 0 "flags_reg_operand" "")
8104         (match_operator 1 "compare_operator"
8105           [(zero_extract
8106              (match_operand 2 "nonimmediate_operand" "")
8107              (match_operand 3 "const_int_operand" "")
8108              (match_operand 4 "const_int_operand" ""))
8109            (const_int 0)]))]
8110   "ix86_match_ccmode (insn, CCNOmode)"
8111   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8112 {
8113   rtx val = operands[2];
8114   HOST_WIDE_INT len = INTVAL (operands[3]);
8115   HOST_WIDE_INT pos = INTVAL (operands[4]);
8116   HOST_WIDE_INT mask;
8117   enum machine_mode mode, submode;
8118
8119   mode = GET_MODE (val);
8120   if (GET_CODE (val) == MEM)
8121     {
8122       /* ??? Combine likes to put non-volatile mem extractions in QImode
8123          no matter the size of the test.  So find a mode that works.  */
8124       if (! MEM_VOLATILE_P (val))
8125         {
8126           mode = smallest_mode_for_size (pos + len, MODE_INT);
8127           val = adjust_address (val, mode, 0);
8128         }
8129     }
8130   else if (GET_CODE (val) == SUBREG
8131            && (submode = GET_MODE (SUBREG_REG (val)),
8132                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8133            && pos + len <= GET_MODE_BITSIZE (submode))
8134     {
8135       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8136       mode = submode;
8137       val = SUBREG_REG (val);
8138     }
8139   else if (mode == HImode && pos + len <= 8)
8140     {
8141       /* Small HImode tests can be converted to QImode.  */
8142       mode = QImode;
8143       val = gen_lowpart (QImode, val);
8144     }
8145
8146   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8147   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8148
8149   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8150 })
8151
8152 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8153 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8154 ;; this is relatively important trick.
8155 ;; Do the conversion only post-reload to avoid limiting of the register class
8156 ;; to QI regs.
8157 (define_split
8158   [(set (match_operand 0 "flags_reg_operand" "")
8159         (match_operator 1 "compare_operator"
8160           [(and (match_operand 2 "register_operand" "")
8161                 (match_operand 3 "const_int_operand" ""))
8162            (const_int 0)]))]
8163    "reload_completed
8164     && QI_REG_P (operands[2])
8165     && GET_MODE (operands[2]) != QImode
8166     && ((ix86_match_ccmode (insn, CCZmode)
8167          && !(INTVAL (operands[3]) & ~(255 << 8)))
8168         || (ix86_match_ccmode (insn, CCNOmode)
8169             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8170   [(set (match_dup 0)
8171         (match_op_dup 1
8172           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8173                    (match_dup 3))
8174            (const_int 0)]))]
8175   "operands[2] = gen_lowpart (SImode, operands[2]);
8176    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8177
8178 (define_split
8179   [(set (match_operand 0 "flags_reg_operand" "")
8180         (match_operator 1 "compare_operator"
8181           [(and (match_operand 2 "nonimmediate_operand" "")
8182                 (match_operand 3 "const_int_operand" ""))
8183            (const_int 0)]))]
8184    "reload_completed
8185     && GET_MODE (operands[2]) != QImode
8186     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8187     && ((ix86_match_ccmode (insn, CCZmode)
8188          && !(INTVAL (operands[3]) & ~255))
8189         || (ix86_match_ccmode (insn, CCNOmode)
8190             && !(INTVAL (operands[3]) & ~127)))"
8191   [(set (match_dup 0)
8192         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8193                          (const_int 0)]))]
8194   "operands[2] = gen_lowpart (QImode, operands[2]);
8195    operands[3] = gen_lowpart (QImode, operands[3]);")
8196
8197
8198 ;; %%% This used to optimize known byte-wide and operations to memory,
8199 ;; and sometimes to QImode registers.  If this is considered useful,
8200 ;; it should be done with splitters.
8201
8202 (define_expand "anddi3"
8203   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8204         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8205                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8206    (clobber (reg:CC FLAGS_REG))]
8207   "TARGET_64BIT"
8208   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8209
8210 (define_insn "*anddi_1_rex64"
8211   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8212         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8213                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8214    (clobber (reg:CC FLAGS_REG))]
8215   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8216 {
8217   switch (get_attr_type (insn))
8218     {
8219     case TYPE_IMOVX:
8220       {
8221         enum machine_mode mode;
8222
8223         if (GET_CODE (operands[2]) != CONST_INT)
8224           abort ();
8225         if (INTVAL (operands[2]) == 0xff)
8226           mode = QImode;
8227         else if (INTVAL (operands[2]) == 0xffff)
8228           mode = HImode;
8229         else
8230           abort ();
8231         
8232         operands[1] = gen_lowpart (mode, operands[1]);
8233         if (mode == QImode)
8234           return "movz{bq|x}\t{%1,%0|%0, %1}";
8235         else
8236           return "movz{wq|x}\t{%1,%0|%0, %1}";
8237       }
8238
8239     default:
8240       if (! rtx_equal_p (operands[0], operands[1]))
8241         abort ();
8242       if (get_attr_mode (insn) == MODE_SI)
8243         return "and{l}\t{%k2, %k0|%k0, %k2}";
8244       else
8245         return "and{q}\t{%2, %0|%0, %2}";
8246     }
8247 }
8248   [(set_attr "type" "alu,alu,alu,imovx")
8249    (set_attr "length_immediate" "*,*,*,0")
8250    (set_attr "mode" "SI,DI,DI,DI")])
8251
8252 (define_insn "*anddi_2"
8253   [(set (reg FLAGS_REG)
8254         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8255                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8256                  (const_int 0)))
8257    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8258         (and:DI (match_dup 1) (match_dup 2)))]
8259   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8260    && ix86_binary_operator_ok (AND, DImode, operands)"
8261   "@
8262    and{l}\t{%k2, %k0|%k0, %k2}
8263    and{q}\t{%2, %0|%0, %2}
8264    and{q}\t{%2, %0|%0, %2}"
8265   [(set_attr "type" "alu")
8266    (set_attr "mode" "SI,DI,DI")])
8267
8268 (define_expand "andsi3"
8269   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8270         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8271                 (match_operand:SI 2 "general_operand" "")))
8272    (clobber (reg:CC FLAGS_REG))]
8273   ""
8274   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8275
8276 (define_insn "*andsi_1"
8277   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8278         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8279                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8280    (clobber (reg:CC FLAGS_REG))]
8281   "ix86_binary_operator_ok (AND, SImode, operands)"
8282 {
8283   switch (get_attr_type (insn))
8284     {
8285     case TYPE_IMOVX:
8286       {
8287         enum machine_mode mode;
8288
8289         if (GET_CODE (operands[2]) != CONST_INT)
8290           abort ();
8291         if (INTVAL (operands[2]) == 0xff)
8292           mode = QImode;
8293         else if (INTVAL (operands[2]) == 0xffff)
8294           mode = HImode;
8295         else
8296           abort ();
8297         
8298         operands[1] = gen_lowpart (mode, operands[1]);
8299         if (mode == QImode)
8300           return "movz{bl|x}\t{%1,%0|%0, %1}";
8301         else
8302           return "movz{wl|x}\t{%1,%0|%0, %1}";
8303       }
8304
8305     default:
8306       if (! rtx_equal_p (operands[0], operands[1]))
8307         abort ();
8308       return "and{l}\t{%2, %0|%0, %2}";
8309     }
8310 }
8311   [(set_attr "type" "alu,alu,imovx")
8312    (set_attr "length_immediate" "*,*,0")
8313    (set_attr "mode" "SI")])
8314
8315 (define_split
8316   [(set (match_operand 0 "register_operand" "")
8317         (and (match_dup 0)
8318              (const_int -65536)))
8319    (clobber (reg:CC FLAGS_REG))]
8320   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8321   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8322   "operands[1] = gen_lowpart (HImode, operands[0]);")
8323
8324 (define_split
8325   [(set (match_operand 0 "ext_register_operand" "")
8326         (and (match_dup 0)
8327              (const_int -256)))
8328    (clobber (reg:CC FLAGS_REG))]
8329   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8330   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8331   "operands[1] = gen_lowpart (QImode, operands[0]);")
8332
8333 (define_split
8334   [(set (match_operand 0 "ext_register_operand" "")
8335         (and (match_dup 0)
8336              (const_int -65281)))
8337    (clobber (reg:CC FLAGS_REG))]
8338   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8339   [(parallel [(set (zero_extract:SI (match_dup 0)
8340                                     (const_int 8)
8341                                     (const_int 8))
8342                    (xor:SI 
8343                      (zero_extract:SI (match_dup 0)
8344                                       (const_int 8)
8345                                       (const_int 8))
8346                      (zero_extract:SI (match_dup 0)
8347                                       (const_int 8)
8348                                       (const_int 8))))
8349               (clobber (reg:CC FLAGS_REG))])]
8350   "operands[0] = gen_lowpart (SImode, operands[0]);")
8351
8352 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8353 (define_insn "*andsi_1_zext"
8354   [(set (match_operand:DI 0 "register_operand" "=r")
8355         (zero_extend:DI
8356           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8357                   (match_operand:SI 2 "general_operand" "rim"))))
8358    (clobber (reg:CC FLAGS_REG))]
8359   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8360   "and{l}\t{%2, %k0|%k0, %2}"
8361   [(set_attr "type" "alu")
8362    (set_attr "mode" "SI")])
8363
8364 (define_insn "*andsi_2"
8365   [(set (reg FLAGS_REG)
8366         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8367                          (match_operand:SI 2 "general_operand" "rim,ri"))
8368                  (const_int 0)))
8369    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8370         (and:SI (match_dup 1) (match_dup 2)))]
8371   "ix86_match_ccmode (insn, CCNOmode)
8372    && ix86_binary_operator_ok (AND, SImode, operands)"
8373   "and{l}\t{%2, %0|%0, %2}"
8374   [(set_attr "type" "alu")
8375    (set_attr "mode" "SI")])
8376
8377 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8378 (define_insn "*andsi_2_zext"
8379   [(set (reg FLAGS_REG)
8380         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8381                          (match_operand:SI 2 "general_operand" "rim"))
8382                  (const_int 0)))
8383    (set (match_operand:DI 0 "register_operand" "=r")
8384         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8385   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8386    && ix86_binary_operator_ok (AND, SImode, operands)"
8387   "and{l}\t{%2, %k0|%k0, %2}"
8388   [(set_attr "type" "alu")
8389    (set_attr "mode" "SI")])
8390
8391 (define_expand "andhi3"
8392   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8393         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8394                 (match_operand:HI 2 "general_operand" "")))
8395    (clobber (reg:CC FLAGS_REG))]
8396   "TARGET_HIMODE_MATH"
8397   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8398
8399 (define_insn "*andhi_1"
8400   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8401         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8402                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8403    (clobber (reg:CC FLAGS_REG))]
8404   "ix86_binary_operator_ok (AND, HImode, operands)"
8405 {
8406   switch (get_attr_type (insn))
8407     {
8408     case TYPE_IMOVX:
8409       if (GET_CODE (operands[2]) != CONST_INT)
8410         abort ();
8411       if (INTVAL (operands[2]) == 0xff)
8412         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8413       abort ();
8414
8415     default:
8416       if (! rtx_equal_p (operands[0], operands[1]))
8417         abort ();
8418
8419       return "and{w}\t{%2, %0|%0, %2}";
8420     }
8421 }
8422   [(set_attr "type" "alu,alu,imovx")
8423    (set_attr "length_immediate" "*,*,0")
8424    (set_attr "mode" "HI,HI,SI")])
8425
8426 (define_insn "*andhi_2"
8427   [(set (reg FLAGS_REG)
8428         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8429                          (match_operand:HI 2 "general_operand" "rim,ri"))
8430                  (const_int 0)))
8431    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8432         (and:HI (match_dup 1) (match_dup 2)))]
8433   "ix86_match_ccmode (insn, CCNOmode)
8434    && ix86_binary_operator_ok (AND, HImode, operands)"
8435   "and{w}\t{%2, %0|%0, %2}"
8436   [(set_attr "type" "alu")
8437    (set_attr "mode" "HI")])
8438
8439 (define_expand "andqi3"
8440   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8441         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8442                 (match_operand:QI 2 "general_operand" "")))
8443    (clobber (reg:CC FLAGS_REG))]
8444   "TARGET_QIMODE_MATH"
8445   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8446
8447 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8448 (define_insn "*andqi_1"
8449   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8450         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8451                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8452    (clobber (reg:CC FLAGS_REG))]
8453   "ix86_binary_operator_ok (AND, QImode, operands)"
8454   "@
8455    and{b}\t{%2, %0|%0, %2}
8456    and{b}\t{%2, %0|%0, %2}
8457    and{l}\t{%k2, %k0|%k0, %k2}"
8458   [(set_attr "type" "alu")
8459    (set_attr "mode" "QI,QI,SI")])
8460
8461 (define_insn "*andqi_1_slp"
8462   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8463         (and:QI (match_dup 0)
8464                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8465    (clobber (reg:CC FLAGS_REG))]
8466   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8467    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8468   "and{b}\t{%1, %0|%0, %1}"
8469   [(set_attr "type" "alu1")
8470    (set_attr "mode" "QI")])
8471
8472 (define_insn "*andqi_2_maybe_si"
8473   [(set (reg FLAGS_REG)
8474         (compare (and:QI
8475                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8476                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8477                  (const_int 0)))
8478    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8479         (and:QI (match_dup 1) (match_dup 2)))]
8480   "ix86_binary_operator_ok (AND, QImode, operands)
8481    && ix86_match_ccmode (insn,
8482                          GET_CODE (operands[2]) == CONST_INT
8483                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8484 {
8485   if (which_alternative == 2)
8486     {
8487       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8488         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8489       return "and{l}\t{%2, %k0|%k0, %2}";
8490     }
8491   return "and{b}\t{%2, %0|%0, %2}";
8492 }
8493   [(set_attr "type" "alu")
8494    (set_attr "mode" "QI,QI,SI")])
8495
8496 (define_insn "*andqi_2"
8497   [(set (reg FLAGS_REG)
8498         (compare (and:QI
8499                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8500                    (match_operand:QI 2 "general_operand" "qim,qi"))
8501                  (const_int 0)))
8502    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8503         (and:QI (match_dup 1) (match_dup 2)))]
8504   "ix86_match_ccmode (insn, CCNOmode)
8505    && ix86_binary_operator_ok (AND, QImode, operands)"
8506   "and{b}\t{%2, %0|%0, %2}"
8507   [(set_attr "type" "alu")
8508    (set_attr "mode" "QI")])
8509
8510 (define_insn "*andqi_2_slp"
8511   [(set (reg FLAGS_REG)
8512         (compare (and:QI
8513                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8514                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8515                  (const_int 0)))
8516    (set (strict_low_part (match_dup 0))
8517         (and:QI (match_dup 0) (match_dup 1)))]
8518   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8519    && ix86_match_ccmode (insn, CCNOmode)
8520    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8521   "and{b}\t{%1, %0|%0, %1}"
8522   [(set_attr "type" "alu1")
8523    (set_attr "mode" "QI")])
8524
8525 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8526 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8527 ;; for a QImode operand, which of course failed.
8528
8529 (define_insn "andqi_ext_0"
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           (match_operand 2 "const_int_operand" "n")))
8539    (clobber (reg:CC FLAGS_REG))]
8540   ""
8541   "and{b}\t{%2, %h0|%h0, %2}"
8542   [(set_attr "type" "alu")
8543    (set_attr "length_immediate" "1")
8544    (set_attr "mode" "QI")])
8545
8546 ;; Generated by peephole translating test to and.  This shows up
8547 ;; often in fp comparisons.
8548
8549 (define_insn "*andqi_ext_0_cc"
8550   [(set (reg FLAGS_REG)
8551         (compare
8552           (and:SI
8553             (zero_extract:SI
8554               (match_operand 1 "ext_register_operand" "0")
8555               (const_int 8)
8556               (const_int 8))
8557             (match_operand 2 "const_int_operand" "n"))
8558           (const_int 0)))
8559    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8560                          (const_int 8)
8561                          (const_int 8))
8562         (and:SI 
8563           (zero_extract:SI
8564             (match_dup 1)
8565             (const_int 8)
8566             (const_int 8))
8567           (match_dup 2)))]
8568   "ix86_match_ccmode (insn, CCNOmode)"
8569   "and{b}\t{%2, %h0|%h0, %2}"
8570   [(set_attr "type" "alu")
8571    (set_attr "length_immediate" "1")
8572    (set_attr "mode" "QI")])
8573
8574 (define_insn "*andqi_ext_1"
8575   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8576                          (const_int 8)
8577                          (const_int 8))
8578         (and:SI 
8579           (zero_extract:SI
8580             (match_operand 1 "ext_register_operand" "0")
8581             (const_int 8)
8582             (const_int 8))
8583           (zero_extend:SI
8584             (match_operand:QI 2 "general_operand" "Qm"))))
8585    (clobber (reg:CC FLAGS_REG))]
8586   "!TARGET_64BIT"
8587   "and{b}\t{%2, %h0|%h0, %2}"
8588   [(set_attr "type" "alu")
8589    (set_attr "length_immediate" "0")
8590    (set_attr "mode" "QI")])
8591
8592 (define_insn "*andqi_ext_1_rex64"
8593   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8594                          (const_int 8)
8595                          (const_int 8))
8596         (and:SI 
8597           (zero_extract:SI
8598             (match_operand 1 "ext_register_operand" "0")
8599             (const_int 8)
8600             (const_int 8))
8601           (zero_extend:SI
8602             (match_operand 2 "ext_register_operand" "Q"))))
8603    (clobber (reg:CC FLAGS_REG))]
8604   "TARGET_64BIT"
8605   "and{b}\t{%2, %h0|%h0, %2}"
8606   [(set_attr "type" "alu")
8607    (set_attr "length_immediate" "0")
8608    (set_attr "mode" "QI")])
8609
8610 (define_insn "*andqi_ext_2"
8611   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8612                          (const_int 8)
8613                          (const_int 8))
8614         (and:SI
8615           (zero_extract:SI
8616             (match_operand 1 "ext_register_operand" "%0")
8617             (const_int 8)
8618             (const_int 8))
8619           (zero_extract:SI
8620             (match_operand 2 "ext_register_operand" "Q")
8621             (const_int 8)
8622             (const_int 8))))
8623    (clobber (reg:CC FLAGS_REG))]
8624   ""
8625   "and{b}\t{%h2, %h0|%h0, %h2}"
8626   [(set_attr "type" "alu")
8627    (set_attr "length_immediate" "0")
8628    (set_attr "mode" "QI")])
8629
8630 ;; Convert wide AND instructions with immediate operand to shorter QImode
8631 ;; equivalents when possible.
8632 ;; Don't do the splitting with memory operands, since it introduces risk
8633 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8634 ;; for size, but that can (should?) be handled by generic code instead.
8635 (define_split
8636   [(set (match_operand 0 "register_operand" "")
8637         (and (match_operand 1 "register_operand" "")
8638              (match_operand 2 "const_int_operand" "")))
8639    (clobber (reg:CC FLAGS_REG))]
8640    "reload_completed
8641     && QI_REG_P (operands[0])
8642     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8643     && !(~INTVAL (operands[2]) & ~(255 << 8))
8644     && GET_MODE (operands[0]) != QImode"
8645   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8646                    (and:SI (zero_extract:SI (match_dup 1)
8647                                             (const_int 8) (const_int 8))
8648                            (match_dup 2)))
8649               (clobber (reg:CC FLAGS_REG))])]
8650   "operands[0] = gen_lowpart (SImode, operands[0]);
8651    operands[1] = gen_lowpart (SImode, operands[1]);
8652    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8653
8654 ;; Since AND can be encoded with sign extended immediate, this is only
8655 ;; profitable when 7th bit is not set.
8656 (define_split
8657   [(set (match_operand 0 "register_operand" "")
8658         (and (match_operand 1 "general_operand" "")
8659              (match_operand 2 "const_int_operand" "")))
8660    (clobber (reg:CC FLAGS_REG))]
8661    "reload_completed
8662     && ANY_QI_REG_P (operands[0])
8663     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8664     && !(~INTVAL (operands[2]) & ~255)
8665     && !(INTVAL (operands[2]) & 128)
8666     && GET_MODE (operands[0]) != QImode"
8667   [(parallel [(set (strict_low_part (match_dup 0))
8668                    (and:QI (match_dup 1)
8669                            (match_dup 2)))
8670               (clobber (reg:CC FLAGS_REG))])]
8671   "operands[0] = gen_lowpart (QImode, operands[0]);
8672    operands[1] = gen_lowpart (QImode, operands[1]);
8673    operands[2] = gen_lowpart (QImode, operands[2]);")
8674 \f
8675 ;; Logical inclusive OR instructions
8676
8677 ;; %%% This used to optimize known byte-wide and operations to memory.
8678 ;; If this is considered useful, it should be done with splitters.
8679
8680 (define_expand "iordi3"
8681   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8682         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8683                 (match_operand:DI 2 "x86_64_general_operand" "")))
8684    (clobber (reg:CC FLAGS_REG))]
8685   "TARGET_64BIT"
8686   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8687
8688 (define_insn "*iordi_1_rex64"
8689   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8690         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8691                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8692    (clobber (reg:CC FLAGS_REG))]
8693   "TARGET_64BIT
8694    && ix86_binary_operator_ok (IOR, DImode, operands)"
8695   "or{q}\t{%2, %0|%0, %2}"
8696   [(set_attr "type" "alu")
8697    (set_attr "mode" "DI")])
8698
8699 (define_insn "*iordi_2_rex64"
8700   [(set (reg FLAGS_REG)
8701         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8702                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8703                  (const_int 0)))
8704    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8705         (ior:DI (match_dup 1) (match_dup 2)))]
8706   "TARGET_64BIT
8707    && ix86_match_ccmode (insn, CCNOmode)
8708    && ix86_binary_operator_ok (IOR, DImode, operands)"
8709   "or{q}\t{%2, %0|%0, %2}"
8710   [(set_attr "type" "alu")
8711    (set_attr "mode" "DI")])
8712
8713 (define_insn "*iordi_3_rex64"
8714   [(set (reg FLAGS_REG)
8715         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8716                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8717                  (const_int 0)))
8718    (clobber (match_scratch:DI 0 "=r"))]
8719   "TARGET_64BIT
8720    && ix86_match_ccmode (insn, CCNOmode)
8721    && ix86_binary_operator_ok (IOR, DImode, operands)"
8722   "or{q}\t{%2, %0|%0, %2}"
8723   [(set_attr "type" "alu")
8724    (set_attr "mode" "DI")])
8725
8726
8727 (define_expand "iorsi3"
8728   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8729         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8730                 (match_operand:SI 2 "general_operand" "")))
8731    (clobber (reg:CC FLAGS_REG))]
8732   ""
8733   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8734
8735 (define_insn "*iorsi_1"
8736   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8737         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8738                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8739    (clobber (reg:CC FLAGS_REG))]
8740   "ix86_binary_operator_ok (IOR, SImode, operands)"
8741   "or{l}\t{%2, %0|%0, %2}"
8742   [(set_attr "type" "alu")
8743    (set_attr "mode" "SI")])
8744
8745 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8746 (define_insn "*iorsi_1_zext"
8747   [(set (match_operand:DI 0 "register_operand" "=rm")
8748         (zero_extend:DI
8749           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8750                   (match_operand:SI 2 "general_operand" "rim"))))
8751    (clobber (reg:CC FLAGS_REG))]
8752   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8753   "or{l}\t{%2, %k0|%k0, %2}"
8754   [(set_attr "type" "alu")
8755    (set_attr "mode" "SI")])
8756
8757 (define_insn "*iorsi_1_zext_imm"
8758   [(set (match_operand:DI 0 "register_operand" "=rm")
8759         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8760                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8761    (clobber (reg:CC FLAGS_REG))]
8762   "TARGET_64BIT"
8763   "or{l}\t{%2, %k0|%k0, %2}"
8764   [(set_attr "type" "alu")
8765    (set_attr "mode" "SI")])
8766
8767 (define_insn "*iorsi_2"
8768   [(set (reg FLAGS_REG)
8769         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8770                          (match_operand:SI 2 "general_operand" "rim,ri"))
8771                  (const_int 0)))
8772    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8773         (ior:SI (match_dup 1) (match_dup 2)))]
8774   "ix86_match_ccmode (insn, CCNOmode)
8775    && ix86_binary_operator_ok (IOR, SImode, operands)"
8776   "or{l}\t{%2, %0|%0, %2}"
8777   [(set_attr "type" "alu")
8778    (set_attr "mode" "SI")])
8779
8780 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8781 ;; ??? Special case for immediate operand is missing - it is tricky.
8782 (define_insn "*iorsi_2_zext"
8783   [(set (reg FLAGS_REG)
8784         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8785                          (match_operand:SI 2 "general_operand" "rim"))
8786                  (const_int 0)))
8787    (set (match_operand:DI 0 "register_operand" "=r")
8788         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8789   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8790    && ix86_binary_operator_ok (IOR, SImode, operands)"
8791   "or{l}\t{%2, %k0|%k0, %2}"
8792   [(set_attr "type" "alu")
8793    (set_attr "mode" "SI")])
8794
8795 (define_insn "*iorsi_2_zext_imm"
8796   [(set (reg FLAGS_REG)
8797         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8798                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8799                  (const_int 0)))
8800    (set (match_operand:DI 0 "register_operand" "=r")
8801         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8802   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8803    && ix86_binary_operator_ok (IOR, SImode, operands)"
8804   "or{l}\t{%2, %k0|%k0, %2}"
8805   [(set_attr "type" "alu")
8806    (set_attr "mode" "SI")])
8807
8808 (define_insn "*iorsi_3"
8809   [(set (reg FLAGS_REG)
8810         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8811                          (match_operand:SI 2 "general_operand" "rim"))
8812                  (const_int 0)))
8813    (clobber (match_scratch:SI 0 "=r"))]
8814   "ix86_match_ccmode (insn, CCNOmode)
8815    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8816   "or{l}\t{%2, %0|%0, %2}"
8817   [(set_attr "type" "alu")
8818    (set_attr "mode" "SI")])
8819
8820 (define_expand "iorhi3"
8821   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8822         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8823                 (match_operand:HI 2 "general_operand" "")))
8824    (clobber (reg:CC FLAGS_REG))]
8825   "TARGET_HIMODE_MATH"
8826   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8827
8828 (define_insn "*iorhi_1"
8829   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8830         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8831                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8832    (clobber (reg:CC FLAGS_REG))]
8833   "ix86_binary_operator_ok (IOR, HImode, operands)"
8834   "or{w}\t{%2, %0|%0, %2}"
8835   [(set_attr "type" "alu")
8836    (set_attr "mode" "HI")])
8837
8838 (define_insn "*iorhi_2"
8839   [(set (reg FLAGS_REG)
8840         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8841                          (match_operand:HI 2 "general_operand" "rim,ri"))
8842                  (const_int 0)))
8843    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8844         (ior:HI (match_dup 1) (match_dup 2)))]
8845   "ix86_match_ccmode (insn, CCNOmode)
8846    && ix86_binary_operator_ok (IOR, HImode, operands)"
8847   "or{w}\t{%2, %0|%0, %2}"
8848   [(set_attr "type" "alu")
8849    (set_attr "mode" "HI")])
8850
8851 (define_insn "*iorhi_3"
8852   [(set (reg FLAGS_REG)
8853         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8854                          (match_operand:HI 2 "general_operand" "rim"))
8855                  (const_int 0)))
8856    (clobber (match_scratch:HI 0 "=r"))]
8857   "ix86_match_ccmode (insn, CCNOmode)
8858    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8859   "or{w}\t{%2, %0|%0, %2}"
8860   [(set_attr "type" "alu")
8861    (set_attr "mode" "HI")])
8862
8863 (define_expand "iorqi3"
8864   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8865         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8866                 (match_operand:QI 2 "general_operand" "")))
8867    (clobber (reg:CC FLAGS_REG))]
8868   "TARGET_QIMODE_MATH"
8869   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8870
8871 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8872 (define_insn "*iorqi_1"
8873   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8874         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8875                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8876    (clobber (reg:CC FLAGS_REG))]
8877   "ix86_binary_operator_ok (IOR, QImode, operands)"
8878   "@
8879    or{b}\t{%2, %0|%0, %2}
8880    or{b}\t{%2, %0|%0, %2}
8881    or{l}\t{%k2, %k0|%k0, %k2}"
8882   [(set_attr "type" "alu")
8883    (set_attr "mode" "QI,QI,SI")])
8884
8885 (define_insn "*iorqi_1_slp"
8886   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8887         (ior:QI (match_dup 0)
8888                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8889    (clobber (reg:CC FLAGS_REG))]
8890   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8891    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8892   "or{b}\t{%1, %0|%0, %1}"
8893   [(set_attr "type" "alu1")
8894    (set_attr "mode" "QI")])
8895
8896 (define_insn "*iorqi_2"
8897   [(set (reg FLAGS_REG)
8898         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8899                          (match_operand:QI 2 "general_operand" "qim,qi"))
8900                  (const_int 0)))
8901    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8902         (ior:QI (match_dup 1) (match_dup 2)))]
8903   "ix86_match_ccmode (insn, CCNOmode)
8904    && ix86_binary_operator_ok (IOR, QImode, operands)"
8905   "or{b}\t{%2, %0|%0, %2}"
8906   [(set_attr "type" "alu")
8907    (set_attr "mode" "QI")])
8908
8909 (define_insn "*iorqi_2_slp"
8910   [(set (reg FLAGS_REG)
8911         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8912                          (match_operand:QI 1 "general_operand" "qim,qi"))
8913                  (const_int 0)))
8914    (set (strict_low_part (match_dup 0))
8915         (ior:QI (match_dup 0) (match_dup 1)))]
8916   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8917    && ix86_match_ccmode (insn, CCNOmode)
8918    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8919   "or{b}\t{%1, %0|%0, %1}"
8920   [(set_attr "type" "alu1")
8921    (set_attr "mode" "QI")])
8922
8923 (define_insn "*iorqi_3"
8924   [(set (reg FLAGS_REG)
8925         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8926                          (match_operand:QI 2 "general_operand" "qim"))
8927                  (const_int 0)))
8928    (clobber (match_scratch:QI 0 "=q"))]
8929   "ix86_match_ccmode (insn, CCNOmode)
8930    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8931   "or{b}\t{%2, %0|%0, %2}"
8932   [(set_attr "type" "alu")
8933    (set_attr "mode" "QI")])
8934
8935 (define_insn "iorqi_ext_0"
8936   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8937                          (const_int 8)
8938                          (const_int 8))
8939         (ior:SI 
8940           (zero_extract:SI
8941             (match_operand 1 "ext_register_operand" "0")
8942             (const_int 8)
8943             (const_int 8))
8944           (match_operand 2 "const_int_operand" "n")))
8945    (clobber (reg:CC FLAGS_REG))]
8946   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8947   "or{b}\t{%2, %h0|%h0, %2}"
8948   [(set_attr "type" "alu")
8949    (set_attr "length_immediate" "1")
8950    (set_attr "mode" "QI")])
8951
8952 (define_insn "*iorqi_ext_1"
8953   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8954                          (const_int 8)
8955                          (const_int 8))
8956         (ior:SI 
8957           (zero_extract:SI
8958             (match_operand 1 "ext_register_operand" "0")
8959             (const_int 8)
8960             (const_int 8))
8961           (zero_extend:SI
8962             (match_operand:QI 2 "general_operand" "Qm"))))
8963    (clobber (reg:CC FLAGS_REG))]
8964   "!TARGET_64BIT
8965    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8966   "or{b}\t{%2, %h0|%h0, %2}"
8967   [(set_attr "type" "alu")
8968    (set_attr "length_immediate" "0")
8969    (set_attr "mode" "QI")])
8970
8971 (define_insn "*iorqi_ext_1_rex64"
8972   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8973                          (const_int 8)
8974                          (const_int 8))
8975         (ior:SI 
8976           (zero_extract:SI
8977             (match_operand 1 "ext_register_operand" "0")
8978             (const_int 8)
8979             (const_int 8))
8980           (zero_extend:SI
8981             (match_operand 2 "ext_register_operand" "Q"))))
8982    (clobber (reg:CC FLAGS_REG))]
8983   "TARGET_64BIT
8984    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8985   "or{b}\t{%2, %h0|%h0, %2}"
8986   [(set_attr "type" "alu")
8987    (set_attr "length_immediate" "0")
8988    (set_attr "mode" "QI")])
8989
8990 (define_insn "*iorqi_ext_2"
8991   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8992                          (const_int 8)
8993                          (const_int 8))
8994         (ior:SI 
8995           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8996                            (const_int 8)
8997                            (const_int 8))
8998           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8999                            (const_int 8)
9000                            (const_int 8))))
9001    (clobber (reg:CC FLAGS_REG))]
9002   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9003   "ior{b}\t{%h2, %h0|%h0, %h2}"
9004   [(set_attr "type" "alu")
9005    (set_attr "length_immediate" "0")
9006    (set_attr "mode" "QI")])
9007
9008 (define_split
9009   [(set (match_operand 0 "register_operand" "")
9010         (ior (match_operand 1 "register_operand" "")
9011              (match_operand 2 "const_int_operand" "")))
9012    (clobber (reg:CC FLAGS_REG))]
9013    "reload_completed
9014     && QI_REG_P (operands[0])
9015     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9016     && !(INTVAL (operands[2]) & ~(255 << 8))
9017     && GET_MODE (operands[0]) != QImode"
9018   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9019                    (ior:SI (zero_extract:SI (match_dup 1)
9020                                             (const_int 8) (const_int 8))
9021                            (match_dup 2)))
9022               (clobber (reg:CC FLAGS_REG))])]
9023   "operands[0] = gen_lowpart (SImode, operands[0]);
9024    operands[1] = gen_lowpart (SImode, operands[1]);
9025    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9026
9027 ;; Since OR can be encoded with sign extended immediate, this is only
9028 ;; profitable when 7th bit is set.
9029 (define_split
9030   [(set (match_operand 0 "register_operand" "")
9031         (ior (match_operand 1 "general_operand" "")
9032              (match_operand 2 "const_int_operand" "")))
9033    (clobber (reg:CC FLAGS_REG))]
9034    "reload_completed
9035     && ANY_QI_REG_P (operands[0])
9036     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9037     && !(INTVAL (operands[2]) & ~255)
9038     && (INTVAL (operands[2]) & 128)
9039     && GET_MODE (operands[0]) != QImode"
9040   [(parallel [(set (strict_low_part (match_dup 0))
9041                    (ior:QI (match_dup 1)
9042                            (match_dup 2)))
9043               (clobber (reg:CC FLAGS_REG))])]
9044   "operands[0] = gen_lowpart (QImode, operands[0]);
9045    operands[1] = gen_lowpart (QImode, operands[1]);
9046    operands[2] = gen_lowpart (QImode, operands[2]);")
9047 \f
9048 ;; Logical XOR instructions
9049
9050 ;; %%% This used to optimize known byte-wide and operations to memory.
9051 ;; If this is considered useful, it should be done with splitters.
9052
9053 (define_expand "xordi3"
9054   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9055         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9056                 (match_operand:DI 2 "x86_64_general_operand" "")))
9057    (clobber (reg:CC FLAGS_REG))]
9058   "TARGET_64BIT"
9059   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9060
9061 (define_insn "*xordi_1_rex64"
9062   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9063         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9064                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9065    (clobber (reg:CC FLAGS_REG))]
9066   "TARGET_64BIT
9067    && ix86_binary_operator_ok (XOR, DImode, operands)"
9068   "@
9069    xor{q}\t{%2, %0|%0, %2}
9070    xor{q}\t{%2, %0|%0, %2}"
9071   [(set_attr "type" "alu")
9072    (set_attr "mode" "DI,DI")])
9073
9074 (define_insn "*xordi_2_rex64"
9075   [(set (reg FLAGS_REG)
9076         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9077                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9078                  (const_int 0)))
9079    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9080         (xor:DI (match_dup 1) (match_dup 2)))]
9081   "TARGET_64BIT
9082    && ix86_match_ccmode (insn, CCNOmode)
9083    && ix86_binary_operator_ok (XOR, DImode, operands)"
9084   "@
9085    xor{q}\t{%2, %0|%0, %2}
9086    xor{q}\t{%2, %0|%0, %2}"
9087   [(set_attr "type" "alu")
9088    (set_attr "mode" "DI,DI")])
9089
9090 (define_insn "*xordi_3_rex64"
9091   [(set (reg FLAGS_REG)
9092         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9093                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9094                  (const_int 0)))
9095    (clobber (match_scratch:DI 0 "=r"))]
9096   "TARGET_64BIT
9097    && ix86_match_ccmode (insn, CCNOmode)
9098    && ix86_binary_operator_ok (XOR, DImode, operands)"
9099   "xor{q}\t{%2, %0|%0, %2}"
9100   [(set_attr "type" "alu")
9101    (set_attr "mode" "DI")])
9102
9103 (define_expand "xorsi3"
9104   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9105         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9106                 (match_operand:SI 2 "general_operand" "")))
9107    (clobber (reg:CC FLAGS_REG))]
9108   ""
9109   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9110
9111 (define_insn "*xorsi_1"
9112   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9113         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9114                 (match_operand:SI 2 "general_operand" "ri,rm")))
9115    (clobber (reg:CC FLAGS_REG))]
9116   "ix86_binary_operator_ok (XOR, SImode, operands)"
9117   "xor{l}\t{%2, %0|%0, %2}"
9118   [(set_attr "type" "alu")
9119    (set_attr "mode" "SI")])
9120
9121 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9122 ;; Add speccase for immediates
9123 (define_insn "*xorsi_1_zext"
9124   [(set (match_operand:DI 0 "register_operand" "=r")
9125         (zero_extend:DI
9126           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9127                   (match_operand:SI 2 "general_operand" "rim"))))
9128    (clobber (reg:CC FLAGS_REG))]
9129   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9130   "xor{l}\t{%2, %k0|%k0, %2}"
9131   [(set_attr "type" "alu")
9132    (set_attr "mode" "SI")])
9133
9134 (define_insn "*xorsi_1_zext_imm"
9135   [(set (match_operand:DI 0 "register_operand" "=r")
9136         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9137                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9138    (clobber (reg:CC FLAGS_REG))]
9139   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9140   "xor{l}\t{%2, %k0|%k0, %2}"
9141   [(set_attr "type" "alu")
9142    (set_attr "mode" "SI")])
9143
9144 (define_insn "*xorsi_2"
9145   [(set (reg FLAGS_REG)
9146         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9147                          (match_operand:SI 2 "general_operand" "rim,ri"))
9148                  (const_int 0)))
9149    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9150         (xor:SI (match_dup 1) (match_dup 2)))]
9151   "ix86_match_ccmode (insn, CCNOmode)
9152    && ix86_binary_operator_ok (XOR, SImode, operands)"
9153   "xor{l}\t{%2, %0|%0, %2}"
9154   [(set_attr "type" "alu")
9155    (set_attr "mode" "SI")])
9156
9157 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9158 ;; ??? Special case for immediate operand is missing - it is tricky.
9159 (define_insn "*xorsi_2_zext"
9160   [(set (reg FLAGS_REG)
9161         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9162                          (match_operand:SI 2 "general_operand" "rim"))
9163                  (const_int 0)))
9164    (set (match_operand:DI 0 "register_operand" "=r")
9165         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9166   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9167    && ix86_binary_operator_ok (XOR, SImode, operands)"
9168   "xor{l}\t{%2, %k0|%k0, %2}"
9169   [(set_attr "type" "alu")
9170    (set_attr "mode" "SI")])
9171
9172 (define_insn "*xorsi_2_zext_imm"
9173   [(set (reg FLAGS_REG)
9174         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9175                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9176                  (const_int 0)))
9177    (set (match_operand:DI 0 "register_operand" "=r")
9178         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9179   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9180    && ix86_binary_operator_ok (XOR, SImode, operands)"
9181   "xor{l}\t{%2, %k0|%k0, %2}"
9182   [(set_attr "type" "alu")
9183    (set_attr "mode" "SI")])
9184
9185 (define_insn "*xorsi_3"
9186   [(set (reg FLAGS_REG)
9187         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9188                          (match_operand:SI 2 "general_operand" "rim"))
9189                  (const_int 0)))
9190    (clobber (match_scratch:SI 0 "=r"))]
9191   "ix86_match_ccmode (insn, CCNOmode)
9192    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9193   "xor{l}\t{%2, %0|%0, %2}"
9194   [(set_attr "type" "alu")
9195    (set_attr "mode" "SI")])
9196
9197 (define_expand "xorhi3"
9198   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9199         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9200                 (match_operand:HI 2 "general_operand" "")))
9201    (clobber (reg:CC FLAGS_REG))]
9202   "TARGET_HIMODE_MATH"
9203   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9204
9205 (define_insn "*xorhi_1"
9206   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9207         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9208                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9209    (clobber (reg:CC FLAGS_REG))]
9210   "ix86_binary_operator_ok (XOR, HImode, operands)"
9211   "xor{w}\t{%2, %0|%0, %2}"
9212   [(set_attr "type" "alu")
9213    (set_attr "mode" "HI")])
9214
9215 (define_insn "*xorhi_2"
9216   [(set (reg FLAGS_REG)
9217         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9218                          (match_operand:HI 2 "general_operand" "rim,ri"))
9219                  (const_int 0)))
9220    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9221         (xor:HI (match_dup 1) (match_dup 2)))]
9222   "ix86_match_ccmode (insn, CCNOmode)
9223    && ix86_binary_operator_ok (XOR, HImode, operands)"
9224   "xor{w}\t{%2, %0|%0, %2}"
9225   [(set_attr "type" "alu")
9226    (set_attr "mode" "HI")])
9227
9228 (define_insn "*xorhi_3"
9229   [(set (reg FLAGS_REG)
9230         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9231                          (match_operand:HI 2 "general_operand" "rim"))
9232                  (const_int 0)))
9233    (clobber (match_scratch:HI 0 "=r"))]
9234   "ix86_match_ccmode (insn, CCNOmode)
9235    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9236   "xor{w}\t{%2, %0|%0, %2}"
9237   [(set_attr "type" "alu")
9238    (set_attr "mode" "HI")])
9239
9240 (define_expand "xorqi3"
9241   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9242         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9243                 (match_operand:QI 2 "general_operand" "")))
9244    (clobber (reg:CC FLAGS_REG))]
9245   "TARGET_QIMODE_MATH"
9246   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9247
9248 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9249 (define_insn "*xorqi_1"
9250   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9251         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9252                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9253    (clobber (reg:CC FLAGS_REG))]
9254   "ix86_binary_operator_ok (XOR, QImode, operands)"
9255   "@
9256    xor{b}\t{%2, %0|%0, %2}
9257    xor{b}\t{%2, %0|%0, %2}
9258    xor{l}\t{%k2, %k0|%k0, %k2}"
9259   [(set_attr "type" "alu")
9260    (set_attr "mode" "QI,QI,SI")])
9261
9262 (define_insn "*xorqi_1_slp"
9263   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9264         (xor:QI (match_dup 0)
9265                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9266    (clobber (reg:CC FLAGS_REG))]
9267   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9268    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9269   "xor{b}\t{%1, %0|%0, %1}"
9270   [(set_attr "type" "alu1")
9271    (set_attr "mode" "QI")])
9272
9273 (define_insn "xorqi_ext_0"
9274   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9275                          (const_int 8)
9276                          (const_int 8))
9277         (xor:SI 
9278           (zero_extract:SI
9279             (match_operand 1 "ext_register_operand" "0")
9280             (const_int 8)
9281             (const_int 8))
9282           (match_operand 2 "const_int_operand" "n")))
9283    (clobber (reg:CC FLAGS_REG))]
9284   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9285   "xor{b}\t{%2, %h0|%h0, %2}"
9286   [(set_attr "type" "alu")
9287    (set_attr "length_immediate" "1")
9288    (set_attr "mode" "QI")])
9289
9290 (define_insn "*xorqi_ext_1"
9291   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9292                          (const_int 8)
9293                          (const_int 8))
9294         (xor:SI 
9295           (zero_extract:SI
9296             (match_operand 1 "ext_register_operand" "0")
9297             (const_int 8)
9298             (const_int 8))
9299           (zero_extend:SI
9300             (match_operand:QI 2 "general_operand" "Qm"))))
9301    (clobber (reg:CC FLAGS_REG))]
9302   "!TARGET_64BIT
9303    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9304   "xor{b}\t{%2, %h0|%h0, %2}"
9305   [(set_attr "type" "alu")
9306    (set_attr "length_immediate" "0")
9307    (set_attr "mode" "QI")])
9308
9309 (define_insn "*xorqi_ext_1_rex64"
9310   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9311                          (const_int 8)
9312                          (const_int 8))
9313         (xor:SI 
9314           (zero_extract:SI
9315             (match_operand 1 "ext_register_operand" "0")
9316             (const_int 8)
9317             (const_int 8))
9318           (zero_extend:SI
9319             (match_operand 2 "ext_register_operand" "Q"))))
9320    (clobber (reg:CC FLAGS_REG))]
9321   "TARGET_64BIT
9322    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9323   "xor{b}\t{%2, %h0|%h0, %2}"
9324   [(set_attr "type" "alu")
9325    (set_attr "length_immediate" "0")
9326    (set_attr "mode" "QI")])
9327
9328 (define_insn "*xorqi_ext_2"
9329   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9330                          (const_int 8)
9331                          (const_int 8))
9332         (xor:SI 
9333           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9334                            (const_int 8)
9335                            (const_int 8))
9336           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9337                            (const_int 8)
9338                            (const_int 8))))
9339    (clobber (reg:CC FLAGS_REG))]
9340   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9341   "xor{b}\t{%h2, %h0|%h0, %h2}"
9342   [(set_attr "type" "alu")
9343    (set_attr "length_immediate" "0")
9344    (set_attr "mode" "QI")])
9345
9346 (define_insn "*xorqi_cc_1"
9347   [(set (reg FLAGS_REG)
9348         (compare
9349           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9350                   (match_operand:QI 2 "general_operand" "qim,qi"))
9351           (const_int 0)))
9352    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9353         (xor:QI (match_dup 1) (match_dup 2)))]
9354   "ix86_match_ccmode (insn, CCNOmode)
9355    && ix86_binary_operator_ok (XOR, QImode, operands)"
9356   "xor{b}\t{%2, %0|%0, %2}"
9357   [(set_attr "type" "alu")
9358    (set_attr "mode" "QI")])
9359
9360 (define_insn "*xorqi_2_slp"
9361   [(set (reg FLAGS_REG)
9362         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9363                          (match_operand:QI 1 "general_operand" "qim,qi"))
9364                  (const_int 0)))
9365    (set (strict_low_part (match_dup 0))
9366         (xor:QI (match_dup 0) (match_dup 1)))]
9367   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9368    && ix86_match_ccmode (insn, CCNOmode)
9369    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9370   "xor{b}\t{%1, %0|%0, %1}"
9371   [(set_attr "type" "alu1")
9372    (set_attr "mode" "QI")])
9373
9374 (define_insn "*xorqi_cc_2"
9375   [(set (reg FLAGS_REG)
9376         (compare
9377           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9378                   (match_operand:QI 2 "general_operand" "qim"))
9379           (const_int 0)))
9380    (clobber (match_scratch:QI 0 "=q"))]
9381   "ix86_match_ccmode (insn, CCNOmode)
9382    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9383   "xor{b}\t{%2, %0|%0, %2}"
9384   [(set_attr "type" "alu")
9385    (set_attr "mode" "QI")])
9386
9387 (define_insn "*xorqi_cc_ext_1"
9388   [(set (reg FLAGS_REG)
9389         (compare
9390           (xor:SI
9391             (zero_extract:SI
9392               (match_operand 1 "ext_register_operand" "0")
9393               (const_int 8)
9394               (const_int 8))
9395             (match_operand:QI 2 "general_operand" "qmn"))
9396           (const_int 0)))
9397    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9398                          (const_int 8)
9399                          (const_int 8))
9400         (xor:SI 
9401           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9402           (match_dup 2)))]
9403   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9404   "xor{b}\t{%2, %h0|%h0, %2}"
9405   [(set_attr "type" "alu")
9406    (set_attr "mode" "QI")])
9407
9408 (define_insn "*xorqi_cc_ext_1_rex64"
9409   [(set (reg FLAGS_REG)
9410         (compare
9411           (xor:SI
9412             (zero_extract:SI
9413               (match_operand 1 "ext_register_operand" "0")
9414               (const_int 8)
9415               (const_int 8))
9416             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9417           (const_int 0)))
9418    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9419                          (const_int 8)
9420                          (const_int 8))
9421         (xor:SI 
9422           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9423           (match_dup 2)))]
9424   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9425   "xor{b}\t{%2, %h0|%h0, %2}"
9426   [(set_attr "type" "alu")
9427    (set_attr "mode" "QI")])
9428
9429 (define_expand "xorqi_cc_ext_1"
9430   [(parallel [
9431      (set (reg:CCNO FLAGS_REG)
9432           (compare:CCNO
9433             (xor:SI
9434               (zero_extract:SI
9435                 (match_operand 1 "ext_register_operand" "")
9436                 (const_int 8)
9437                 (const_int 8))
9438               (match_operand:QI 2 "general_operand" ""))
9439             (const_int 0)))
9440      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9441                            (const_int 8)
9442                            (const_int 8))
9443           (xor:SI 
9444             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9445             (match_dup 2)))])]
9446   ""
9447   "")
9448
9449 (define_split
9450   [(set (match_operand 0 "register_operand" "")
9451         (xor (match_operand 1 "register_operand" "")
9452              (match_operand 2 "const_int_operand" "")))
9453    (clobber (reg:CC FLAGS_REG))]
9454    "reload_completed
9455     && QI_REG_P (operands[0])
9456     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9457     && !(INTVAL (operands[2]) & ~(255 << 8))
9458     && GET_MODE (operands[0]) != QImode"
9459   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9460                    (xor:SI (zero_extract:SI (match_dup 1)
9461                                             (const_int 8) (const_int 8))
9462                            (match_dup 2)))
9463               (clobber (reg:CC FLAGS_REG))])]
9464   "operands[0] = gen_lowpart (SImode, operands[0]);
9465    operands[1] = gen_lowpart (SImode, operands[1]);
9466    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9467
9468 ;; Since XOR can be encoded with sign extended immediate, this is only
9469 ;; profitable when 7th bit is set.
9470 (define_split
9471   [(set (match_operand 0 "register_operand" "")
9472         (xor (match_operand 1 "general_operand" "")
9473              (match_operand 2 "const_int_operand" "")))
9474    (clobber (reg:CC FLAGS_REG))]
9475    "reload_completed
9476     && ANY_QI_REG_P (operands[0])
9477     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9478     && !(INTVAL (operands[2]) & ~255)
9479     && (INTVAL (operands[2]) & 128)
9480     && GET_MODE (operands[0]) != QImode"
9481   [(parallel [(set (strict_low_part (match_dup 0))
9482                    (xor:QI (match_dup 1)
9483                            (match_dup 2)))
9484               (clobber (reg:CC FLAGS_REG))])]
9485   "operands[0] = gen_lowpart (QImode, operands[0]);
9486    operands[1] = gen_lowpart (QImode, operands[1]);
9487    operands[2] = gen_lowpart (QImode, operands[2]);")
9488 \f
9489 ;; Negation instructions
9490
9491 (define_expand "negdi2"
9492   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9493                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9494               (clobber (reg:CC FLAGS_REG))])]
9495   ""
9496   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9497
9498 (define_insn "*negdi2_1"
9499   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9500         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9501    (clobber (reg:CC FLAGS_REG))]
9502   "!TARGET_64BIT
9503    && ix86_unary_operator_ok (NEG, DImode, operands)"
9504   "#")
9505
9506 (define_split
9507   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9508         (neg:DI (match_operand:DI 1 "general_operand" "")))
9509    (clobber (reg:CC FLAGS_REG))]
9510   "!TARGET_64BIT && reload_completed"
9511   [(parallel
9512     [(set (reg:CCZ FLAGS_REG)
9513           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9514      (set (match_dup 0) (neg:SI (match_dup 2)))])
9515    (parallel
9516     [(set (match_dup 1)
9517           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9518                             (match_dup 3))
9519                    (const_int 0)))
9520      (clobber (reg:CC FLAGS_REG))])
9521    (parallel
9522     [(set (match_dup 1)
9523           (neg:SI (match_dup 1)))
9524      (clobber (reg:CC FLAGS_REG))])]
9525   "split_di (operands+1, 1, operands+2, operands+3);
9526    split_di (operands+0, 1, operands+0, operands+1);")
9527
9528 (define_insn "*negdi2_1_rex64"
9529   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9530         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9531    (clobber (reg:CC FLAGS_REG))]
9532   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9533   "neg{q}\t%0"
9534   [(set_attr "type" "negnot")
9535    (set_attr "mode" "DI")])
9536
9537 ;; The problem with neg is that it does not perform (compare x 0),
9538 ;; it really performs (compare 0 x), which leaves us with the zero
9539 ;; flag being the only useful item.
9540
9541 (define_insn "*negdi2_cmpz_rex64"
9542   [(set (reg:CCZ FLAGS_REG)
9543         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9544                      (const_int 0)))
9545    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9546         (neg:DI (match_dup 1)))]
9547   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9548   "neg{q}\t%0"
9549   [(set_attr "type" "negnot")
9550    (set_attr "mode" "DI")])
9551
9552
9553 (define_expand "negsi2"
9554   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9555                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9556               (clobber (reg:CC FLAGS_REG))])]
9557   ""
9558   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9559
9560 (define_insn "*negsi2_1"
9561   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9562         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9563    (clobber (reg:CC FLAGS_REG))]
9564   "ix86_unary_operator_ok (NEG, SImode, operands)"
9565   "neg{l}\t%0"
9566   [(set_attr "type" "negnot")
9567    (set_attr "mode" "SI")])
9568
9569 ;; Combine is quite creative about this pattern.
9570 (define_insn "*negsi2_1_zext"
9571   [(set (match_operand:DI 0 "register_operand" "=r")
9572         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9573                                         (const_int 32)))
9574                      (const_int 32)))
9575    (clobber (reg:CC FLAGS_REG))]
9576   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9577   "neg{l}\t%k0"
9578   [(set_attr "type" "negnot")
9579    (set_attr "mode" "SI")])
9580
9581 ;; The problem with neg is that it does not perform (compare x 0),
9582 ;; it really performs (compare 0 x), which leaves us with the zero
9583 ;; flag being the only useful item.
9584
9585 (define_insn "*negsi2_cmpz"
9586   [(set (reg:CCZ FLAGS_REG)
9587         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9588                      (const_int 0)))
9589    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9590         (neg:SI (match_dup 1)))]
9591   "ix86_unary_operator_ok (NEG, SImode, operands)"
9592   "neg{l}\t%0"
9593   [(set_attr "type" "negnot")
9594    (set_attr "mode" "SI")])
9595
9596 (define_insn "*negsi2_cmpz_zext"
9597   [(set (reg:CCZ FLAGS_REG)
9598         (compare:CCZ (lshiftrt:DI
9599                        (neg:DI (ashift:DI
9600                                  (match_operand:DI 1 "register_operand" "0")
9601                                  (const_int 32)))
9602                        (const_int 32))
9603                      (const_int 0)))
9604    (set (match_operand:DI 0 "register_operand" "=r")
9605         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9606                                         (const_int 32)))
9607                      (const_int 32)))]
9608   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9609   "neg{l}\t%k0"
9610   [(set_attr "type" "negnot")
9611    (set_attr "mode" "SI")])
9612
9613 (define_expand "neghi2"
9614   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9615                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9616               (clobber (reg:CC FLAGS_REG))])]
9617   "TARGET_HIMODE_MATH"
9618   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9619
9620 (define_insn "*neghi2_1"
9621   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9622         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9623    (clobber (reg:CC FLAGS_REG))]
9624   "ix86_unary_operator_ok (NEG, HImode, operands)"
9625   "neg{w}\t%0"
9626   [(set_attr "type" "negnot")
9627    (set_attr "mode" "HI")])
9628
9629 (define_insn "*neghi2_cmpz"
9630   [(set (reg:CCZ FLAGS_REG)
9631         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9632                      (const_int 0)))
9633    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9634         (neg:HI (match_dup 1)))]
9635   "ix86_unary_operator_ok (NEG, HImode, operands)"
9636   "neg{w}\t%0"
9637   [(set_attr "type" "negnot")
9638    (set_attr "mode" "HI")])
9639
9640 (define_expand "negqi2"
9641   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9642                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9643               (clobber (reg:CC FLAGS_REG))])]
9644   "TARGET_QIMODE_MATH"
9645   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9646
9647 (define_insn "*negqi2_1"
9648   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9649         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9650    (clobber (reg:CC FLAGS_REG))]
9651   "ix86_unary_operator_ok (NEG, QImode, operands)"
9652   "neg{b}\t%0"
9653   [(set_attr "type" "negnot")
9654    (set_attr "mode" "QI")])
9655
9656 (define_insn "*negqi2_cmpz"
9657   [(set (reg:CCZ FLAGS_REG)
9658         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9659                      (const_int 0)))
9660    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9661         (neg:QI (match_dup 1)))]
9662   "ix86_unary_operator_ok (NEG, QImode, operands)"
9663   "neg{b}\t%0"
9664   [(set_attr "type" "negnot")
9665    (set_attr "mode" "QI")])
9666
9667 ;; Changing of sign for FP values is doable using integer unit too.
9668
9669 (define_expand "negsf2"
9670   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9671         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9672   "TARGET_80387 || TARGET_SSE_MATH"
9673   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9674
9675 (define_expand "abssf2"
9676   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9677         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9678   "TARGET_80387 || TARGET_SSE_MATH"
9679   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9680
9681 (define_insn "*absnegsf2_mixed"
9682   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#fr,x#fr,f#xr,rm#xf")
9683         (match_operator:SF 3 "absneg_operator"
9684           [(match_operand:SF 1 "nonimmediate_operand" "0    ,x#fr,0   ,0")]))
9685    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm   ,0   ,X   ,X"))
9686    (clobber (reg:CC FLAGS_REG))]
9687   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9688    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9689   "#")
9690
9691 (define_insn "*absnegsf2_sse"
9692   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#r,x#r,rm#x")
9693         (match_operator:SF 3 "absneg_operator"
9694           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#r,0")]))
9695    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X"))
9696    (clobber (reg:CC FLAGS_REG))]
9697   "TARGET_SSE_MATH
9698    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9699   "#")
9700
9701 (define_insn "*absnegsf2_i387"
9702   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9703         (match_operator:SF 3 "absneg_operator"
9704           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9705    (use (match_operand 2 "" ""))
9706    (clobber (reg:CC FLAGS_REG))]
9707   "TARGET_80387 && !TARGET_SSE_MATH
9708    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9709   "#")
9710
9711 (define_expand "negdf2"
9712   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9713         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9714   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9715   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9716
9717 (define_expand "absdf2"
9718   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9719         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9720   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9721   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9722
9723 (define_insn "*absnegdf2_mixed"
9724   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#fr,Y#fr,f#Yr,rm#Yf")
9725         (match_operator:DF 3 "absneg_operator"
9726           [(match_operand:DF 1 "nonimmediate_operand" "0    ,Y#fr,0   ,0")]))
9727    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym   ,0   ,X   ,X"))
9728    (clobber (reg:CC FLAGS_REG))]
9729   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9730    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9731   "#")
9732
9733 (define_insn "*absnegdf2_sse"
9734   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#r,Y#r,rm#Y")
9735         (match_operator:DF 3 "absneg_operator"
9736           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#r,0")]))
9737    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X"))
9738    (clobber (reg:CC FLAGS_REG))]
9739   "TARGET_SSE2 && TARGET_SSE_MATH
9740    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9741   "#")
9742
9743 (define_insn "*absnegdf2_i387"
9744   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9745         (match_operator:DF 3 "absneg_operator"
9746           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9747    (use (match_operand 2 "" ""))
9748    (clobber (reg:CC FLAGS_REG))]
9749   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9750    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9751   "#")
9752
9753 (define_expand "negxf2"
9754   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9755         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9756   "TARGET_80387"
9757   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9758
9759 (define_expand "absxf2"
9760   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9761         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9762   "TARGET_80387"
9763   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9764
9765 (define_insn "*absnegxf2_i387"
9766   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9767         (match_operator:XF 3 "absneg_operator"
9768           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9769    (use (match_operand 2 "" ""))
9770    (clobber (reg:CC FLAGS_REG))]
9771   "TARGET_80387
9772    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9773   "#")
9774
9775 ;; Splitters for fp abs and neg.
9776
9777 (define_split
9778   [(set (match_operand 0 "fp_register_operand" "")
9779         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9780    (use (match_operand 2 "" ""))
9781    (clobber (reg:CC FLAGS_REG))]
9782   "reload_completed"
9783   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9784
9785 (define_split
9786   [(set (match_operand 0 "register_operand" "")
9787         (match_operator 3 "absneg_operator"
9788           [(match_operand 1 "register_operand" "")]))
9789    (use (match_operand 2 "nonimmediate_operand" ""))
9790    (clobber (reg:CC FLAGS_REG))]
9791   "reload_completed && SSE_REG_P (operands[0])"
9792   [(set (match_dup 0) (match_dup 3))]
9793 {
9794   enum machine_mode mode = GET_MODE (operands[0]);
9795   enum machine_mode vmode = GET_MODE (operands[2]);
9796   rtx tmp;
9797   
9798   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9799   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9800   if (operands_match_p (operands[0], operands[2]))
9801     {
9802       tmp = operands[1];
9803       operands[1] = operands[2];
9804       operands[2] = tmp;
9805     }
9806   if (GET_CODE (operands[3]) == ABS)
9807     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9808   else
9809     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9810   operands[3] = tmp;
9811 })
9812
9813 (define_split
9814   [(set (match_operand:SF 0 "register_operand" "")
9815         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9816    (use (match_operand:V4SF 2 "" ""))
9817    (clobber (reg:CC FLAGS_REG))]
9818   "reload_completed"
9819   [(parallel [(set (match_dup 0) (match_dup 1))
9820               (clobber (reg:CC FLAGS_REG))])]
9821
9822   rtx tmp;
9823   operands[0] = gen_lowpart (SImode, operands[0]);
9824   if (GET_CODE (operands[1]) == ABS)
9825     {
9826       tmp = gen_int_mode (0x7fffffff, SImode);
9827       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9828     }
9829   else
9830     {
9831       tmp = gen_int_mode (0x80000000, SImode);
9832       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9833     }
9834   operands[1] = tmp;
9835 })
9836
9837 (define_split
9838   [(set (match_operand:DF 0 "register_operand" "")
9839         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9840    (use (match_operand 2 "" ""))
9841    (clobber (reg:CC FLAGS_REG))]
9842   "reload_completed"
9843   [(parallel [(set (match_dup 0) (match_dup 1))
9844               (clobber (reg:CC FLAGS_REG))])]
9845 {
9846   rtx tmp;
9847   if (TARGET_64BIT)
9848     {
9849       tmp = gen_lowpart (DImode, operands[0]);
9850       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9851       operands[0] = tmp;
9852
9853       if (GET_CODE (operands[1]) == ABS)
9854         tmp = const0_rtx;
9855       else
9856         tmp = gen_rtx_NOT (DImode, tmp);
9857     }
9858   else
9859     {
9860       operands[0] = gen_highpart (SImode, operands[0]);
9861       if (GET_CODE (operands[1]) == ABS)
9862         {
9863           tmp = gen_int_mode (0x7fffffff, SImode);
9864           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9865         }
9866       else
9867         {
9868           tmp = gen_int_mode (0x80000000, SImode);
9869           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9870         }
9871     }
9872   operands[1] = tmp;
9873 })
9874
9875 (define_split
9876   [(set (match_operand:XF 0 "register_operand" "")
9877         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9878    (use (match_operand 2 "" ""))
9879    (clobber (reg:CC FLAGS_REG))]
9880   "reload_completed"
9881   [(parallel [(set (match_dup 0) (match_dup 1))
9882               (clobber (reg:CC FLAGS_REG))])]
9883 {
9884   rtx tmp;
9885   operands[0] = gen_rtx_REG (SImode,
9886                              true_regnum (operands[0])
9887                              + (TARGET_64BIT ? 1 : 2));
9888   if (GET_CODE (operands[1]) == ABS)
9889     {
9890       tmp = GEN_INT (0x7fff);
9891       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9892     }
9893   else
9894     {
9895       tmp = GEN_INT (0x8000);
9896       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9897     }
9898   operands[1] = tmp;
9899 })
9900
9901 (define_split
9902   [(set (match_operand 0 "memory_operand" "")
9903         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9904    (use (match_operand 2 "" ""))
9905    (clobber (reg:CC FLAGS_REG))]
9906   "reload_completed"
9907   [(parallel [(set (match_dup 0) (match_dup 1))
9908               (clobber (reg:CC FLAGS_REG))])]
9909 {
9910   enum machine_mode mode = GET_MODE (operands[0]);
9911   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9912   rtx tmp;
9913
9914   operands[0] = adjust_address (operands[0], QImode, size - 1);
9915   if (GET_CODE (operands[1]) == ABS)
9916     {
9917       tmp = gen_int_mode (0x7f, QImode);
9918       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9919     }
9920   else
9921     {
9922       tmp = gen_int_mode (0x80, QImode);
9923       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9924     }
9925   operands[1] = tmp;
9926 })
9927
9928 ;; Conditionalize these after reload. If they match before reload, we 
9929 ;; lose the clobber and ability to use integer instructions.
9930
9931 (define_insn "*negsf2_1"
9932   [(set (match_operand:SF 0 "register_operand" "=f")
9933         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9934   "TARGET_80387 && reload_completed"
9935   "fchs"
9936   [(set_attr "type" "fsgn")
9937    (set_attr "mode" "SF")])
9938
9939 (define_insn "*negdf2_1"
9940   [(set (match_operand:DF 0 "register_operand" "=f")
9941         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9942   "TARGET_80387 && reload_completed"
9943   "fchs"
9944   [(set_attr "type" "fsgn")
9945    (set_attr "mode" "DF")])
9946
9947 (define_insn "*negxf2_1"
9948   [(set (match_operand:XF 0 "register_operand" "=f")
9949         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9950   "TARGET_80387 && reload_completed"
9951   "fchs"
9952   [(set_attr "type" "fsgn")
9953    (set_attr "mode" "XF")])
9954
9955 (define_insn "*abssf2_1"
9956   [(set (match_operand:SF 0 "register_operand" "=f")
9957         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9958   "TARGET_80387 && reload_completed"
9959   "fabs"
9960   [(set_attr "type" "fsgn")
9961    (set_attr "mode" "SF")])
9962
9963 (define_insn "*absdf2_1"
9964   [(set (match_operand:DF 0 "register_operand" "=f")
9965         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9966   "TARGET_80387 && reload_completed"
9967   "fabs"
9968   [(set_attr "type" "fsgn")
9969    (set_attr "mode" "DF")])
9970
9971 (define_insn "*absxf2_1"
9972   [(set (match_operand:XF 0 "register_operand" "=f")
9973         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9974   "TARGET_80387 && reload_completed"
9975   "fabs"
9976   [(set_attr "type" "fsgn")
9977    (set_attr "mode" "DF")])
9978
9979 (define_insn "*negextendsfdf2"
9980   [(set (match_operand:DF 0 "register_operand" "=f")
9981         (neg:DF (float_extend:DF
9982                   (match_operand:SF 1 "register_operand" "0"))))]
9983   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9984   "fchs"
9985   [(set_attr "type" "fsgn")
9986    (set_attr "mode" "DF")])
9987
9988 (define_insn "*negextenddfxf2"
9989   [(set (match_operand:XF 0 "register_operand" "=f")
9990         (neg:XF (float_extend:XF
9991                   (match_operand:DF 1 "register_operand" "0"))))]
9992   "TARGET_80387"
9993   "fchs"
9994   [(set_attr "type" "fsgn")
9995    (set_attr "mode" "XF")])
9996
9997 (define_insn "*negextendsfxf2"
9998   [(set (match_operand:XF 0 "register_operand" "=f")
9999         (neg:XF (float_extend:XF
10000                   (match_operand:SF 1 "register_operand" "0"))))]
10001   "TARGET_80387"
10002   "fchs"
10003   [(set_attr "type" "fsgn")
10004    (set_attr "mode" "XF")])
10005
10006 (define_insn "*absextendsfdf2"
10007   [(set (match_operand:DF 0 "register_operand" "=f")
10008         (abs:DF (float_extend:DF
10009                   (match_operand:SF 1 "register_operand" "0"))))]
10010   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10011   "fabs"
10012   [(set_attr "type" "fsgn")
10013    (set_attr "mode" "DF")])
10014
10015 (define_insn "*absextenddfxf2"
10016   [(set (match_operand:XF 0 "register_operand" "=f")
10017         (abs:XF (float_extend:XF
10018           (match_operand:DF 1 "register_operand" "0"))))]
10019   "TARGET_80387"
10020   "fabs"
10021   [(set_attr "type" "fsgn")
10022    (set_attr "mode" "XF")])
10023
10024 (define_insn "*absextendsfxf2"
10025   [(set (match_operand:XF 0 "register_operand" "=f")
10026         (abs:XF (float_extend:XF
10027           (match_operand:SF 1 "register_operand" "0"))))]
10028   "TARGET_80387"
10029   "fabs"
10030   [(set_attr "type" "fsgn")
10031    (set_attr "mode" "XF")])
10032 \f
10033 ;; One complement instructions
10034
10035 (define_expand "one_cmpldi2"
10036   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10037         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10038   "TARGET_64BIT"
10039   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10040
10041 (define_insn "*one_cmpldi2_1_rex64"
10042   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10043         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10044   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10045   "not{q}\t%0"
10046   [(set_attr "type" "negnot")
10047    (set_attr "mode" "DI")])
10048
10049 (define_insn "*one_cmpldi2_2_rex64"
10050   [(set (reg FLAGS_REG)
10051         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10052                  (const_int 0)))
10053    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10054         (not:DI (match_dup 1)))]
10055   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10056    && ix86_unary_operator_ok (NOT, DImode, operands)"
10057   "#"
10058   [(set_attr "type" "alu1")
10059    (set_attr "mode" "DI")])
10060
10061 (define_split
10062   [(set (match_operand 0 "flags_reg_operand" "")
10063         (match_operator 2 "compare_operator"
10064           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10065            (const_int 0)]))
10066    (set (match_operand:DI 1 "nonimmediate_operand" "")
10067         (not:DI (match_dup 3)))]
10068   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10069   [(parallel [(set (match_dup 0)
10070                    (match_op_dup 2
10071                      [(xor:DI (match_dup 3) (const_int -1))
10072                       (const_int 0)]))
10073               (set (match_dup 1)
10074                    (xor:DI (match_dup 3) (const_int -1)))])]
10075   "")
10076
10077 (define_expand "one_cmplsi2"
10078   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10079         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10080   ""
10081   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10082
10083 (define_insn "*one_cmplsi2_1"
10084   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10085         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10086   "ix86_unary_operator_ok (NOT, SImode, operands)"
10087   "not{l}\t%0"
10088   [(set_attr "type" "negnot")
10089    (set_attr "mode" "SI")])
10090
10091 ;; ??? Currently never generated - xor is used instead.
10092 (define_insn "*one_cmplsi2_1_zext"
10093   [(set (match_operand:DI 0 "register_operand" "=r")
10094         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10095   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10096   "not{l}\t%k0"
10097   [(set_attr "type" "negnot")
10098    (set_attr "mode" "SI")])
10099
10100 (define_insn "*one_cmplsi2_2"
10101   [(set (reg FLAGS_REG)
10102         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10103                  (const_int 0)))
10104    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10105         (not:SI (match_dup 1)))]
10106   "ix86_match_ccmode (insn, CCNOmode)
10107    && ix86_unary_operator_ok (NOT, SImode, operands)"
10108   "#"
10109   [(set_attr "type" "alu1")
10110    (set_attr "mode" "SI")])
10111
10112 (define_split
10113   [(set (match_operand 0 "flags_reg_operand" "")
10114         (match_operator 2 "compare_operator"
10115           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10116            (const_int 0)]))
10117    (set (match_operand:SI 1 "nonimmediate_operand" "")
10118         (not:SI (match_dup 3)))]
10119   "ix86_match_ccmode (insn, CCNOmode)"
10120   [(parallel [(set (match_dup 0)
10121                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10122                                     (const_int 0)]))
10123               (set (match_dup 1)
10124                    (xor:SI (match_dup 3) (const_int -1)))])]
10125   "")
10126
10127 ;; ??? Currently never generated - xor is used instead.
10128 (define_insn "*one_cmplsi2_2_zext"
10129   [(set (reg FLAGS_REG)
10130         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10131                  (const_int 0)))
10132    (set (match_operand:DI 0 "register_operand" "=r")
10133         (zero_extend:DI (not:SI (match_dup 1))))]
10134   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10135    && ix86_unary_operator_ok (NOT, SImode, operands)"
10136   "#"
10137   [(set_attr "type" "alu1")
10138    (set_attr "mode" "SI")])
10139
10140 (define_split
10141   [(set (match_operand 0 "flags_reg_operand" "")
10142         (match_operator 2 "compare_operator"
10143           [(not:SI (match_operand:SI 3 "register_operand" ""))
10144            (const_int 0)]))
10145    (set (match_operand:DI 1 "register_operand" "")
10146         (zero_extend:DI (not:SI (match_dup 3))))]
10147   "ix86_match_ccmode (insn, CCNOmode)"
10148   [(parallel [(set (match_dup 0)
10149                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10150                                     (const_int 0)]))
10151               (set (match_dup 1)
10152                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10153   "")
10154
10155 (define_expand "one_cmplhi2"
10156   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10157         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10158   "TARGET_HIMODE_MATH"
10159   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10160
10161 (define_insn "*one_cmplhi2_1"
10162   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10163         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10164   "ix86_unary_operator_ok (NOT, HImode, operands)"
10165   "not{w}\t%0"
10166   [(set_attr "type" "negnot")
10167    (set_attr "mode" "HI")])
10168
10169 (define_insn "*one_cmplhi2_2"
10170   [(set (reg FLAGS_REG)
10171         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10172                  (const_int 0)))
10173    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10174         (not:HI (match_dup 1)))]
10175   "ix86_match_ccmode (insn, CCNOmode)
10176    && ix86_unary_operator_ok (NEG, HImode, operands)"
10177   "#"
10178   [(set_attr "type" "alu1")
10179    (set_attr "mode" "HI")])
10180
10181 (define_split
10182   [(set (match_operand 0 "flags_reg_operand" "")
10183         (match_operator 2 "compare_operator"
10184           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10185            (const_int 0)]))
10186    (set (match_operand:HI 1 "nonimmediate_operand" "")
10187         (not:HI (match_dup 3)))]
10188   "ix86_match_ccmode (insn, CCNOmode)"
10189   [(parallel [(set (match_dup 0)
10190                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10191                                     (const_int 0)]))
10192               (set (match_dup 1)
10193                    (xor:HI (match_dup 3) (const_int -1)))])]
10194   "")
10195
10196 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10197 (define_expand "one_cmplqi2"
10198   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10199         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10200   "TARGET_QIMODE_MATH"
10201   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10202
10203 (define_insn "*one_cmplqi2_1"
10204   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10205         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10206   "ix86_unary_operator_ok (NOT, QImode, operands)"
10207   "@
10208    not{b}\t%0
10209    not{l}\t%k0"
10210   [(set_attr "type" "negnot")
10211    (set_attr "mode" "QI,SI")])
10212
10213 (define_insn "*one_cmplqi2_2"
10214   [(set (reg FLAGS_REG)
10215         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10216                  (const_int 0)))
10217    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10218         (not:QI (match_dup 1)))]
10219   "ix86_match_ccmode (insn, CCNOmode)
10220    && ix86_unary_operator_ok (NOT, QImode, operands)"
10221   "#"
10222   [(set_attr "type" "alu1")
10223    (set_attr "mode" "QI")])
10224
10225 (define_split
10226   [(set (match_operand 0 "flags_reg_operand" "")
10227         (match_operator 2 "compare_operator"
10228           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10229            (const_int 0)]))
10230    (set (match_operand:QI 1 "nonimmediate_operand" "")
10231         (not:QI (match_dup 3)))]
10232   "ix86_match_ccmode (insn, CCNOmode)"
10233   [(parallel [(set (match_dup 0)
10234                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10235                                     (const_int 0)]))
10236               (set (match_dup 1)
10237                    (xor:QI (match_dup 3) (const_int -1)))])]
10238   "")
10239 \f
10240 ;; Arithmetic shift instructions
10241
10242 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10243 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10244 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10245 ;; from the assembler input.
10246 ;;
10247 ;; This instruction shifts the target reg/mem as usual, but instead of
10248 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10249 ;; is a left shift double, bits are taken from the high order bits of
10250 ;; reg, else if the insn is a shift right double, bits are taken from the
10251 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10252 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10253 ;;
10254 ;; Since sh[lr]d does not change the `reg' operand, that is done
10255 ;; separately, making all shifts emit pairs of shift double and normal
10256 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10257 ;; support a 63 bit shift, each shift where the count is in a reg expands
10258 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10259 ;;
10260 ;; If the shift count is a constant, we need never emit more than one
10261 ;; shift pair, instead using moves and sign extension for counts greater
10262 ;; than 31.
10263
10264 (define_expand "ashldi3"
10265   [(set (match_operand:DI 0 "shiftdi_operand" "")
10266         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10267                    (match_operand:QI 2 "nonmemory_operand" "")))]
10268   ""
10269   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10270
10271 (define_insn "*ashldi3_1_rex64"
10272   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10273         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10274                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10275    (clobber (reg:CC FLAGS_REG))]
10276   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10277 {
10278   switch (get_attr_type (insn))
10279     {
10280     case TYPE_ALU:
10281       if (operands[2] != const1_rtx)
10282         abort ();
10283       if (!rtx_equal_p (operands[0], operands[1]))
10284         abort ();
10285       return "add{q}\t{%0, %0|%0, %0}";
10286
10287     case TYPE_LEA:
10288       if (GET_CODE (operands[2]) != CONST_INT
10289           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10290         abort ();
10291       operands[1] = gen_rtx_MULT (DImode, operands[1],
10292                                   GEN_INT (1 << INTVAL (operands[2])));
10293       return "lea{q}\t{%a1, %0|%0, %a1}";
10294
10295     default:
10296       if (REG_P (operands[2]))
10297         return "sal{q}\t{%b2, %0|%0, %b2}";
10298       else if (operands[2] == const1_rtx
10299                && (TARGET_SHIFT1 || optimize_size))
10300         return "sal{q}\t%0";
10301       else
10302         return "sal{q}\t{%2, %0|%0, %2}";
10303     }
10304 }
10305   [(set (attr "type")
10306      (cond [(eq_attr "alternative" "1")
10307               (const_string "lea")
10308             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10309                           (const_int 0))
10310                       (match_operand 0 "register_operand" ""))
10311                  (match_operand 2 "const1_operand" ""))
10312               (const_string "alu")
10313            ]
10314            (const_string "ishift")))
10315    (set_attr "mode" "DI")])
10316
10317 ;; Convert lea to the lea pattern to avoid flags dependency.
10318 (define_split
10319   [(set (match_operand:DI 0 "register_operand" "")
10320         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10321                    (match_operand:QI 2 "immediate_operand" "")))
10322    (clobber (reg:CC FLAGS_REG))]
10323   "TARGET_64BIT && reload_completed
10324    && true_regnum (operands[0]) != true_regnum (operands[1])"
10325   [(set (match_dup 0)
10326         (mult:DI (match_dup 1)
10327                  (match_dup 2)))]
10328   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10329
10330 ;; This pattern can't accept a variable shift count, since shifts by
10331 ;; zero don't affect the flags.  We assume that shifts by constant
10332 ;; zero are optimized away.
10333 (define_insn "*ashldi3_cmp_rex64"
10334   [(set (reg FLAGS_REG)
10335         (compare
10336           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10337                      (match_operand:QI 2 "immediate_operand" "e"))
10338           (const_int 0)))
10339    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10340         (ashift:DI (match_dup 1) (match_dup 2)))]
10341   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10342    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10343 {
10344   switch (get_attr_type (insn))
10345     {
10346     case TYPE_ALU:
10347       if (operands[2] != const1_rtx)
10348         abort ();
10349       return "add{q}\t{%0, %0|%0, %0}";
10350
10351     default:
10352       if (REG_P (operands[2]))
10353         return "sal{q}\t{%b2, %0|%0, %b2}";
10354       else if (operands[2] == const1_rtx
10355                && (TARGET_SHIFT1 || optimize_size))
10356         return "sal{q}\t%0";
10357       else
10358         return "sal{q}\t{%2, %0|%0, %2}";
10359     }
10360 }
10361   [(set (attr "type")
10362      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10363                           (const_int 0))
10364                       (match_operand 0 "register_operand" ""))
10365                  (match_operand 2 "const1_operand" ""))
10366               (const_string "alu")
10367            ]
10368            (const_string "ishift")))
10369    (set_attr "mode" "DI")])
10370
10371 (define_insn "*ashldi3_1"
10372   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10373         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10374                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10375    (clobber (reg:CC FLAGS_REG))]
10376   "!TARGET_64BIT"
10377   "#"
10378   [(set_attr "type" "multi")])
10379
10380 ;; By default we don't ask for a scratch register, because when DImode
10381 ;; values are manipulated, registers are already at a premium.  But if
10382 ;; we have one handy, we won't turn it away.
10383 (define_peephole2
10384   [(match_scratch:SI 3 "r")
10385    (parallel [(set (match_operand:DI 0 "register_operand" "")
10386                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10387                               (match_operand:QI 2 "nonmemory_operand" "")))
10388               (clobber (reg:CC FLAGS_REG))])
10389    (match_dup 3)]
10390   "!TARGET_64BIT && TARGET_CMOVE"
10391   [(const_int 0)]
10392   "ix86_split_ashldi (operands, operands[3]); DONE;")
10393
10394 (define_split
10395   [(set (match_operand:DI 0 "register_operand" "")
10396         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10397                    (match_operand:QI 2 "nonmemory_operand" "")))
10398    (clobber (reg:CC FLAGS_REG))]
10399   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10400   [(const_int 0)]
10401   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10402
10403 (define_insn "x86_shld_1"
10404   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10405         (ior:SI (ashift:SI (match_dup 0)
10406                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10407                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10408                   (minus:QI (const_int 32) (match_dup 2)))))
10409    (clobber (reg:CC FLAGS_REG))]
10410   ""
10411   "@
10412    shld{l}\t{%2, %1, %0|%0, %1, %2}
10413    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10414   [(set_attr "type" "ishift")
10415    (set_attr "prefix_0f" "1")
10416    (set_attr "mode" "SI")
10417    (set_attr "pent_pair" "np")
10418    (set_attr "athlon_decode" "vector")])
10419
10420 (define_expand "x86_shift_adj_1"
10421   [(set (reg:CCZ FLAGS_REG)
10422         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10423                              (const_int 32))
10424                      (const_int 0)))
10425    (set (match_operand:SI 0 "register_operand" "")
10426         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10427                          (match_operand:SI 1 "register_operand" "")
10428                          (match_dup 0)))
10429    (set (match_dup 1)
10430         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10431                          (match_operand:SI 3 "register_operand" "r")
10432                          (match_dup 1)))]
10433   "TARGET_CMOVE"
10434   "")
10435
10436 (define_expand "x86_shift_adj_2"
10437   [(use (match_operand:SI 0 "register_operand" ""))
10438    (use (match_operand:SI 1 "register_operand" ""))
10439    (use (match_operand:QI 2 "register_operand" ""))]
10440   ""
10441 {
10442   rtx label = gen_label_rtx ();
10443   rtx tmp;
10444
10445   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10446
10447   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10448   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10449   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10450                               gen_rtx_LABEL_REF (VOIDmode, label),
10451                               pc_rtx);
10452   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10453   JUMP_LABEL (tmp) = label;
10454
10455   emit_move_insn (operands[0], operands[1]);
10456   ix86_expand_clear (operands[1]);
10457
10458   emit_label (label);
10459   LABEL_NUSES (label) = 1;
10460
10461   DONE;
10462 })
10463
10464 (define_expand "ashlsi3"
10465   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10466         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10467                    (match_operand:QI 2 "nonmemory_operand" "")))
10468    (clobber (reg:CC FLAGS_REG))]
10469   ""
10470   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10471
10472 (define_insn "*ashlsi3_1"
10473   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10474         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10475                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10476    (clobber (reg:CC FLAGS_REG))]
10477   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10478 {
10479   switch (get_attr_type (insn))
10480     {
10481     case TYPE_ALU:
10482       if (operands[2] != const1_rtx)
10483         abort ();
10484       if (!rtx_equal_p (operands[0], operands[1]))
10485         abort ();
10486       return "add{l}\t{%0, %0|%0, %0}";
10487
10488     case TYPE_LEA:
10489       return "#";
10490
10491     default:
10492       if (REG_P (operands[2]))
10493         return "sal{l}\t{%b2, %0|%0, %b2}";
10494       else if (operands[2] == const1_rtx
10495                && (TARGET_SHIFT1 || optimize_size))
10496         return "sal{l}\t%0";
10497       else
10498         return "sal{l}\t{%2, %0|%0, %2}";
10499     }
10500 }
10501   [(set (attr "type")
10502      (cond [(eq_attr "alternative" "1")
10503               (const_string "lea")
10504             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10505                           (const_int 0))
10506                       (match_operand 0 "register_operand" ""))
10507                  (match_operand 2 "const1_operand" ""))
10508               (const_string "alu")
10509            ]
10510            (const_string "ishift")))
10511    (set_attr "mode" "SI")])
10512
10513 ;; Convert lea to the lea pattern to avoid flags dependency.
10514 (define_split
10515   [(set (match_operand 0 "register_operand" "")
10516         (ashift (match_operand 1 "index_register_operand" "")
10517                 (match_operand:QI 2 "const_int_operand" "")))
10518    (clobber (reg:CC FLAGS_REG))]
10519   "reload_completed
10520    && true_regnum (operands[0]) != true_regnum (operands[1])
10521    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10522   [(const_int 0)]
10523 {
10524   rtx pat;
10525   enum machine_mode mode = GET_MODE (operands[0]);
10526
10527   if (GET_MODE_SIZE (mode) < 4)
10528     operands[0] = gen_lowpart (SImode, operands[0]);
10529   if (mode != Pmode)
10530     operands[1] = gen_lowpart (Pmode, operands[1]);
10531   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10532
10533   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10534   if (Pmode != SImode)
10535     pat = gen_rtx_SUBREG (SImode, pat, 0);
10536   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10537   DONE;
10538 })
10539
10540 ;; Rare case of shifting RSP is handled by generating move and shift
10541 (define_split
10542   [(set (match_operand 0 "register_operand" "")
10543         (ashift (match_operand 1 "register_operand" "")
10544                 (match_operand:QI 2 "const_int_operand" "")))
10545    (clobber (reg:CC FLAGS_REG))]
10546   "reload_completed
10547    && true_regnum (operands[0]) != true_regnum (operands[1])"
10548   [(const_int 0)]
10549 {
10550   rtx pat, clob;
10551   emit_move_insn (operands[1], operands[0]);
10552   pat = gen_rtx_SET (VOIDmode, operands[0],
10553                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10554                                      operands[0], operands[2]));
10555   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10556   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10557   DONE;
10558 })
10559
10560 (define_insn "*ashlsi3_1_zext"
10561   [(set (match_operand:DI 0 "register_operand" "=r,r")
10562         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10563                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10564    (clobber (reg:CC FLAGS_REG))]
10565   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10566 {
10567   switch (get_attr_type (insn))
10568     {
10569     case TYPE_ALU:
10570       if (operands[2] != const1_rtx)
10571         abort ();
10572       return "add{l}\t{%k0, %k0|%k0, %k0}";
10573
10574     case TYPE_LEA:
10575       return "#";
10576
10577     default:
10578       if (REG_P (operands[2]))
10579         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10580       else if (operands[2] == const1_rtx
10581                && (TARGET_SHIFT1 || optimize_size))
10582         return "sal{l}\t%k0";
10583       else
10584         return "sal{l}\t{%2, %k0|%k0, %2}";
10585     }
10586 }
10587   [(set (attr "type")
10588      (cond [(eq_attr "alternative" "1")
10589               (const_string "lea")
10590             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10591                      (const_int 0))
10592                  (match_operand 2 "const1_operand" ""))
10593               (const_string "alu")
10594            ]
10595            (const_string "ishift")))
10596    (set_attr "mode" "SI")])
10597
10598 ;; Convert lea to the lea pattern to avoid flags dependency.
10599 (define_split
10600   [(set (match_operand:DI 0 "register_operand" "")
10601         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10602                                 (match_operand:QI 2 "const_int_operand" ""))))
10603    (clobber (reg:CC FLAGS_REG))]
10604   "TARGET_64BIT && reload_completed
10605    && true_regnum (operands[0]) != true_regnum (operands[1])"
10606   [(set (match_dup 0) (zero_extend:DI
10607                         (subreg:SI (mult:SI (match_dup 1)
10608                                             (match_dup 2)) 0)))]
10609 {
10610   operands[1] = gen_lowpart (Pmode, operands[1]);
10611   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10612 })
10613
10614 ;; This pattern can't accept a variable shift count, since shifts by
10615 ;; zero don't affect the flags.  We assume that shifts by constant
10616 ;; zero are optimized away.
10617 (define_insn "*ashlsi3_cmp"
10618   [(set (reg FLAGS_REG)
10619         (compare
10620           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10621                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10622           (const_int 0)))
10623    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10624         (ashift:SI (match_dup 1) (match_dup 2)))]
10625   "ix86_match_ccmode (insn, CCGOCmode)
10626    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10627 {
10628   switch (get_attr_type (insn))
10629     {
10630     case TYPE_ALU:
10631       if (operands[2] != const1_rtx)
10632         abort ();
10633       return "add{l}\t{%0, %0|%0, %0}";
10634
10635     default:
10636       if (REG_P (operands[2]))
10637         return "sal{l}\t{%b2, %0|%0, %b2}";
10638       else if (operands[2] == const1_rtx
10639                && (TARGET_SHIFT1 || optimize_size))
10640         return "sal{l}\t%0";
10641       else
10642         return "sal{l}\t{%2, %0|%0, %2}";
10643     }
10644 }
10645   [(set (attr "type")
10646      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10647                           (const_int 0))
10648                       (match_operand 0 "register_operand" ""))
10649                  (match_operand 2 "const1_operand" ""))
10650               (const_string "alu")
10651            ]
10652            (const_string "ishift")))
10653    (set_attr "mode" "SI")])
10654
10655 (define_insn "*ashlsi3_cmp_zext"
10656   [(set (reg FLAGS_REG)
10657         (compare
10658           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10659                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10660           (const_int 0)))
10661    (set (match_operand:DI 0 "register_operand" "=r")
10662         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10663   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10664    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10665 {
10666   switch (get_attr_type (insn))
10667     {
10668     case TYPE_ALU:
10669       if (operands[2] != const1_rtx)
10670         abort ();
10671       return "add{l}\t{%k0, %k0|%k0, %k0}";
10672
10673     default:
10674       if (REG_P (operands[2]))
10675         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10676       else if (operands[2] == const1_rtx
10677                && (TARGET_SHIFT1 || optimize_size))
10678         return "sal{l}\t%k0";
10679       else
10680         return "sal{l}\t{%2, %k0|%k0, %2}";
10681     }
10682 }
10683   [(set (attr "type")
10684      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10685                      (const_int 0))
10686                  (match_operand 2 "const1_operand" ""))
10687               (const_string "alu")
10688            ]
10689            (const_string "ishift")))
10690    (set_attr "mode" "SI")])
10691
10692 (define_expand "ashlhi3"
10693   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10694         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10695                    (match_operand:QI 2 "nonmemory_operand" "")))
10696    (clobber (reg:CC FLAGS_REG))]
10697   "TARGET_HIMODE_MATH"
10698   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10699
10700 (define_insn "*ashlhi3_1_lea"
10701   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10702         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10703                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10704    (clobber (reg:CC FLAGS_REG))]
10705   "!TARGET_PARTIAL_REG_STALL
10706    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10707 {
10708   switch (get_attr_type (insn))
10709     {
10710     case TYPE_LEA:
10711       return "#";
10712     case TYPE_ALU:
10713       if (operands[2] != const1_rtx)
10714         abort ();
10715       return "add{w}\t{%0, %0|%0, %0}";
10716
10717     default:
10718       if (REG_P (operands[2]))
10719         return "sal{w}\t{%b2, %0|%0, %b2}";
10720       else if (operands[2] == const1_rtx
10721                && (TARGET_SHIFT1 || optimize_size))
10722         return "sal{w}\t%0";
10723       else
10724         return "sal{w}\t{%2, %0|%0, %2}";
10725     }
10726 }
10727   [(set (attr "type")
10728      (cond [(eq_attr "alternative" "1")
10729               (const_string "lea")
10730             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10731                           (const_int 0))
10732                       (match_operand 0 "register_operand" ""))
10733                  (match_operand 2 "const1_operand" ""))
10734               (const_string "alu")
10735            ]
10736            (const_string "ishift")))
10737    (set_attr "mode" "HI,SI")])
10738
10739 (define_insn "*ashlhi3_1"
10740   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10741         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10742                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10743    (clobber (reg:CC FLAGS_REG))]
10744   "TARGET_PARTIAL_REG_STALL
10745    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10746 {
10747   switch (get_attr_type (insn))
10748     {
10749     case TYPE_ALU:
10750       if (operands[2] != const1_rtx)
10751         abort ();
10752       return "add{w}\t{%0, %0|%0, %0}";
10753
10754     default:
10755       if (REG_P (operands[2]))
10756         return "sal{w}\t{%b2, %0|%0, %b2}";
10757       else if (operands[2] == const1_rtx
10758                && (TARGET_SHIFT1 || optimize_size))
10759         return "sal{w}\t%0";
10760       else
10761         return "sal{w}\t{%2, %0|%0, %2}";
10762     }
10763 }
10764   [(set (attr "type")
10765      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10766                           (const_int 0))
10767                       (match_operand 0 "register_operand" ""))
10768                  (match_operand 2 "const1_operand" ""))
10769               (const_string "alu")
10770            ]
10771            (const_string "ishift")))
10772    (set_attr "mode" "HI")])
10773
10774 ;; This pattern can't accept a variable shift count, since shifts by
10775 ;; zero don't affect the flags.  We assume that shifts by constant
10776 ;; zero are optimized away.
10777 (define_insn "*ashlhi3_cmp"
10778   [(set (reg FLAGS_REG)
10779         (compare
10780           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10781                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10782           (const_int 0)))
10783    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10784         (ashift:HI (match_dup 1) (match_dup 2)))]
10785   "ix86_match_ccmode (insn, CCGOCmode)
10786    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10787 {
10788   switch (get_attr_type (insn))
10789     {
10790     case TYPE_ALU:
10791       if (operands[2] != const1_rtx)
10792         abort ();
10793       return "add{w}\t{%0, %0|%0, %0}";
10794
10795     default:
10796       if (REG_P (operands[2]))
10797         return "sal{w}\t{%b2, %0|%0, %b2}";
10798       else if (operands[2] == const1_rtx
10799                && (TARGET_SHIFT1 || optimize_size))
10800         return "sal{w}\t%0";
10801       else
10802         return "sal{w}\t{%2, %0|%0, %2}";
10803     }
10804 }
10805   [(set (attr "type")
10806      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10807                           (const_int 0))
10808                       (match_operand 0 "register_operand" ""))
10809                  (match_operand 2 "const1_operand" ""))
10810               (const_string "alu")
10811            ]
10812            (const_string "ishift")))
10813    (set_attr "mode" "HI")])
10814
10815 (define_expand "ashlqi3"
10816   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10817         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10818                    (match_operand:QI 2 "nonmemory_operand" "")))
10819    (clobber (reg:CC FLAGS_REG))]
10820   "TARGET_QIMODE_MATH"
10821   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10822
10823 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10824
10825 (define_insn "*ashlqi3_1_lea"
10826   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10827         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10828                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10829    (clobber (reg:CC FLAGS_REG))]
10830   "!TARGET_PARTIAL_REG_STALL
10831    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10832 {
10833   switch (get_attr_type (insn))
10834     {
10835     case TYPE_LEA:
10836       return "#";
10837     case TYPE_ALU:
10838       if (operands[2] != const1_rtx)
10839         abort ();
10840       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10841         return "add{l}\t{%k0, %k0|%k0, %k0}";
10842       else
10843         return "add{b}\t{%0, %0|%0, %0}";
10844
10845     default:
10846       if (REG_P (operands[2]))
10847         {
10848           if (get_attr_mode (insn) == MODE_SI)
10849             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10850           else
10851             return "sal{b}\t{%b2, %0|%0, %b2}";
10852         }
10853       else if (operands[2] == const1_rtx
10854                && (TARGET_SHIFT1 || optimize_size))
10855         {
10856           if (get_attr_mode (insn) == MODE_SI)
10857             return "sal{l}\t%0";
10858           else
10859             return "sal{b}\t%0";
10860         }
10861       else
10862         {
10863           if (get_attr_mode (insn) == MODE_SI)
10864             return "sal{l}\t{%2, %k0|%k0, %2}";
10865           else
10866             return "sal{b}\t{%2, %0|%0, %2}";
10867         }
10868     }
10869 }
10870   [(set (attr "type")
10871      (cond [(eq_attr "alternative" "2")
10872               (const_string "lea")
10873             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10874                           (const_int 0))
10875                       (match_operand 0 "register_operand" ""))
10876                  (match_operand 2 "const1_operand" ""))
10877               (const_string "alu")
10878            ]
10879            (const_string "ishift")))
10880    (set_attr "mode" "QI,SI,SI")])
10881
10882 (define_insn "*ashlqi3_1"
10883   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10884         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10885                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10886    (clobber (reg:CC FLAGS_REG))]
10887   "TARGET_PARTIAL_REG_STALL
10888    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10889 {
10890   switch (get_attr_type (insn))
10891     {
10892     case TYPE_ALU:
10893       if (operands[2] != const1_rtx)
10894         abort ();
10895       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10896         return "add{l}\t{%k0, %k0|%k0, %k0}";
10897       else
10898         return "add{b}\t{%0, %0|%0, %0}";
10899
10900     default:
10901       if (REG_P (operands[2]))
10902         {
10903           if (get_attr_mode (insn) == MODE_SI)
10904             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10905           else
10906             return "sal{b}\t{%b2, %0|%0, %b2}";
10907         }
10908       else if (operands[2] == const1_rtx
10909                && (TARGET_SHIFT1 || optimize_size))
10910         {
10911           if (get_attr_mode (insn) == MODE_SI)
10912             return "sal{l}\t%0";
10913           else
10914             return "sal{b}\t%0";
10915         }
10916       else
10917         {
10918           if (get_attr_mode (insn) == MODE_SI)
10919             return "sal{l}\t{%2, %k0|%k0, %2}";
10920           else
10921             return "sal{b}\t{%2, %0|%0, %2}";
10922         }
10923     }
10924 }
10925   [(set (attr "type")
10926      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10927                           (const_int 0))
10928                       (match_operand 0 "register_operand" ""))
10929                  (match_operand 2 "const1_operand" ""))
10930               (const_string "alu")
10931            ]
10932            (const_string "ishift")))
10933    (set_attr "mode" "QI,SI")])
10934
10935 ;; This pattern can't accept a variable shift count, since shifts by
10936 ;; zero don't affect the flags.  We assume that shifts by constant
10937 ;; zero are optimized away.
10938 (define_insn "*ashlqi3_cmp"
10939   [(set (reg FLAGS_REG)
10940         (compare
10941           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10942                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10943           (const_int 0)))
10944    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10945         (ashift:QI (match_dup 1) (match_dup 2)))]
10946   "ix86_match_ccmode (insn, CCGOCmode)
10947    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10948 {
10949   switch (get_attr_type (insn))
10950     {
10951     case TYPE_ALU:
10952       if (operands[2] != const1_rtx)
10953         abort ();
10954       return "add{b}\t{%0, %0|%0, %0}";
10955
10956     default:
10957       if (REG_P (operands[2]))
10958         return "sal{b}\t{%b2, %0|%0, %b2}";
10959       else if (operands[2] == const1_rtx
10960                && (TARGET_SHIFT1 || optimize_size))
10961         return "sal{b}\t%0";
10962       else
10963         return "sal{b}\t{%2, %0|%0, %2}";
10964     }
10965 }
10966   [(set (attr "type")
10967      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10968                           (const_int 0))
10969                       (match_operand 0 "register_operand" ""))
10970                  (match_operand 2 "const1_operand" ""))
10971               (const_string "alu")
10972            ]
10973            (const_string "ishift")))
10974    (set_attr "mode" "QI")])
10975
10976 ;; See comment above `ashldi3' about how this works.
10977
10978 (define_expand "ashrdi3"
10979   [(set (match_operand:DI 0 "shiftdi_operand" "")
10980         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10981                      (match_operand:QI 2 "nonmemory_operand" "")))]
10982   ""
10983   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10984
10985 (define_insn "*ashrdi3_63_rex64"
10986   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10987         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10988                      (match_operand:DI 2 "const_int_operand" "i,i")))
10989    (clobber (reg:CC FLAGS_REG))]
10990   "TARGET_64BIT && INTVAL (operands[2]) == 63
10991    && (TARGET_USE_CLTD || optimize_size)
10992    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10993   "@
10994    {cqto|cqo}
10995    sar{q}\t{%2, %0|%0, %2}"
10996   [(set_attr "type" "imovx,ishift")
10997    (set_attr "prefix_0f" "0,*")
10998    (set_attr "length_immediate" "0,*")
10999    (set_attr "modrm" "0,1")
11000    (set_attr "mode" "DI")])
11001
11002 (define_insn "*ashrdi3_1_one_bit_rex64"
11003   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11004         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11005                      (match_operand:QI 2 "const1_operand" "")))
11006    (clobber (reg:CC FLAGS_REG))]
11007   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11008    && (TARGET_SHIFT1 || optimize_size)"
11009   "sar{q}\t%0"
11010   [(set_attr "type" "ishift")
11011    (set (attr "length") 
11012      (if_then_else (match_operand:DI 0 "register_operand" "") 
11013         (const_string "2")
11014         (const_string "*")))])
11015
11016 (define_insn "*ashrdi3_1_rex64"
11017   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11018         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11019                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11020    (clobber (reg:CC FLAGS_REG))]
11021   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11022   "@
11023    sar{q}\t{%2, %0|%0, %2}
11024    sar{q}\t{%b2, %0|%0, %b2}"
11025   [(set_attr "type" "ishift")
11026    (set_attr "mode" "DI")])
11027
11028 ;; This pattern can't accept a variable shift count, since shifts by
11029 ;; zero don't affect the flags.  We assume that shifts by constant
11030 ;; zero are optimized away.
11031 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11032   [(set (reg FLAGS_REG)
11033         (compare
11034           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11035                        (match_operand:QI 2 "const1_operand" ""))
11036           (const_int 0)))
11037    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11038         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11039   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11040    && (TARGET_SHIFT1 || optimize_size)
11041    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11042   "sar{q}\t%0"
11043   [(set_attr "type" "ishift")
11044    (set (attr "length") 
11045      (if_then_else (match_operand:DI 0 "register_operand" "") 
11046         (const_string "2")
11047         (const_string "*")))])
11048
11049 ;; This pattern can't accept a variable shift count, since shifts by
11050 ;; zero don't affect the flags.  We assume that shifts by constant
11051 ;; zero are optimized away.
11052 (define_insn "*ashrdi3_cmp_rex64"
11053   [(set (reg FLAGS_REG)
11054         (compare
11055           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11056                        (match_operand:QI 2 "const_int_operand" "n"))
11057           (const_int 0)))
11058    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11059         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11060   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11061    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11062   "sar{q}\t{%2, %0|%0, %2}"
11063   [(set_attr "type" "ishift")
11064    (set_attr "mode" "DI")])
11065
11066 (define_insn "*ashrdi3_1"
11067   [(set (match_operand:DI 0 "register_operand" "=r")
11068         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11069                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11070    (clobber (reg:CC FLAGS_REG))]
11071   "!TARGET_64BIT"
11072   "#"
11073   [(set_attr "type" "multi")])
11074
11075 ;; By default we don't ask for a scratch register, because when DImode
11076 ;; values are manipulated, registers are already at a premium.  But if
11077 ;; we have one handy, we won't turn it away.
11078 (define_peephole2
11079   [(match_scratch:SI 3 "r")
11080    (parallel [(set (match_operand:DI 0 "register_operand" "")
11081                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11082                                 (match_operand:QI 2 "nonmemory_operand" "")))
11083               (clobber (reg:CC FLAGS_REG))])
11084    (match_dup 3)]
11085   "!TARGET_64BIT && TARGET_CMOVE"
11086   [(const_int 0)]
11087   "ix86_split_ashrdi (operands, operands[3]); DONE;")
11088
11089 (define_split
11090   [(set (match_operand:DI 0 "register_operand" "")
11091         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11092                      (match_operand:QI 2 "nonmemory_operand" "")))
11093    (clobber (reg:CC FLAGS_REG))]
11094   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11095   [(const_int 0)]
11096   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11097
11098 (define_insn "x86_shrd_1"
11099   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11100         (ior:SI (ashiftrt:SI (match_dup 0)
11101                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11102                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11103                   (minus:QI (const_int 32) (match_dup 2)))))
11104    (clobber (reg:CC FLAGS_REG))]
11105   ""
11106   "@
11107    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11108    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11109   [(set_attr "type" "ishift")
11110    (set_attr "prefix_0f" "1")
11111    (set_attr "pent_pair" "np")
11112    (set_attr "mode" "SI")])
11113
11114 (define_expand "x86_shift_adj_3"
11115   [(use (match_operand:SI 0 "register_operand" ""))
11116    (use (match_operand:SI 1 "register_operand" ""))
11117    (use (match_operand:QI 2 "register_operand" ""))]
11118   ""
11119 {
11120   rtx label = gen_label_rtx ();
11121   rtx tmp;
11122
11123   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11124
11125   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11126   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11127   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11128                               gen_rtx_LABEL_REF (VOIDmode, label),
11129                               pc_rtx);
11130   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11131   JUMP_LABEL (tmp) = label;
11132
11133   emit_move_insn (operands[0], operands[1]);
11134   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11135
11136   emit_label (label);
11137   LABEL_NUSES (label) = 1;
11138
11139   DONE;
11140 })
11141
11142 (define_insn "ashrsi3_31"
11143   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11144         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11145                      (match_operand:SI 2 "const_int_operand" "i,i")))
11146    (clobber (reg:CC FLAGS_REG))]
11147   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11148    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11149   "@
11150    {cltd|cdq}
11151    sar{l}\t{%2, %0|%0, %2}"
11152   [(set_attr "type" "imovx,ishift")
11153    (set_attr "prefix_0f" "0,*")
11154    (set_attr "length_immediate" "0,*")
11155    (set_attr "modrm" "0,1")
11156    (set_attr "mode" "SI")])
11157
11158 (define_insn "*ashrsi3_31_zext"
11159   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11160         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11161                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11162    (clobber (reg:CC FLAGS_REG))]
11163   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11164    && INTVAL (operands[2]) == 31
11165    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11166   "@
11167    {cltd|cdq}
11168    sar{l}\t{%2, %k0|%k0, %2}"
11169   [(set_attr "type" "imovx,ishift")
11170    (set_attr "prefix_0f" "0,*")
11171    (set_attr "length_immediate" "0,*")
11172    (set_attr "modrm" "0,1")
11173    (set_attr "mode" "SI")])
11174
11175 (define_expand "ashrsi3"
11176   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11177         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11178                      (match_operand:QI 2 "nonmemory_operand" "")))
11179    (clobber (reg:CC FLAGS_REG))]
11180   ""
11181   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11182
11183 (define_insn "*ashrsi3_1_one_bit"
11184   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11185         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11186                      (match_operand:QI 2 "const1_operand" "")))
11187    (clobber (reg:CC FLAGS_REG))]
11188   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11189    && (TARGET_SHIFT1 || optimize_size)"
11190   "sar{l}\t%0"
11191   [(set_attr "type" "ishift")
11192    (set (attr "length") 
11193      (if_then_else (match_operand:SI 0 "register_operand" "") 
11194         (const_string "2")
11195         (const_string "*")))])
11196
11197 (define_insn "*ashrsi3_1_one_bit_zext"
11198   [(set (match_operand:DI 0 "register_operand" "=r")
11199         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11200                                      (match_operand:QI 2 "const1_operand" ""))))
11201    (clobber (reg:CC FLAGS_REG))]
11202   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11203    && (TARGET_SHIFT1 || optimize_size)"
11204   "sar{l}\t%k0"
11205   [(set_attr "type" "ishift")
11206    (set_attr "length" "2")])
11207
11208 (define_insn "*ashrsi3_1"
11209   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11210         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11211                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11212    (clobber (reg:CC FLAGS_REG))]
11213   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11214   "@
11215    sar{l}\t{%2, %0|%0, %2}
11216    sar{l}\t{%b2, %0|%0, %b2}"
11217   [(set_attr "type" "ishift")
11218    (set_attr "mode" "SI")])
11219
11220 (define_insn "*ashrsi3_1_zext"
11221   [(set (match_operand:DI 0 "register_operand" "=r,r")
11222         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11223                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11224    (clobber (reg:CC FLAGS_REG))]
11225   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11226   "@
11227    sar{l}\t{%2, %k0|%k0, %2}
11228    sar{l}\t{%b2, %k0|%k0, %b2}"
11229   [(set_attr "type" "ishift")
11230    (set_attr "mode" "SI")])
11231
11232 ;; This pattern can't accept a variable shift count, since shifts by
11233 ;; zero don't affect the flags.  We assume that shifts by constant
11234 ;; zero are optimized away.
11235 (define_insn "*ashrsi3_one_bit_cmp"
11236   [(set (reg FLAGS_REG)
11237         (compare
11238           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11239                        (match_operand:QI 2 "const1_operand" ""))
11240           (const_int 0)))
11241    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11242         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11243   "ix86_match_ccmode (insn, CCGOCmode)
11244    && (TARGET_SHIFT1 || optimize_size)
11245    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11246   "sar{l}\t%0"
11247   [(set_attr "type" "ishift")
11248    (set (attr "length") 
11249      (if_then_else (match_operand:SI 0 "register_operand" "") 
11250         (const_string "2")
11251         (const_string "*")))])
11252
11253 (define_insn "*ashrsi3_one_bit_cmp_zext"
11254   [(set (reg FLAGS_REG)
11255         (compare
11256           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11257                        (match_operand:QI 2 "const1_operand" ""))
11258           (const_int 0)))
11259    (set (match_operand:DI 0 "register_operand" "=r")
11260         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11261   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11262    && (TARGET_SHIFT1 || optimize_size)
11263    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11264   "sar{l}\t%k0"
11265   [(set_attr "type" "ishift")
11266    (set_attr "length" "2")])
11267
11268 ;; This pattern can't accept a variable shift count, since shifts by
11269 ;; zero don't affect the flags.  We assume that shifts by constant
11270 ;; zero are optimized away.
11271 (define_insn "*ashrsi3_cmp"
11272   [(set (reg FLAGS_REG)
11273         (compare
11274           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11275                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11276           (const_int 0)))
11277    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11278         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11279   "ix86_match_ccmode (insn, CCGOCmode)
11280    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11281   "sar{l}\t{%2, %0|%0, %2}"
11282   [(set_attr "type" "ishift")
11283    (set_attr "mode" "SI")])
11284
11285 (define_insn "*ashrsi3_cmp_zext"
11286   [(set (reg FLAGS_REG)
11287         (compare
11288           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11289                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11290           (const_int 0)))
11291    (set (match_operand:DI 0 "register_operand" "=r")
11292         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11293   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11294    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11295   "sar{l}\t{%2, %k0|%k0, %2}"
11296   [(set_attr "type" "ishift")
11297    (set_attr "mode" "SI")])
11298
11299 (define_expand "ashrhi3"
11300   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11301         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11302                      (match_operand:QI 2 "nonmemory_operand" "")))
11303    (clobber (reg:CC FLAGS_REG))]
11304   "TARGET_HIMODE_MATH"
11305   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11306
11307 (define_insn "*ashrhi3_1_one_bit"
11308   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11309         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11310                      (match_operand:QI 2 "const1_operand" "")))
11311    (clobber (reg:CC FLAGS_REG))]
11312   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11313    && (TARGET_SHIFT1 || optimize_size)"
11314   "sar{w}\t%0"
11315   [(set_attr "type" "ishift")
11316    (set (attr "length") 
11317      (if_then_else (match_operand 0 "register_operand" "") 
11318         (const_string "2")
11319         (const_string "*")))])
11320
11321 (define_insn "*ashrhi3_1"
11322   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11323         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11324                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11325    (clobber (reg:CC FLAGS_REG))]
11326   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11327   "@
11328    sar{w}\t{%2, %0|%0, %2}
11329    sar{w}\t{%b2, %0|%0, %b2}"
11330   [(set_attr "type" "ishift")
11331    (set_attr "mode" "HI")])
11332
11333 ;; This pattern can't accept a variable shift count, since shifts by
11334 ;; zero don't affect the flags.  We assume that shifts by constant
11335 ;; zero are optimized away.
11336 (define_insn "*ashrhi3_one_bit_cmp"
11337   [(set (reg FLAGS_REG)
11338         (compare
11339           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11340                        (match_operand:QI 2 "const1_operand" ""))
11341           (const_int 0)))
11342    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11343         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11344   "ix86_match_ccmode (insn, CCGOCmode)
11345    && (TARGET_SHIFT1 || optimize_size)
11346    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11347   "sar{w}\t%0"
11348   [(set_attr "type" "ishift")
11349    (set (attr "length") 
11350      (if_then_else (match_operand 0 "register_operand" "") 
11351         (const_string "2")
11352         (const_string "*")))])
11353
11354 ;; This pattern can't accept a variable shift count, since shifts by
11355 ;; zero don't affect the flags.  We assume that shifts by constant
11356 ;; zero are optimized away.
11357 (define_insn "*ashrhi3_cmp"
11358   [(set (reg FLAGS_REG)
11359         (compare
11360           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11361                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11362           (const_int 0)))
11363    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11364         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11365   "ix86_match_ccmode (insn, CCGOCmode)
11366    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11367   "sar{w}\t{%2, %0|%0, %2}"
11368   [(set_attr "type" "ishift")
11369    (set_attr "mode" "HI")])
11370
11371 (define_expand "ashrqi3"
11372   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11373         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11374                      (match_operand:QI 2 "nonmemory_operand" "")))
11375    (clobber (reg:CC FLAGS_REG))]
11376   "TARGET_QIMODE_MATH"
11377   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11378
11379 (define_insn "*ashrqi3_1_one_bit"
11380   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11381         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11382                      (match_operand:QI 2 "const1_operand" "")))
11383    (clobber (reg:CC FLAGS_REG))]
11384   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11385    && (TARGET_SHIFT1 || optimize_size)"
11386   "sar{b}\t%0"
11387   [(set_attr "type" "ishift")
11388    (set (attr "length") 
11389      (if_then_else (match_operand 0 "register_operand" "") 
11390         (const_string "2")
11391         (const_string "*")))])
11392
11393 (define_insn "*ashrqi3_1_one_bit_slp"
11394   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11395         (ashiftrt:QI (match_dup 0)
11396                      (match_operand:QI 1 "const1_operand" "")))
11397    (clobber (reg:CC FLAGS_REG))]
11398   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11399    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11400    && (TARGET_SHIFT1 || optimize_size)"
11401   "sar{b}\t%0"
11402   [(set_attr "type" "ishift1")
11403    (set (attr "length") 
11404      (if_then_else (match_operand 0 "register_operand" "") 
11405         (const_string "2")
11406         (const_string "*")))])
11407
11408 (define_insn "*ashrqi3_1"
11409   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11410         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11411                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11412    (clobber (reg:CC FLAGS_REG))]
11413   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11414   "@
11415    sar{b}\t{%2, %0|%0, %2}
11416    sar{b}\t{%b2, %0|%0, %b2}"
11417   [(set_attr "type" "ishift")
11418    (set_attr "mode" "QI")])
11419
11420 (define_insn "*ashrqi3_1_slp"
11421   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11422         (ashiftrt:QI (match_dup 0)
11423                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11424    (clobber (reg:CC FLAGS_REG))]
11425   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11426    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11427   "@
11428    sar{b}\t{%1, %0|%0, %1}
11429    sar{b}\t{%b1, %0|%0, %b1}"
11430   [(set_attr "type" "ishift1")
11431    (set_attr "mode" "QI")])
11432
11433 ;; This pattern can't accept a variable shift count, since shifts by
11434 ;; zero don't affect the flags.  We assume that shifts by constant
11435 ;; zero are optimized away.
11436 (define_insn "*ashrqi3_one_bit_cmp"
11437   [(set (reg FLAGS_REG)
11438         (compare
11439           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11440                        (match_operand:QI 2 "const1_operand" "I"))
11441           (const_int 0)))
11442    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11443         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11444   "ix86_match_ccmode (insn, CCGOCmode)
11445    && (TARGET_SHIFT1 || optimize_size)
11446    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11447   "sar{b}\t%0"
11448   [(set_attr "type" "ishift")
11449    (set (attr "length") 
11450      (if_then_else (match_operand 0 "register_operand" "") 
11451         (const_string "2")
11452         (const_string "*")))])
11453
11454 ;; This pattern can't accept a variable shift count, since shifts by
11455 ;; zero don't affect the flags.  We assume that shifts by constant
11456 ;; zero are optimized away.
11457 (define_insn "*ashrqi3_cmp"
11458   [(set (reg FLAGS_REG)
11459         (compare
11460           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11461                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11462           (const_int 0)))
11463    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11464         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11465   "ix86_match_ccmode (insn, CCGOCmode)
11466    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11467   "sar{b}\t{%2, %0|%0, %2}"
11468   [(set_attr "type" "ishift")
11469    (set_attr "mode" "QI")])
11470 \f
11471 ;; Logical shift instructions
11472
11473 ;; See comment above `ashldi3' about how this works.
11474
11475 (define_expand "lshrdi3"
11476   [(set (match_operand:DI 0 "shiftdi_operand" "")
11477         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11478                      (match_operand:QI 2 "nonmemory_operand" "")))]
11479   ""
11480   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11481
11482 (define_insn "*lshrdi3_1_one_bit_rex64"
11483   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11484         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11485                      (match_operand:QI 2 "const1_operand" "")))
11486    (clobber (reg:CC FLAGS_REG))]
11487   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11488    && (TARGET_SHIFT1 || optimize_size)"
11489   "shr{q}\t%0"
11490   [(set_attr "type" "ishift")
11491    (set (attr "length") 
11492      (if_then_else (match_operand:DI 0 "register_operand" "") 
11493         (const_string "2")
11494         (const_string "*")))])
11495
11496 (define_insn "*lshrdi3_1_rex64"
11497   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11498         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11499                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11500    (clobber (reg:CC FLAGS_REG))]
11501   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11502   "@
11503    shr{q}\t{%2, %0|%0, %2}
11504    shr{q}\t{%b2, %0|%0, %b2}"
11505   [(set_attr "type" "ishift")
11506    (set_attr "mode" "DI")])
11507
11508 ;; This pattern can't accept a variable shift count, since shifts by
11509 ;; zero don't affect the flags.  We assume that shifts by constant
11510 ;; zero are optimized away.
11511 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11512   [(set (reg FLAGS_REG)
11513         (compare
11514           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11515                        (match_operand:QI 2 "const1_operand" ""))
11516           (const_int 0)))
11517    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11518         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11519   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11520    && (TARGET_SHIFT1 || optimize_size)
11521    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11522   "shr{q}\t%0"
11523   [(set_attr "type" "ishift")
11524    (set (attr "length") 
11525      (if_then_else (match_operand:DI 0 "register_operand" "") 
11526         (const_string "2")
11527         (const_string "*")))])
11528
11529 ;; This pattern can't accept a variable shift count, since shifts by
11530 ;; zero don't affect the flags.  We assume that shifts by constant
11531 ;; zero are optimized away.
11532 (define_insn "*lshrdi3_cmp_rex64"
11533   [(set (reg FLAGS_REG)
11534         (compare
11535           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11536                        (match_operand:QI 2 "const_int_operand" "e"))
11537           (const_int 0)))
11538    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11539         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11540   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11541    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11542   "shr{q}\t{%2, %0|%0, %2}"
11543   [(set_attr "type" "ishift")
11544    (set_attr "mode" "DI")])
11545
11546 (define_insn "*lshrdi3_1"
11547   [(set (match_operand:DI 0 "register_operand" "=r")
11548         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11549                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11550    (clobber (reg:CC FLAGS_REG))]
11551   "!TARGET_64BIT"
11552   "#"
11553   [(set_attr "type" "multi")])
11554
11555 ;; By default we don't ask for a scratch register, because when DImode
11556 ;; values are manipulated, registers are already at a premium.  But if
11557 ;; we have one handy, we won't turn it away.
11558 (define_peephole2
11559   [(match_scratch:SI 3 "r")
11560    (parallel [(set (match_operand:DI 0 "register_operand" "")
11561                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11562                                 (match_operand:QI 2 "nonmemory_operand" "")))
11563               (clobber (reg:CC FLAGS_REG))])
11564    (match_dup 3)]
11565   "!TARGET_64BIT && TARGET_CMOVE"
11566   [(const_int 0)]
11567   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11568
11569 (define_split 
11570   [(set (match_operand:DI 0 "register_operand" "")
11571         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11572                      (match_operand:QI 2 "nonmemory_operand" "")))
11573    (clobber (reg:CC FLAGS_REG))]
11574   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11575   [(const_int 0)]
11576   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11577
11578 (define_expand "lshrsi3"
11579   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11580         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11581                      (match_operand:QI 2 "nonmemory_operand" "")))
11582    (clobber (reg:CC FLAGS_REG))]
11583   ""
11584   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11585
11586 (define_insn "*lshrsi3_1_one_bit"
11587   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11588         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11589                      (match_operand:QI 2 "const1_operand" "")))
11590    (clobber (reg:CC FLAGS_REG))]
11591   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11592    && (TARGET_SHIFT1 || optimize_size)"
11593   "shr{l}\t%0"
11594   [(set_attr "type" "ishift")
11595    (set (attr "length") 
11596      (if_then_else (match_operand:SI 0 "register_operand" "") 
11597         (const_string "2")
11598         (const_string "*")))])
11599
11600 (define_insn "*lshrsi3_1_one_bit_zext"
11601   [(set (match_operand:DI 0 "register_operand" "=r")
11602         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11603                      (match_operand:QI 2 "const1_operand" "")))
11604    (clobber (reg:CC FLAGS_REG))]
11605   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11606    && (TARGET_SHIFT1 || optimize_size)"
11607   "shr{l}\t%k0"
11608   [(set_attr "type" "ishift")
11609    (set_attr "length" "2")])
11610
11611 (define_insn "*lshrsi3_1"
11612   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11613         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11614                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11615    (clobber (reg:CC FLAGS_REG))]
11616   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11617   "@
11618    shr{l}\t{%2, %0|%0, %2}
11619    shr{l}\t{%b2, %0|%0, %b2}"
11620   [(set_attr "type" "ishift")
11621    (set_attr "mode" "SI")])
11622
11623 (define_insn "*lshrsi3_1_zext"
11624   [(set (match_operand:DI 0 "register_operand" "=r,r")
11625         (zero_extend:DI
11626           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11627                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11628    (clobber (reg:CC FLAGS_REG))]
11629   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11630   "@
11631    shr{l}\t{%2, %k0|%k0, %2}
11632    shr{l}\t{%b2, %k0|%k0, %b2}"
11633   [(set_attr "type" "ishift")
11634    (set_attr "mode" "SI")])
11635
11636 ;; This pattern can't accept a variable shift count, since shifts by
11637 ;; zero don't affect the flags.  We assume that shifts by constant
11638 ;; zero are optimized away.
11639 (define_insn "*lshrsi3_one_bit_cmp"
11640   [(set (reg FLAGS_REG)
11641         (compare
11642           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11643                        (match_operand:QI 2 "const1_operand" ""))
11644           (const_int 0)))
11645    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11646         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11647   "ix86_match_ccmode (insn, CCGOCmode)
11648    && (TARGET_SHIFT1 || optimize_size)
11649    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11650   "shr{l}\t%0"
11651   [(set_attr "type" "ishift")
11652    (set (attr "length") 
11653      (if_then_else (match_operand:SI 0 "register_operand" "") 
11654         (const_string "2")
11655         (const_string "*")))])
11656
11657 (define_insn "*lshrsi3_cmp_one_bit_zext"
11658   [(set (reg FLAGS_REG)
11659         (compare
11660           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11661                        (match_operand:QI 2 "const1_operand" ""))
11662           (const_int 0)))
11663    (set (match_operand:DI 0 "register_operand" "=r")
11664         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11665   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11666    && (TARGET_SHIFT1 || optimize_size)
11667    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11668   "shr{l}\t%k0"
11669   [(set_attr "type" "ishift")
11670    (set_attr "length" "2")])
11671
11672 ;; This pattern can't accept a variable shift count, since shifts by
11673 ;; zero don't affect the flags.  We assume that shifts by constant
11674 ;; zero are optimized away.
11675 (define_insn "*lshrsi3_cmp"
11676   [(set (reg FLAGS_REG)
11677         (compare
11678           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11679                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11680           (const_int 0)))
11681    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11682         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11683   "ix86_match_ccmode (insn, CCGOCmode)
11684    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11685   "shr{l}\t{%2, %0|%0, %2}"
11686   [(set_attr "type" "ishift")
11687    (set_attr "mode" "SI")])
11688
11689 (define_insn "*lshrsi3_cmp_zext"
11690   [(set (reg FLAGS_REG)
11691         (compare
11692           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11693                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11694           (const_int 0)))
11695    (set (match_operand:DI 0 "register_operand" "=r")
11696         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11697   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11698    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11699   "shr{l}\t{%2, %k0|%k0, %2}"
11700   [(set_attr "type" "ishift")
11701    (set_attr "mode" "SI")])
11702
11703 (define_expand "lshrhi3"
11704   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11705         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11706                      (match_operand:QI 2 "nonmemory_operand" "")))
11707    (clobber (reg:CC FLAGS_REG))]
11708   "TARGET_HIMODE_MATH"
11709   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11710
11711 (define_insn "*lshrhi3_1_one_bit"
11712   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11713         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11714                      (match_operand:QI 2 "const1_operand" "")))
11715    (clobber (reg:CC FLAGS_REG))]
11716   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11717    && (TARGET_SHIFT1 || optimize_size)"
11718   "shr{w}\t%0"
11719   [(set_attr "type" "ishift")
11720    (set (attr "length") 
11721      (if_then_else (match_operand 0 "register_operand" "") 
11722         (const_string "2")
11723         (const_string "*")))])
11724
11725 (define_insn "*lshrhi3_1"
11726   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11727         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11728                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11729    (clobber (reg:CC FLAGS_REG))]
11730   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11731   "@
11732    shr{w}\t{%2, %0|%0, %2}
11733    shr{w}\t{%b2, %0|%0, %b2}"
11734   [(set_attr "type" "ishift")
11735    (set_attr "mode" "HI")])
11736
11737 ;; This pattern can't accept a variable shift count, since shifts by
11738 ;; zero don't affect the flags.  We assume that shifts by constant
11739 ;; zero are optimized away.
11740 (define_insn "*lshrhi3_one_bit_cmp"
11741   [(set (reg FLAGS_REG)
11742         (compare
11743           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11744                        (match_operand:QI 2 "const1_operand" ""))
11745           (const_int 0)))
11746    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11747         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11748   "ix86_match_ccmode (insn, CCGOCmode)
11749    && (TARGET_SHIFT1 || optimize_size)
11750    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11751   "shr{w}\t%0"
11752   [(set_attr "type" "ishift")
11753    (set (attr "length") 
11754      (if_then_else (match_operand:SI 0 "register_operand" "") 
11755         (const_string "2")
11756         (const_string "*")))])
11757
11758 ;; This pattern can't accept a variable shift count, since shifts by
11759 ;; zero don't affect the flags.  We assume that shifts by constant
11760 ;; zero are optimized away.
11761 (define_insn "*lshrhi3_cmp"
11762   [(set (reg FLAGS_REG)
11763         (compare
11764           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11765                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11766           (const_int 0)))
11767    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11768         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11769   "ix86_match_ccmode (insn, CCGOCmode)
11770    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11771   "shr{w}\t{%2, %0|%0, %2}"
11772   [(set_attr "type" "ishift")
11773    (set_attr "mode" "HI")])
11774
11775 (define_expand "lshrqi3"
11776   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11777         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11778                      (match_operand:QI 2 "nonmemory_operand" "")))
11779    (clobber (reg:CC FLAGS_REG))]
11780   "TARGET_QIMODE_MATH"
11781   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11782
11783 (define_insn "*lshrqi3_1_one_bit"
11784   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11785         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11786                      (match_operand:QI 2 "const1_operand" "")))
11787    (clobber (reg:CC FLAGS_REG))]
11788   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11789    && (TARGET_SHIFT1 || optimize_size)"
11790   "shr{b}\t%0"
11791   [(set_attr "type" "ishift")
11792    (set (attr "length") 
11793      (if_then_else (match_operand 0 "register_operand" "") 
11794         (const_string "2")
11795         (const_string "*")))])
11796
11797 (define_insn "*lshrqi3_1_one_bit_slp"
11798   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11799         (lshiftrt:QI (match_dup 0)
11800                      (match_operand:QI 1 "const1_operand" "")))
11801    (clobber (reg:CC FLAGS_REG))]
11802   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11803    && (TARGET_SHIFT1 || optimize_size)"
11804   "shr{b}\t%0"
11805   [(set_attr "type" "ishift1")
11806    (set (attr "length") 
11807      (if_then_else (match_operand 0 "register_operand" "") 
11808         (const_string "2")
11809         (const_string "*")))])
11810
11811 (define_insn "*lshrqi3_1"
11812   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11813         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11814                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11815    (clobber (reg:CC FLAGS_REG))]
11816   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11817   "@
11818    shr{b}\t{%2, %0|%0, %2}
11819    shr{b}\t{%b2, %0|%0, %b2}"
11820   [(set_attr "type" "ishift")
11821    (set_attr "mode" "QI")])
11822
11823 (define_insn "*lshrqi3_1_slp"
11824   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11825         (lshiftrt:QI (match_dup 0)
11826                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11827    (clobber (reg:CC FLAGS_REG))]
11828   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11829    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11830   "@
11831    shr{b}\t{%1, %0|%0, %1}
11832    shr{b}\t{%b1, %0|%0, %b1}"
11833   [(set_attr "type" "ishift1")
11834    (set_attr "mode" "QI")])
11835
11836 ;; This pattern can't accept a variable shift count, since shifts by
11837 ;; zero don't affect the flags.  We assume that shifts by constant
11838 ;; zero are optimized away.
11839 (define_insn "*lshrqi2_one_bit_cmp"
11840   [(set (reg FLAGS_REG)
11841         (compare
11842           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11843                        (match_operand:QI 2 "const1_operand" ""))
11844           (const_int 0)))
11845    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11846         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11847   "ix86_match_ccmode (insn, CCGOCmode)
11848    && (TARGET_SHIFT1 || optimize_size)
11849    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11850   "shr{b}\t%0"
11851   [(set_attr "type" "ishift")
11852    (set (attr "length") 
11853      (if_then_else (match_operand:SI 0 "register_operand" "") 
11854         (const_string "2")
11855         (const_string "*")))])
11856
11857 ;; This pattern can't accept a variable shift count, since shifts by
11858 ;; zero don't affect the flags.  We assume that shifts by constant
11859 ;; zero are optimized away.
11860 (define_insn "*lshrqi2_cmp"
11861   [(set (reg FLAGS_REG)
11862         (compare
11863           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11864                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11865           (const_int 0)))
11866    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11867         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11868   "ix86_match_ccmode (insn, CCGOCmode)
11869    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11870   "shr{b}\t{%2, %0|%0, %2}"
11871   [(set_attr "type" "ishift")
11872    (set_attr "mode" "QI")])
11873 \f
11874 ;; Rotate instructions
11875
11876 (define_expand "rotldi3"
11877   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11878         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11879                    (match_operand:QI 2 "nonmemory_operand" "")))
11880    (clobber (reg:CC FLAGS_REG))]
11881   "TARGET_64BIT"
11882   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11883
11884 (define_insn "*rotlsi3_1_one_bit_rex64"
11885   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11886         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11887                    (match_operand:QI 2 "const1_operand" "")))
11888    (clobber (reg:CC FLAGS_REG))]
11889   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11890    && (TARGET_SHIFT1 || optimize_size)"
11891   "rol{q}\t%0"
11892   [(set_attr "type" "rotate")
11893    (set (attr "length") 
11894      (if_then_else (match_operand:DI 0 "register_operand" "") 
11895         (const_string "2")
11896         (const_string "*")))])
11897
11898 (define_insn "*rotldi3_1_rex64"
11899   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11900         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11901                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11902    (clobber (reg:CC FLAGS_REG))]
11903   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11904   "@
11905    rol{q}\t{%2, %0|%0, %2}
11906    rol{q}\t{%b2, %0|%0, %b2}"
11907   [(set_attr "type" "rotate")
11908    (set_attr "mode" "DI")])
11909
11910 (define_expand "rotlsi3"
11911   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11912         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11913                    (match_operand:QI 2 "nonmemory_operand" "")))
11914    (clobber (reg:CC FLAGS_REG))]
11915   ""
11916   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11917
11918 (define_insn "*rotlsi3_1_one_bit"
11919   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11920         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11921                    (match_operand:QI 2 "const1_operand" "")))
11922    (clobber (reg:CC FLAGS_REG))]
11923   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11924    && (TARGET_SHIFT1 || optimize_size)"
11925   "rol{l}\t%0"
11926   [(set_attr "type" "rotate")
11927    (set (attr "length") 
11928      (if_then_else (match_operand:SI 0 "register_operand" "") 
11929         (const_string "2")
11930         (const_string "*")))])
11931
11932 (define_insn "*rotlsi3_1_one_bit_zext"
11933   [(set (match_operand:DI 0 "register_operand" "=r")
11934         (zero_extend:DI
11935           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11936                      (match_operand:QI 2 "const1_operand" ""))))
11937    (clobber (reg:CC FLAGS_REG))]
11938   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11939    && (TARGET_SHIFT1 || optimize_size)"
11940   "rol{l}\t%k0"
11941   [(set_attr "type" "rotate")
11942    (set_attr "length" "2")])
11943
11944 (define_insn "*rotlsi3_1"
11945   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11946         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11947                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11948    (clobber (reg:CC FLAGS_REG))]
11949   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11950   "@
11951    rol{l}\t{%2, %0|%0, %2}
11952    rol{l}\t{%b2, %0|%0, %b2}"
11953   [(set_attr "type" "rotate")
11954    (set_attr "mode" "SI")])
11955
11956 (define_insn "*rotlsi3_1_zext"
11957   [(set (match_operand:DI 0 "register_operand" "=r,r")
11958         (zero_extend:DI
11959           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11960                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11961    (clobber (reg:CC FLAGS_REG))]
11962   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11963   "@
11964    rol{l}\t{%2, %k0|%k0, %2}
11965    rol{l}\t{%b2, %k0|%k0, %b2}"
11966   [(set_attr "type" "rotate")
11967    (set_attr "mode" "SI")])
11968
11969 (define_expand "rotlhi3"
11970   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11971         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11972                    (match_operand:QI 2 "nonmemory_operand" "")))
11973    (clobber (reg:CC FLAGS_REG))]
11974   "TARGET_HIMODE_MATH"
11975   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11976
11977 (define_insn "*rotlhi3_1_one_bit"
11978   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11979         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11980                    (match_operand:QI 2 "const1_operand" "")))
11981    (clobber (reg:CC FLAGS_REG))]
11982   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11983    && (TARGET_SHIFT1 || optimize_size)"
11984   "rol{w}\t%0"
11985   [(set_attr "type" "rotate")
11986    (set (attr "length") 
11987      (if_then_else (match_operand 0 "register_operand" "") 
11988         (const_string "2")
11989         (const_string "*")))])
11990
11991 (define_insn "*rotlhi3_1"
11992   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11993         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11994                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11995    (clobber (reg:CC FLAGS_REG))]
11996   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11997   "@
11998    rol{w}\t{%2, %0|%0, %2}
11999    rol{w}\t{%b2, %0|%0, %b2}"
12000   [(set_attr "type" "rotate")
12001    (set_attr "mode" "HI")])
12002
12003 (define_expand "rotlqi3"
12004   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12005         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12006                    (match_operand:QI 2 "nonmemory_operand" "")))
12007    (clobber (reg:CC FLAGS_REG))]
12008   "TARGET_QIMODE_MATH"
12009   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12010
12011 (define_insn "*rotlqi3_1_one_bit_slp"
12012   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12013         (rotate:QI (match_dup 0)
12014                    (match_operand:QI 1 "const1_operand" "")))
12015    (clobber (reg:CC FLAGS_REG))]
12016   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12017    && (TARGET_SHIFT1 || optimize_size)"
12018   "rol{b}\t%0"
12019   [(set_attr "type" "rotate1")
12020    (set (attr "length") 
12021      (if_then_else (match_operand 0 "register_operand" "") 
12022         (const_string "2")
12023         (const_string "*")))])
12024
12025 (define_insn "*rotlqi3_1_one_bit"
12026   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12027         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12028                    (match_operand:QI 2 "const1_operand" "")))
12029    (clobber (reg:CC FLAGS_REG))]
12030   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12031    && (TARGET_SHIFT1 || optimize_size)"
12032   "rol{b}\t%0"
12033   [(set_attr "type" "rotate")
12034    (set (attr "length") 
12035      (if_then_else (match_operand 0 "register_operand" "") 
12036         (const_string "2")
12037         (const_string "*")))])
12038
12039 (define_insn "*rotlqi3_1_slp"
12040   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12041         (rotate:QI (match_dup 0)
12042                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12043    (clobber (reg:CC FLAGS_REG))]
12044   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12045    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12046   "@
12047    rol{b}\t{%1, %0|%0, %1}
12048    rol{b}\t{%b1, %0|%0, %b1}"
12049   [(set_attr "type" "rotate1")
12050    (set_attr "mode" "QI")])
12051
12052 (define_insn "*rotlqi3_1"
12053   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12054         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12055                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12056    (clobber (reg:CC FLAGS_REG))]
12057   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12058   "@
12059    rol{b}\t{%2, %0|%0, %2}
12060    rol{b}\t{%b2, %0|%0, %b2}"
12061   [(set_attr "type" "rotate")
12062    (set_attr "mode" "QI")])
12063
12064 (define_expand "rotrdi3"
12065   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12066         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12067                      (match_operand:QI 2 "nonmemory_operand" "")))
12068    (clobber (reg:CC FLAGS_REG))]
12069   "TARGET_64BIT"
12070   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12071
12072 (define_insn "*rotrdi3_1_one_bit_rex64"
12073   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12074         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12075                      (match_operand:QI 2 "const1_operand" "")))
12076    (clobber (reg:CC FLAGS_REG))]
12077   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12078    && (TARGET_SHIFT1 || optimize_size)"
12079   "ror{q}\t%0"
12080   [(set_attr "type" "rotate")
12081    (set (attr "length") 
12082      (if_then_else (match_operand:DI 0 "register_operand" "") 
12083         (const_string "2")
12084         (const_string "*")))])
12085
12086 (define_insn "*rotrdi3_1_rex64"
12087   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12088         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12089                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12090    (clobber (reg:CC FLAGS_REG))]
12091   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12092   "@
12093    ror{q}\t{%2, %0|%0, %2}
12094    ror{q}\t{%b2, %0|%0, %b2}"
12095   [(set_attr "type" "rotate")
12096    (set_attr "mode" "DI")])
12097
12098 (define_expand "rotrsi3"
12099   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12100         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12101                      (match_operand:QI 2 "nonmemory_operand" "")))
12102    (clobber (reg:CC FLAGS_REG))]
12103   ""
12104   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12105
12106 (define_insn "*rotrsi3_1_one_bit"
12107   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12108         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12109                      (match_operand:QI 2 "const1_operand" "")))
12110    (clobber (reg:CC FLAGS_REG))]
12111   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12112    && (TARGET_SHIFT1 || optimize_size)"
12113   "ror{l}\t%0"
12114   [(set_attr "type" "rotate")
12115    (set (attr "length") 
12116      (if_then_else (match_operand:SI 0 "register_operand" "") 
12117         (const_string "2")
12118         (const_string "*")))])
12119
12120 (define_insn "*rotrsi3_1_one_bit_zext"
12121   [(set (match_operand:DI 0 "register_operand" "=r")
12122         (zero_extend:DI
12123           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12124                        (match_operand:QI 2 "const1_operand" ""))))
12125    (clobber (reg:CC FLAGS_REG))]
12126   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12127    && (TARGET_SHIFT1 || optimize_size)"
12128   "ror{l}\t%k0"
12129   [(set_attr "type" "rotate")
12130    (set (attr "length") 
12131      (if_then_else (match_operand:SI 0 "register_operand" "") 
12132         (const_string "2")
12133         (const_string "*")))])
12134
12135 (define_insn "*rotrsi3_1"
12136   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12137         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12138                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12139    (clobber (reg:CC FLAGS_REG))]
12140   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12141   "@
12142    ror{l}\t{%2, %0|%0, %2}
12143    ror{l}\t{%b2, %0|%0, %b2}"
12144   [(set_attr "type" "rotate")
12145    (set_attr "mode" "SI")])
12146
12147 (define_insn "*rotrsi3_1_zext"
12148   [(set (match_operand:DI 0 "register_operand" "=r,r")
12149         (zero_extend:DI
12150           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12151                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12152    (clobber (reg:CC FLAGS_REG))]
12153   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12154   "@
12155    ror{l}\t{%2, %k0|%k0, %2}
12156    ror{l}\t{%b2, %k0|%k0, %b2}"
12157   [(set_attr "type" "rotate")
12158    (set_attr "mode" "SI")])
12159
12160 (define_expand "rotrhi3"
12161   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12162         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12163                      (match_operand:QI 2 "nonmemory_operand" "")))
12164    (clobber (reg:CC FLAGS_REG))]
12165   "TARGET_HIMODE_MATH"
12166   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12167
12168 (define_insn "*rotrhi3_one_bit"
12169   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12170         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12171                      (match_operand:QI 2 "const1_operand" "")))
12172    (clobber (reg:CC FLAGS_REG))]
12173   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12174    && (TARGET_SHIFT1 || optimize_size)"
12175   "ror{w}\t%0"
12176   [(set_attr "type" "rotate")
12177    (set (attr "length") 
12178      (if_then_else (match_operand 0 "register_operand" "") 
12179         (const_string "2")
12180         (const_string "*")))])
12181
12182 (define_insn "*rotrhi3"
12183   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12184         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12185                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12186    (clobber (reg:CC FLAGS_REG))]
12187   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12188   "@
12189    ror{w}\t{%2, %0|%0, %2}
12190    ror{w}\t{%b2, %0|%0, %b2}"
12191   [(set_attr "type" "rotate")
12192    (set_attr "mode" "HI")])
12193
12194 (define_expand "rotrqi3"
12195   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12196         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12197                      (match_operand:QI 2 "nonmemory_operand" "")))
12198    (clobber (reg:CC FLAGS_REG))]
12199   "TARGET_QIMODE_MATH"
12200   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12201
12202 (define_insn "*rotrqi3_1_one_bit"
12203   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12204         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12205                      (match_operand:QI 2 "const1_operand" "")))
12206    (clobber (reg:CC FLAGS_REG))]
12207   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12208    && (TARGET_SHIFT1 || optimize_size)"
12209   "ror{b}\t%0"
12210   [(set_attr "type" "rotate")
12211    (set (attr "length") 
12212      (if_then_else (match_operand 0 "register_operand" "") 
12213         (const_string "2")
12214         (const_string "*")))])
12215
12216 (define_insn "*rotrqi3_1_one_bit_slp"
12217   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12218         (rotatert:QI (match_dup 0)
12219                      (match_operand:QI 1 "const1_operand" "")))
12220    (clobber (reg:CC FLAGS_REG))]
12221   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12222    && (TARGET_SHIFT1 || optimize_size)"
12223   "ror{b}\t%0"
12224   [(set_attr "type" "rotate1")
12225    (set (attr "length") 
12226      (if_then_else (match_operand 0 "register_operand" "") 
12227         (const_string "2")
12228         (const_string "*")))])
12229
12230 (define_insn "*rotrqi3_1"
12231   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12232         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12233                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12234    (clobber (reg:CC FLAGS_REG))]
12235   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12236   "@
12237    ror{b}\t{%2, %0|%0, %2}
12238    ror{b}\t{%b2, %0|%0, %b2}"
12239   [(set_attr "type" "rotate")
12240    (set_attr "mode" "QI")])
12241
12242 (define_insn "*rotrqi3_1_slp"
12243   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12244         (rotatert:QI (match_dup 0)
12245                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12246    (clobber (reg:CC FLAGS_REG))]
12247   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12248    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12249   "@
12250    ror{b}\t{%1, %0|%0, %1}
12251    ror{b}\t{%b1, %0|%0, %b1}"
12252   [(set_attr "type" "rotate1")
12253    (set_attr "mode" "QI")])
12254 \f
12255 ;; Bit set / bit test instructions
12256
12257 (define_expand "extv"
12258   [(set (match_operand:SI 0 "register_operand" "")
12259         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12260                          (match_operand:SI 2 "immediate_operand" "")
12261                          (match_operand:SI 3 "immediate_operand" "")))]
12262   ""
12263 {
12264   /* Handle extractions from %ah et al.  */
12265   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12266     FAIL;
12267
12268   /* From mips.md: extract_bit_field doesn't verify that our source
12269      matches the predicate, so check it again here.  */
12270   if (! ext_register_operand (operands[1], VOIDmode))
12271     FAIL;
12272 })
12273
12274 (define_expand "extzv"
12275   [(set (match_operand:SI 0 "register_operand" "")
12276         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12277                          (match_operand:SI 2 "immediate_operand" "")
12278                          (match_operand:SI 3 "immediate_operand" "")))]
12279   ""
12280 {
12281   /* Handle extractions from %ah et al.  */
12282   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12283     FAIL;
12284
12285   /* From mips.md: extract_bit_field doesn't verify that our source
12286      matches the predicate, so check it again here.  */
12287   if (! ext_register_operand (operands[1], VOIDmode))
12288     FAIL;
12289 })
12290
12291 (define_expand "insv"
12292   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12293                       (match_operand 1 "immediate_operand" "")
12294                       (match_operand 2 "immediate_operand" ""))
12295         (match_operand 3 "register_operand" ""))]
12296   ""
12297 {
12298   /* Handle extractions from %ah et al.  */
12299   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12300     FAIL;
12301
12302   /* From mips.md: insert_bit_field doesn't verify that our source
12303      matches the predicate, so check it again here.  */
12304   if (! ext_register_operand (operands[0], VOIDmode))
12305     FAIL;
12306
12307   if (TARGET_64BIT)
12308     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12309   else
12310     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12311
12312   DONE;
12313 })
12314
12315 ;; %%% bts, btr, btc, bt.
12316 ;; In general these instructions are *slow* when applied to memory,
12317 ;; since they enforce atomic operation.  When applied to registers,
12318 ;; it depends on the cpu implementation.  They're never faster than
12319 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12320 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12321 ;; within the instruction itself, so operating on bits in the high
12322 ;; 32-bits of a register becomes easier.
12323 ;;
12324 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12325 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12326 ;; negdf respectively, so they can never be disabled entirely.
12327
12328 (define_insn "*btsq"
12329   [(set (zero_extract:DI (match_operand 0 "register_operand" "+r")
12330                          (const_int 1)
12331                          (match_operand 1 "const_0_to_63_operand" ""))
12332         (const_int 1))
12333    (clobber (reg:CC FLAGS_REG))]
12334   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12335   "bts{q} %1,%0"
12336   [(set_attr "type" "alu1")])
12337
12338 (define_insn "*btrq"
12339   [(set (zero_extract:DI (match_operand 0 "register_operand" "+r")
12340                          (const_int 1)
12341                          (match_operand 1 "const_0_to_63_operand" ""))
12342         (const_int 0))
12343    (clobber (reg:CC FLAGS_REG))]
12344   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12345   "btr{q} %1,%0"
12346   [(set_attr "type" "alu1")])
12347
12348 (define_insn "*btcq"
12349   [(set (zero_extract:DI (match_operand 0 "register_operand" "+r")
12350                          (const_int 1)
12351                          (match_operand 1 "const_0_to_63_operand" ""))
12352         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12353    (clobber (reg:CC FLAGS_REG))]
12354   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12355   "btc{q} %1,%0"
12356   [(set_attr "type" "alu1")])
12357
12358 ;; Allow Nocona to avoid these instructions if a register is available.
12359
12360 (define_peephole2
12361   [(match_scratch:DI 2 "r")
12362    (parallel [(set (zero_extract:DI
12363                      (match_operand 0 "register_operand" "")
12364                      (const_int 1)
12365                      (match_operand 1 "const_0_to_63_operand" ""))
12366                    (const_int 1))
12367               (clobber (reg:CC FLAGS_REG))])]
12368   "TARGET_64BIT && !TARGET_USE_BT"
12369   [(const_int 0)]
12370 {
12371   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12372   rtx op1;
12373
12374   if (HOST_BITS_PER_WIDE_INT >= 64)
12375     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12376   else if (i < HOST_BITS_PER_WIDE_INT)
12377     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12378   else
12379     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12380
12381   op1 = immed_double_const (lo, hi, DImode);
12382   if (i >= 31)
12383     {
12384       emit_move_insn (operands[2], op1);
12385       op1 = operands[2];
12386     }
12387
12388   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12389   DONE;
12390 })
12391
12392 (define_peephole2
12393   [(match_scratch:DI 2 "r")
12394    (parallel [(set (zero_extract:DI
12395                      (match_operand 0 "register_operand" "")
12396                      (const_int 1)
12397                      (match_operand 1 "const_0_to_63_operand" ""))
12398                    (const_int 0))
12399               (clobber (reg:CC FLAGS_REG))])]
12400   "TARGET_64BIT && !TARGET_USE_BT"
12401   [(const_int 0)]
12402 {
12403   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12404   rtx op1;
12405
12406   if (HOST_BITS_PER_WIDE_INT >= 64)
12407     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12408   else if (i < HOST_BITS_PER_WIDE_INT)
12409     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12410   else
12411     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12412
12413   op1 = immed_double_const (~lo, ~hi, DImode);
12414   if (i >= 32)
12415     {
12416       emit_move_insn (operands[2], op1);
12417       op1 = operands[2];
12418     }
12419
12420   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12421   DONE;
12422 })
12423
12424 (define_peephole2
12425   [(match_scratch:DI 2 "r")
12426    (parallel [(set (zero_extract:DI
12427                      (match_operand 0 "register_operand" "")
12428                      (const_int 1)
12429                      (match_operand 1 "const_0_to_63_operand" ""))
12430               (not:DI (zero_extract:DI
12431                         (match_dup 0) (const_int 1) (match_dup 1))))
12432               (clobber (reg:CC FLAGS_REG))])]
12433   "TARGET_64BIT && !TARGET_USE_BT"
12434   [(const_int 0)]
12435 {
12436   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12437   rtx op1;
12438
12439   if (HOST_BITS_PER_WIDE_INT >= 64)
12440     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12441   else if (i < HOST_BITS_PER_WIDE_INT)
12442     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12443   else
12444     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12445
12446   op1 = immed_double_const (lo, hi, DImode);
12447   if (i >= 31)
12448     {
12449       emit_move_insn (operands[2], op1);
12450       op1 = operands[2];
12451     }
12452
12453   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12454   DONE;
12455 })
12456 \f
12457 ;; Store-flag instructions.
12458
12459 ;; For all sCOND expanders, also expand the compare or test insn that
12460 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12461
12462 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12463 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12464 ;; way, which can later delete the movzx if only QImode is needed.
12465
12466 (define_expand "seq"
12467   [(set (match_operand:QI 0 "register_operand" "")
12468         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12469   ""
12470   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12471
12472 (define_expand "sne"
12473   [(set (match_operand:QI 0 "register_operand" "")
12474         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12475   ""
12476   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12477
12478 (define_expand "sgt"
12479   [(set (match_operand:QI 0 "register_operand" "")
12480         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12481   ""
12482   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12483
12484 (define_expand "sgtu"
12485   [(set (match_operand:QI 0 "register_operand" "")
12486         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12487   ""
12488   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12489
12490 (define_expand "slt"
12491   [(set (match_operand:QI 0 "register_operand" "")
12492         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12493   ""
12494   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12495
12496 (define_expand "sltu"
12497   [(set (match_operand:QI 0 "register_operand" "")
12498         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12499   ""
12500   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12501
12502 (define_expand "sge"
12503   [(set (match_operand:QI 0 "register_operand" "")
12504         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12505   ""
12506   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12507
12508 (define_expand "sgeu"
12509   [(set (match_operand:QI 0 "register_operand" "")
12510         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12511   ""
12512   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12513
12514 (define_expand "sle"
12515   [(set (match_operand:QI 0 "register_operand" "")
12516         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12517   ""
12518   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12519
12520 (define_expand "sleu"
12521   [(set (match_operand:QI 0 "register_operand" "")
12522         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12523   ""
12524   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12525
12526 (define_expand "sunordered"
12527   [(set (match_operand:QI 0 "register_operand" "")
12528         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12529   "TARGET_80387 || TARGET_SSE"
12530   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12531
12532 (define_expand "sordered"
12533   [(set (match_operand:QI 0 "register_operand" "")
12534         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12535   "TARGET_80387"
12536   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12537
12538 (define_expand "suneq"
12539   [(set (match_operand:QI 0 "register_operand" "")
12540         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12541   "TARGET_80387 || TARGET_SSE"
12542   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12543
12544 (define_expand "sunge"
12545   [(set (match_operand:QI 0 "register_operand" "")
12546         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12547   "TARGET_80387 || TARGET_SSE"
12548   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12549
12550 (define_expand "sungt"
12551   [(set (match_operand:QI 0 "register_operand" "")
12552         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12553   "TARGET_80387 || TARGET_SSE"
12554   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12555
12556 (define_expand "sunle"
12557   [(set (match_operand:QI 0 "register_operand" "")
12558         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12559   "TARGET_80387 || TARGET_SSE"
12560   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12561
12562 (define_expand "sunlt"
12563   [(set (match_operand:QI 0 "register_operand" "")
12564         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12565   "TARGET_80387 || TARGET_SSE"
12566   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12567
12568 (define_expand "sltgt"
12569   [(set (match_operand:QI 0 "register_operand" "")
12570         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12571   "TARGET_80387 || TARGET_SSE"
12572   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12573
12574 (define_insn "*setcc_1"
12575   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12576         (match_operator:QI 1 "ix86_comparison_operator"
12577           [(reg FLAGS_REG) (const_int 0)]))]
12578   ""
12579   "set%C1\t%0"
12580   [(set_attr "type" "setcc")
12581    (set_attr "mode" "QI")])
12582
12583 (define_insn "*setcc_2"
12584   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12585         (match_operator:QI 1 "ix86_comparison_operator"
12586           [(reg FLAGS_REG) (const_int 0)]))]
12587   ""
12588   "set%C1\t%0"
12589   [(set_attr "type" "setcc")
12590    (set_attr "mode" "QI")])
12591
12592 ;; In general it is not safe to assume too much about CCmode registers,
12593 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12594 ;; conditions this is safe on x86, so help combine not create
12595 ;;
12596 ;;      seta    %al
12597 ;;      testb   %al, %al
12598 ;;      sete    %al
12599
12600 (define_split 
12601   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12602         (ne:QI (match_operator 1 "ix86_comparison_operator"
12603                  [(reg FLAGS_REG) (const_int 0)])
12604             (const_int 0)))]
12605   ""
12606   [(set (match_dup 0) (match_dup 1))]
12607 {
12608   PUT_MODE (operands[1], QImode);
12609 })
12610
12611 (define_split 
12612   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12613         (ne:QI (match_operator 1 "ix86_comparison_operator"
12614                  [(reg FLAGS_REG) (const_int 0)])
12615             (const_int 0)))]
12616   ""
12617   [(set (match_dup 0) (match_dup 1))]
12618 {
12619   PUT_MODE (operands[1], QImode);
12620 })
12621
12622 (define_split 
12623   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12624         (eq:QI (match_operator 1 "ix86_comparison_operator"
12625                  [(reg FLAGS_REG) (const_int 0)])
12626             (const_int 0)))]
12627   ""
12628   [(set (match_dup 0) (match_dup 1))]
12629 {
12630   rtx new_op1 = copy_rtx (operands[1]);
12631   operands[1] = new_op1;
12632   PUT_MODE (new_op1, QImode);
12633   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12634                                              GET_MODE (XEXP (new_op1, 0))));
12635
12636   /* Make sure that (a) the CCmode we have for the flags is strong
12637      enough for the reversed compare or (b) we have a valid FP compare.  */
12638   if (! ix86_comparison_operator (new_op1, VOIDmode))
12639     FAIL;
12640 })
12641
12642 (define_split 
12643   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12644         (eq:QI (match_operator 1 "ix86_comparison_operator"
12645                  [(reg FLAGS_REG) (const_int 0)])
12646             (const_int 0)))]
12647   ""
12648   [(set (match_dup 0) (match_dup 1))]
12649 {
12650   rtx new_op1 = copy_rtx (operands[1]);
12651   operands[1] = new_op1;
12652   PUT_MODE (new_op1, QImode);
12653   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12654                                              GET_MODE (XEXP (new_op1, 0))));
12655
12656   /* Make sure that (a) the CCmode we have for the flags is strong
12657      enough for the reversed compare or (b) we have a valid FP compare.  */
12658   if (! ix86_comparison_operator (new_op1, VOIDmode))
12659     FAIL;
12660 })
12661
12662 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12663 ;; subsequent logical operations are used to imitate conditional moves.
12664 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12665 ;; it directly.  Further holding this value in pseudo register might bring
12666 ;; problem in implicit normalization in spill code.
12667 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12668 ;; instructions after reload by splitting the conditional move patterns.
12669
12670 (define_insn "*sse_setccsf"
12671   [(set (match_operand:SF 0 "register_operand" "=x")
12672         (match_operator:SF 1 "sse_comparison_operator"
12673           [(match_operand:SF 2 "register_operand" "0")
12674            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12675   "TARGET_SSE && reload_completed"
12676   "cmp%D1ss\t{%3, %0|%0, %3}"
12677   [(set_attr "type" "ssecmp")
12678    (set_attr "mode" "SF")])
12679
12680 (define_insn "*sse_setccdf"
12681   [(set (match_operand:DF 0 "register_operand" "=Y")
12682         (match_operator:DF 1 "sse_comparison_operator"
12683           [(match_operand:DF 2 "register_operand" "0")
12684            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12685   "TARGET_SSE2 && reload_completed"
12686   "cmp%D1sd\t{%3, %0|%0, %3}"
12687   [(set_attr "type" "ssecmp")
12688    (set_attr "mode" "DF")])
12689 \f
12690 ;; Basic conditional jump instructions.
12691 ;; We ignore the overflow flag for signed branch instructions.
12692
12693 ;; For all bCOND expanders, also expand the compare or test insn that
12694 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12695
12696 (define_expand "beq"
12697   [(set (pc)
12698         (if_then_else (match_dup 1)
12699                       (label_ref (match_operand 0 "" ""))
12700                       (pc)))]
12701   ""
12702   "ix86_expand_branch (EQ, operands[0]); DONE;")
12703
12704 (define_expand "bne"
12705   [(set (pc)
12706         (if_then_else (match_dup 1)
12707                       (label_ref (match_operand 0 "" ""))
12708                       (pc)))]
12709   ""
12710   "ix86_expand_branch (NE, operands[0]); DONE;")
12711
12712 (define_expand "bgt"
12713   [(set (pc)
12714         (if_then_else (match_dup 1)
12715                       (label_ref (match_operand 0 "" ""))
12716                       (pc)))]
12717   ""
12718   "ix86_expand_branch (GT, operands[0]); DONE;")
12719
12720 (define_expand "bgtu"
12721   [(set (pc)
12722         (if_then_else (match_dup 1)
12723                       (label_ref (match_operand 0 "" ""))
12724                       (pc)))]
12725   ""
12726   "ix86_expand_branch (GTU, operands[0]); DONE;")
12727
12728 (define_expand "blt"
12729   [(set (pc)
12730         (if_then_else (match_dup 1)
12731                       (label_ref (match_operand 0 "" ""))
12732                       (pc)))]
12733   ""
12734   "ix86_expand_branch (LT, operands[0]); DONE;")
12735
12736 (define_expand "bltu"
12737   [(set (pc)
12738         (if_then_else (match_dup 1)
12739                       (label_ref (match_operand 0 "" ""))
12740                       (pc)))]
12741   ""
12742   "ix86_expand_branch (LTU, operands[0]); DONE;")
12743
12744 (define_expand "bge"
12745   [(set (pc)
12746         (if_then_else (match_dup 1)
12747                       (label_ref (match_operand 0 "" ""))
12748                       (pc)))]
12749   ""
12750   "ix86_expand_branch (GE, operands[0]); DONE;")
12751
12752 (define_expand "bgeu"
12753   [(set (pc)
12754         (if_then_else (match_dup 1)
12755                       (label_ref (match_operand 0 "" ""))
12756                       (pc)))]
12757   ""
12758   "ix86_expand_branch (GEU, operands[0]); DONE;")
12759
12760 (define_expand "ble"
12761   [(set (pc)
12762         (if_then_else (match_dup 1)
12763                       (label_ref (match_operand 0 "" ""))
12764                       (pc)))]
12765   ""
12766   "ix86_expand_branch (LE, operands[0]); DONE;")
12767
12768 (define_expand "bleu"
12769   [(set (pc)
12770         (if_then_else (match_dup 1)
12771                       (label_ref (match_operand 0 "" ""))
12772                       (pc)))]
12773   ""
12774   "ix86_expand_branch (LEU, operands[0]); DONE;")
12775
12776 (define_expand "bunordered"
12777   [(set (pc)
12778         (if_then_else (match_dup 1)
12779                       (label_ref (match_operand 0 "" ""))
12780                       (pc)))]
12781   "TARGET_80387 || TARGET_SSE"
12782   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12783
12784 (define_expand "bordered"
12785   [(set (pc)
12786         (if_then_else (match_dup 1)
12787                       (label_ref (match_operand 0 "" ""))
12788                       (pc)))]
12789   "TARGET_80387 || TARGET_SSE"
12790   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12791
12792 (define_expand "buneq"
12793   [(set (pc)
12794         (if_then_else (match_dup 1)
12795                       (label_ref (match_operand 0 "" ""))
12796                       (pc)))]
12797   "TARGET_80387 || TARGET_SSE"
12798   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12799
12800 (define_expand "bunge"
12801   [(set (pc)
12802         (if_then_else (match_dup 1)
12803                       (label_ref (match_operand 0 "" ""))
12804                       (pc)))]
12805   "TARGET_80387 || TARGET_SSE"
12806   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12807
12808 (define_expand "bungt"
12809   [(set (pc)
12810         (if_then_else (match_dup 1)
12811                       (label_ref (match_operand 0 "" ""))
12812                       (pc)))]
12813   "TARGET_80387 || TARGET_SSE"
12814   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12815
12816 (define_expand "bunle"
12817   [(set (pc)
12818         (if_then_else (match_dup 1)
12819                       (label_ref (match_operand 0 "" ""))
12820                       (pc)))]
12821   "TARGET_80387 || TARGET_SSE"
12822   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12823
12824 (define_expand "bunlt"
12825   [(set (pc)
12826         (if_then_else (match_dup 1)
12827                       (label_ref (match_operand 0 "" ""))
12828                       (pc)))]
12829   "TARGET_80387 || TARGET_SSE"
12830   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12831
12832 (define_expand "bltgt"
12833   [(set (pc)
12834         (if_then_else (match_dup 1)
12835                       (label_ref (match_operand 0 "" ""))
12836                       (pc)))]
12837   "TARGET_80387 || TARGET_SSE"
12838   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12839
12840 (define_insn "*jcc_1"
12841   [(set (pc)
12842         (if_then_else (match_operator 1 "ix86_comparison_operator"
12843                                       [(reg FLAGS_REG) (const_int 0)])
12844                       (label_ref (match_operand 0 "" ""))
12845                       (pc)))]
12846   ""
12847   "%+j%C1\t%l0"
12848   [(set_attr "type" "ibr")
12849    (set_attr "modrm" "0")
12850    (set (attr "length")
12851            (if_then_else (and (ge (minus (match_dup 0) (pc))
12852                                   (const_int -126))
12853                               (lt (minus (match_dup 0) (pc))
12854                                   (const_int 128)))
12855              (const_int 2)
12856              (const_int 6)))])
12857
12858 (define_insn "*jcc_2"
12859   [(set (pc)
12860         (if_then_else (match_operator 1 "ix86_comparison_operator"
12861                                       [(reg FLAGS_REG) (const_int 0)])
12862                       (pc)
12863                       (label_ref (match_operand 0 "" ""))))]
12864   ""
12865   "%+j%c1\t%l0"
12866   [(set_attr "type" "ibr")
12867    (set_attr "modrm" "0")
12868    (set (attr "length")
12869            (if_then_else (and (ge (minus (match_dup 0) (pc))
12870                                   (const_int -126))
12871                               (lt (minus (match_dup 0) (pc))
12872                                   (const_int 128)))
12873              (const_int 2)
12874              (const_int 6)))])
12875
12876 ;; In general it is not safe to assume too much about CCmode registers,
12877 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12878 ;; conditions this is safe on x86, so help combine not create
12879 ;;
12880 ;;      seta    %al
12881 ;;      testb   %al, %al
12882 ;;      je      Lfoo
12883
12884 (define_split 
12885   [(set (pc)
12886         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12887                                       [(reg FLAGS_REG) (const_int 0)])
12888                           (const_int 0))
12889                       (label_ref (match_operand 1 "" ""))
12890                       (pc)))]
12891   ""
12892   [(set (pc)
12893         (if_then_else (match_dup 0)
12894                       (label_ref (match_dup 1))
12895                       (pc)))]
12896 {
12897   PUT_MODE (operands[0], VOIDmode);
12898 })
12899   
12900 (define_split 
12901   [(set (pc)
12902         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12903                                       [(reg FLAGS_REG) (const_int 0)])
12904                           (const_int 0))
12905                       (label_ref (match_operand 1 "" ""))
12906                       (pc)))]
12907   ""
12908   [(set (pc)
12909         (if_then_else (match_dup 0)
12910                       (label_ref (match_dup 1))
12911                       (pc)))]
12912 {
12913   rtx new_op0 = copy_rtx (operands[0]);
12914   operands[0] = new_op0;
12915   PUT_MODE (new_op0, VOIDmode);
12916   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12917                                              GET_MODE (XEXP (new_op0, 0))));
12918
12919   /* Make sure that (a) the CCmode we have for the flags is strong
12920      enough for the reversed compare or (b) we have a valid FP compare.  */
12921   if (! ix86_comparison_operator (new_op0, VOIDmode))
12922     FAIL;
12923 })
12924
12925 ;; Define combination compare-and-branch fp compare instructions to use
12926 ;; during early optimization.  Splitting the operation apart early makes
12927 ;; for bad code when we want to reverse the operation.
12928
12929 (define_insn "*fp_jcc_1"
12930   [(set (pc)
12931         (if_then_else (match_operator 0 "comparison_operator"
12932                         [(match_operand 1 "register_operand" "f")
12933                          (match_operand 2 "register_operand" "f")])
12934           (label_ref (match_operand 3 "" ""))
12935           (pc)))
12936    (clobber (reg:CCFP FPSR_REG))
12937    (clobber (reg:CCFP FLAGS_REG))]
12938   "TARGET_CMOVE && TARGET_80387
12939    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12940    && FLOAT_MODE_P (GET_MODE (operands[1]))
12941    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12942    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12943   "#")
12944
12945 (define_insn "*fp_jcc_1_sse"
12946   [(set (pc)
12947         (if_then_else (match_operator 0 "comparison_operator"
12948                         [(match_operand 1 "register_operand" "f#x,x#f")
12949                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12950           (label_ref (match_operand 3 "" ""))
12951           (pc)))
12952    (clobber (reg:CCFP FPSR_REG))
12953    (clobber (reg:CCFP FLAGS_REG))]
12954   "TARGET_80387
12955    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12956    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12957    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12958   "#")
12959
12960 (define_insn "*fp_jcc_1_sse_only"
12961   [(set (pc)
12962         (if_then_else (match_operator 0 "comparison_operator"
12963                         [(match_operand 1 "register_operand" "x")
12964                          (match_operand 2 "nonimmediate_operand" "xm")])
12965           (label_ref (match_operand 3 "" ""))
12966           (pc)))
12967    (clobber (reg:CCFP FPSR_REG))
12968    (clobber (reg:CCFP FLAGS_REG))]
12969   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12970    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12971    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12972   "#")
12973
12974 (define_insn "*fp_jcc_2"
12975   [(set (pc)
12976         (if_then_else (match_operator 0 "comparison_operator"
12977                         [(match_operand 1 "register_operand" "f")
12978                          (match_operand 2 "register_operand" "f")])
12979           (pc)
12980           (label_ref (match_operand 3 "" ""))))
12981    (clobber (reg:CCFP FPSR_REG))
12982    (clobber (reg:CCFP FLAGS_REG))]
12983   "TARGET_CMOVE && TARGET_80387
12984    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12985    && FLOAT_MODE_P (GET_MODE (operands[1]))
12986    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12987    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12988   "#")
12989
12990 (define_insn "*fp_jcc_2_sse"
12991   [(set (pc)
12992         (if_then_else (match_operator 0 "comparison_operator"
12993                         [(match_operand 1 "register_operand" "f#x,x#f")
12994                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12995           (pc)
12996           (label_ref (match_operand 3 "" ""))))
12997    (clobber (reg:CCFP FPSR_REG))
12998    (clobber (reg:CCFP FLAGS_REG))]
12999   "TARGET_80387
13000    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13001    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13002    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13003   "#")
13004
13005 (define_insn "*fp_jcc_2_sse_only"
13006   [(set (pc)
13007         (if_then_else (match_operator 0 "comparison_operator"
13008                         [(match_operand 1 "register_operand" "x")
13009                          (match_operand 2 "nonimmediate_operand" "xm")])
13010           (pc)
13011           (label_ref (match_operand 3 "" ""))))
13012    (clobber (reg:CCFP FPSR_REG))
13013    (clobber (reg:CCFP FLAGS_REG))]
13014   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13015    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13016    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13017   "#")
13018
13019 (define_insn "*fp_jcc_3"
13020   [(set (pc)
13021         (if_then_else (match_operator 0 "comparison_operator"
13022                         [(match_operand 1 "register_operand" "f")
13023                          (match_operand 2 "nonimmediate_operand" "fm")])
13024           (label_ref (match_operand 3 "" ""))
13025           (pc)))
13026    (clobber (reg:CCFP FPSR_REG))
13027    (clobber (reg:CCFP FLAGS_REG))
13028    (clobber (match_scratch:HI 4 "=a"))]
13029   "TARGET_80387
13030    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13031    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13032    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13033    && SELECT_CC_MODE (GET_CODE (operands[0]),
13034                       operands[1], operands[2]) == CCFPmode
13035    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13036   "#")
13037
13038 (define_insn "*fp_jcc_4"
13039   [(set (pc)
13040         (if_then_else (match_operator 0 "comparison_operator"
13041                         [(match_operand 1 "register_operand" "f")
13042                          (match_operand 2 "nonimmediate_operand" "fm")])
13043           (pc)
13044           (label_ref (match_operand 3 "" ""))))
13045    (clobber (reg:CCFP FPSR_REG))
13046    (clobber (reg:CCFP FLAGS_REG))
13047    (clobber (match_scratch:HI 4 "=a"))]
13048   "TARGET_80387
13049    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13050    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13051    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13052    && SELECT_CC_MODE (GET_CODE (operands[0]),
13053                       operands[1], operands[2]) == CCFPmode
13054    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13055   "#")
13056
13057 (define_insn "*fp_jcc_5"
13058   [(set (pc)
13059         (if_then_else (match_operator 0 "comparison_operator"
13060                         [(match_operand 1 "register_operand" "f")
13061                          (match_operand 2 "register_operand" "f")])
13062           (label_ref (match_operand 3 "" ""))
13063           (pc)))
13064    (clobber (reg:CCFP FPSR_REG))
13065    (clobber (reg:CCFP FLAGS_REG))
13066    (clobber (match_scratch:HI 4 "=a"))]
13067   "TARGET_80387
13068    && FLOAT_MODE_P (GET_MODE (operands[1]))
13069    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13070    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13071   "#")
13072
13073 (define_insn "*fp_jcc_6"
13074   [(set (pc)
13075         (if_then_else (match_operator 0 "comparison_operator"
13076                         [(match_operand 1 "register_operand" "f")
13077                          (match_operand 2 "register_operand" "f")])
13078           (pc)
13079           (label_ref (match_operand 3 "" ""))))
13080    (clobber (reg:CCFP FPSR_REG))
13081    (clobber (reg:CCFP FLAGS_REG))
13082    (clobber (match_scratch:HI 4 "=a"))]
13083   "TARGET_80387
13084    && FLOAT_MODE_P (GET_MODE (operands[1]))
13085    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13086    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13087   "#")
13088
13089 (define_insn "*fp_jcc_7"
13090   [(set (pc)
13091         (if_then_else (match_operator 0 "comparison_operator"
13092                         [(match_operand 1 "register_operand" "f")
13093                          (match_operand 2 "const_double_operand" "C")])
13094           (label_ref (match_operand 3 "" ""))
13095           (pc)))
13096    (clobber (reg:CCFP FPSR_REG))
13097    (clobber (reg:CCFP FLAGS_REG))
13098    (clobber (match_scratch:HI 4 "=a"))]
13099   "TARGET_80387
13100    && FLOAT_MODE_P (GET_MODE (operands[1]))
13101    && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
13102    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13103    && SELECT_CC_MODE (GET_CODE (operands[0]),
13104                       operands[1], operands[2]) == CCFPmode
13105    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13106   "#")
13107
13108 ;; The order of operands in *fp_jcc_8 is forced by combine in
13109 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13110 ;; with a precedence over other operators and is always put in the first
13111 ;; place. Swap condition and operands to match ficom instruction.
13112
13113 (define_insn "*fp_jcc_8"
13114   [(set (pc)
13115         (if_then_else (match_operator 0 "comparison_operator"
13116                         [(match_operator 1 "float_operator"
13117                            [(match_operand:SI 2 "nonimmediate_operand" "m,?r")])
13118                            (match_operand 3 "register_operand" "f,f")])
13119           (label_ref (match_operand 4 "" ""))
13120           (pc)))
13121    (clobber (reg:CCFP FPSR_REG))
13122    (clobber (reg:CCFP FLAGS_REG))
13123    (clobber (match_scratch:HI 5 "=a,a"))]
13124   "TARGET_80387 && TARGET_USE_FIOP
13125    && FLOAT_MODE_P (GET_MODE (operands[3]))
13126    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13127    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13128    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13129    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13130   "#")
13131
13132 (define_split
13133   [(set (pc)
13134         (if_then_else (match_operator 0 "comparison_operator"
13135                         [(match_operand 1 "register_operand" "")
13136                          (match_operand 2 "nonimmediate_operand" "")])
13137           (match_operand 3 "" "")
13138           (match_operand 4 "" "")))
13139    (clobber (reg:CCFP FPSR_REG))
13140    (clobber (reg:CCFP FLAGS_REG))]
13141   "reload_completed"
13142   [(const_int 0)]
13143 {
13144   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13145                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13146   DONE;
13147 })
13148
13149 (define_split
13150   [(set (pc)
13151         (if_then_else (match_operator 0 "comparison_operator"
13152                         [(match_operand 1 "register_operand" "")
13153                          (match_operand 2 "general_operand" "")])
13154           (match_operand 3 "" "")
13155           (match_operand 4 "" "")))
13156    (clobber (reg:CCFP FPSR_REG))
13157    (clobber (reg:CCFP FLAGS_REG))
13158    (clobber (match_scratch:HI 5 "=a"))]
13159   "reload_completed"
13160   [(const_int 0)]
13161 {
13162   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13163                         operands[3], operands[4], operands[5], NULL_RTX);
13164   DONE;
13165 })
13166
13167 (define_split
13168   [(set (pc)
13169         (if_then_else (match_operator 0 "comparison_operator"
13170                         [(match_operator 1 "float_operator"
13171                            [(match_operand:SI 2 "memory_operand" "")])
13172                            (match_operand 3 "register_operand" "")])
13173           (match_operand 4 "" "")
13174           (match_operand 5 "" "")))
13175    (clobber (reg:CCFP FPSR_REG))
13176    (clobber (reg:CCFP FLAGS_REG))
13177    (clobber (match_scratch:HI 6 "=a"))]
13178   "reload_completed"
13179   [(const_int 0)]
13180 {
13181   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13182   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13183                         operands[3], operands[7],
13184                         operands[4], operands[5], operands[6], NULL_RTX);
13185   DONE;
13186 })
13187
13188 ;; %%% Kill this when reload knows how to do it.
13189 (define_split
13190   [(set (pc)
13191         (if_then_else (match_operator 0 "comparison_operator"
13192                         [(match_operator 1 "float_operator"
13193                            [(match_operand:SI 2 "register_operand" "")])
13194                            (match_operand 3 "register_operand" "")])
13195           (match_operand 4 "" "")
13196           (match_operand 5 "" "")))
13197    (clobber (reg:CCFP FPSR_REG))
13198    (clobber (reg:CCFP FLAGS_REG))
13199    (clobber (match_scratch:HI 6 "=a"))]
13200   "reload_completed"
13201   [(const_int 0)]
13202 {
13203   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13204   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13205   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13206                         operands[3], operands[7],
13207                         operands[4], operands[5], operands[6], operands[2]);
13208   DONE;
13209 })
13210 \f
13211 ;; Unconditional and other jump instructions
13212
13213 (define_insn "jump"
13214   [(set (pc)
13215         (label_ref (match_operand 0 "" "")))]
13216   ""
13217   "jmp\t%l0"
13218   [(set_attr "type" "ibr")
13219    (set (attr "length")
13220            (if_then_else (and (ge (minus (match_dup 0) (pc))
13221                                   (const_int -126))
13222                               (lt (minus (match_dup 0) (pc))
13223                                   (const_int 128)))
13224              (const_int 2)
13225              (const_int 5)))
13226    (set_attr "modrm" "0")])
13227
13228 (define_expand "indirect_jump"
13229   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13230   ""
13231   "")
13232
13233 (define_insn "*indirect_jump"
13234   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13235   "!TARGET_64BIT"
13236   "jmp\t%A0"
13237   [(set_attr "type" "ibr")
13238    (set_attr "length_immediate" "0")])
13239
13240 (define_insn "*indirect_jump_rtx64"
13241   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13242   "TARGET_64BIT"
13243   "jmp\t%A0"
13244   [(set_attr "type" "ibr")
13245    (set_attr "length_immediate" "0")])
13246
13247 (define_expand "tablejump"
13248   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13249               (use (label_ref (match_operand 1 "" "")))])]
13250   ""
13251 {
13252   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13253      relative.  Convert the relative address to an absolute address.  */
13254   if (flag_pic)
13255     {
13256       rtx op0, op1;
13257       enum rtx_code code;
13258
13259       if (TARGET_64BIT)
13260         {
13261           code = PLUS;
13262           op0 = operands[0];
13263           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13264         }
13265       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13266         {
13267           code = PLUS;
13268           op0 = operands[0];
13269           op1 = pic_offset_table_rtx;
13270         }
13271       else
13272         {
13273           code = MINUS;
13274           op0 = pic_offset_table_rtx;
13275           op1 = operands[0];
13276         }
13277
13278       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13279                                          OPTAB_DIRECT);
13280     }
13281 })
13282
13283 (define_insn "*tablejump_1"
13284   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13285    (use (label_ref (match_operand 1 "" "")))]
13286   "!TARGET_64BIT"
13287   "jmp\t%A0"
13288   [(set_attr "type" "ibr")
13289    (set_attr "length_immediate" "0")])
13290
13291 (define_insn "*tablejump_1_rtx64"
13292   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13293    (use (label_ref (match_operand 1 "" "")))]
13294   "TARGET_64BIT"
13295   "jmp\t%A0"
13296   [(set_attr "type" "ibr")
13297    (set_attr "length_immediate" "0")])
13298 \f
13299 ;; Loop instruction
13300 ;;
13301 ;; This is all complicated by the fact that since this is a jump insn
13302 ;; we must handle our own reloads.
13303
13304 (define_expand "doloop_end"
13305   [(use (match_operand 0 "" ""))        ; loop pseudo
13306    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13307    (use (match_operand 2 "" ""))        ; max iterations
13308    (use (match_operand 3 "" ""))        ; loop level 
13309    (use (match_operand 4 "" ""))]       ; label
13310   "!TARGET_64BIT && TARGET_USE_LOOP"
13311   "                                 
13312 {
13313   /* Only use cloop on innermost loops.  */
13314   if (INTVAL (operands[3]) > 1)
13315     FAIL;
13316   if (GET_MODE (operands[0]) != SImode)
13317     FAIL;
13318   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13319                                            operands[0]));
13320   DONE;
13321 }")
13322
13323 (define_insn "doloop_end_internal"
13324   [(set (pc)
13325         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13326                           (const_int 1))
13327                       (label_ref (match_operand 0 "" ""))
13328                       (pc)))
13329    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13330         (plus:SI (match_dup 1)
13331                  (const_int -1)))
13332    (clobber (match_scratch:SI 3 "=X,X,r"))
13333    (clobber (reg:CC FLAGS_REG))]
13334   "!TARGET_64BIT && TARGET_USE_LOOP
13335    && (reload_in_progress || reload_completed
13336        || register_operand (operands[2], VOIDmode))"
13337 {
13338   if (which_alternative != 0)
13339     return "#";
13340   if (get_attr_length (insn) == 2)
13341     return "%+loop\t%l0";
13342   else
13343     return "dec{l}\t%1\;%+jne\t%l0";
13344 }
13345   [(set (attr "length")
13346         (if_then_else (and (eq_attr "alternative" "0")
13347                            (and (ge (minus (match_dup 0) (pc))
13348                                     (const_int -126))
13349                                 (lt (minus (match_dup 0) (pc))
13350                                     (const_int 128))))
13351                       (const_int 2)
13352                       (const_int 16)))
13353    ;; We don't know the type before shorten branches.  Optimistically expect
13354    ;; the loop instruction to match.
13355    (set (attr "type") (const_string "ibr"))])
13356
13357 (define_split
13358   [(set (pc)
13359         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13360                           (const_int 1))
13361                       (match_operand 0 "" "")
13362                       (pc)))
13363    (set (match_dup 1)
13364         (plus:SI (match_dup 1)
13365                  (const_int -1)))
13366    (clobber (match_scratch:SI 2 ""))
13367    (clobber (reg:CC FLAGS_REG))]
13368   "!TARGET_64BIT && TARGET_USE_LOOP
13369    && reload_completed
13370    && REGNO (operands[1]) != 2"
13371   [(parallel [(set (reg:CCZ FLAGS_REG)
13372                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13373                                  (const_int 0)))
13374               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13375    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13376                            (match_dup 0)
13377                            (pc)))]
13378   "")
13379   
13380 (define_split
13381   [(set (pc)
13382         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13383                           (const_int 1))
13384                       (match_operand 0 "" "")
13385                       (pc)))
13386    (set (match_operand:SI 2 "nonimmediate_operand" "")
13387         (plus:SI (match_dup 1)
13388                  (const_int -1)))
13389    (clobber (match_scratch:SI 3 ""))
13390    (clobber (reg:CC FLAGS_REG))]
13391   "!TARGET_64BIT && TARGET_USE_LOOP
13392    && reload_completed
13393    && (! REG_P (operands[2])
13394        || ! rtx_equal_p (operands[1], operands[2]))"
13395   [(set (match_dup 3) (match_dup 1))
13396    (parallel [(set (reg:CCZ FLAGS_REG)
13397                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13398                                 (const_int 0)))
13399               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13400    (set (match_dup 2) (match_dup 3))
13401    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13402                            (match_dup 0)
13403                            (pc)))]
13404   "")
13405
13406 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13407
13408 (define_peephole2
13409   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13410    (set (match_operand:QI 1 "register_operand" "")
13411         (match_operator:QI 2 "ix86_comparison_operator"
13412           [(reg FLAGS_REG) (const_int 0)]))
13413    (set (match_operand 3 "q_regs_operand" "")
13414         (zero_extend (match_dup 1)))]
13415   "(peep2_reg_dead_p (3, operands[1])
13416     || operands_match_p (operands[1], operands[3]))
13417    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13418   [(set (match_dup 4) (match_dup 0))
13419    (set (strict_low_part (match_dup 5))
13420         (match_dup 2))]
13421 {
13422   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13423   operands[5] = gen_lowpart (QImode, operands[3]);
13424   ix86_expand_clear (operands[3]);
13425 })
13426
13427 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13428
13429 (define_peephole2
13430   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13431    (set (match_operand:QI 1 "register_operand" "")
13432         (match_operator:QI 2 "ix86_comparison_operator"
13433           [(reg FLAGS_REG) (const_int 0)]))
13434    (parallel [(set (match_operand 3 "q_regs_operand" "")
13435                    (zero_extend (match_dup 1)))
13436               (clobber (reg:CC FLAGS_REG))])]
13437   "(peep2_reg_dead_p (3, operands[1])
13438     || operands_match_p (operands[1], operands[3]))
13439    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13440   [(set (match_dup 4) (match_dup 0))
13441    (set (strict_low_part (match_dup 5))
13442         (match_dup 2))]
13443 {
13444   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13445   operands[5] = gen_lowpart (QImode, operands[3]);
13446   ix86_expand_clear (operands[3]);
13447 })
13448 \f
13449 ;; Call instructions.
13450
13451 ;; The predicates normally associated with named expanders are not properly
13452 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13453 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13454
13455 ;; Call subroutine returning no value.
13456
13457 (define_expand "call_pop"
13458   [(parallel [(call (match_operand:QI 0 "" "")
13459                     (match_operand:SI 1 "" ""))
13460               (set (reg:SI SP_REG)
13461                    (plus:SI (reg:SI SP_REG)
13462                             (match_operand:SI 3 "" "")))])]
13463   "!TARGET_64BIT"
13464 {
13465   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13466   DONE;
13467 })
13468
13469 (define_insn "*call_pop_0"
13470   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13471          (match_operand:SI 1 "" ""))
13472    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13473                             (match_operand:SI 2 "immediate_operand" "")))]
13474   "!TARGET_64BIT"
13475 {
13476   if (SIBLING_CALL_P (insn))
13477     return "jmp\t%P0";
13478   else
13479     return "call\t%P0";
13480 }
13481   [(set_attr "type" "call")])
13482   
13483 (define_insn "*call_pop_1"
13484   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13485          (match_operand:SI 1 "" ""))
13486    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13487                             (match_operand:SI 2 "immediate_operand" "i")))]
13488   "!TARGET_64BIT"
13489 {
13490   if (constant_call_address_operand (operands[0], Pmode))
13491     {
13492       if (SIBLING_CALL_P (insn))
13493         return "jmp\t%P0";
13494       else
13495         return "call\t%P0";
13496     }
13497   if (SIBLING_CALL_P (insn))
13498     return "jmp\t%A0";
13499   else
13500     return "call\t%A0";
13501 }
13502   [(set_attr "type" "call")])
13503
13504 (define_expand "call"
13505   [(call (match_operand:QI 0 "" "")
13506          (match_operand 1 "" ""))
13507    (use (match_operand 2 "" ""))]
13508   ""
13509 {
13510   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13511   DONE;
13512 })
13513
13514 (define_expand "sibcall"
13515   [(call (match_operand:QI 0 "" "")
13516          (match_operand 1 "" ""))
13517    (use (match_operand 2 "" ""))]
13518   ""
13519 {
13520   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13521   DONE;
13522 })
13523
13524 (define_insn "*call_0"
13525   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13526          (match_operand 1 "" ""))]
13527   ""
13528 {
13529   if (SIBLING_CALL_P (insn))
13530     return "jmp\t%P0";
13531   else
13532     return "call\t%P0";
13533 }
13534   [(set_attr "type" "call")])
13535
13536 (define_insn "*call_1"
13537   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13538          (match_operand 1 "" ""))]
13539   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13540 {
13541   if (constant_call_address_operand (operands[0], Pmode))
13542     return "call\t%P0";
13543   return "call\t%A0";
13544 }
13545   [(set_attr "type" "call")])
13546
13547 (define_insn "*sibcall_1"
13548   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13549          (match_operand 1 "" ""))]
13550   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13551 {
13552   if (constant_call_address_operand (operands[0], Pmode))
13553     return "jmp\t%P0";
13554   return "jmp\t%A0";
13555 }
13556   [(set_attr "type" "call")])
13557
13558 (define_insn "*call_1_rex64"
13559   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13560          (match_operand 1 "" ""))]
13561   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13562 {
13563   if (constant_call_address_operand (operands[0], Pmode))
13564     return "call\t%P0";
13565   return "call\t%A0";
13566 }
13567   [(set_attr "type" "call")])
13568
13569 (define_insn "*sibcall_1_rex64"
13570   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13571          (match_operand 1 "" ""))]
13572   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13573   "jmp\t%P0"
13574   [(set_attr "type" "call")])
13575
13576 (define_insn "*sibcall_1_rex64_v"
13577   [(call (mem:QI (reg:DI 40))
13578          (match_operand 0 "" ""))]
13579   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13580   "jmp\t*%%r11"
13581   [(set_attr "type" "call")])
13582
13583
13584 ;; Call subroutine, returning value in operand 0
13585
13586 (define_expand "call_value_pop"
13587   [(parallel [(set (match_operand 0 "" "")
13588                    (call (match_operand:QI 1 "" "")
13589                          (match_operand:SI 2 "" "")))
13590               (set (reg:SI SP_REG)
13591                    (plus:SI (reg:SI SP_REG)
13592                             (match_operand:SI 4 "" "")))])]
13593   "!TARGET_64BIT"
13594 {
13595   ix86_expand_call (operands[0], operands[1], operands[2],
13596                     operands[3], operands[4], 0);
13597   DONE;
13598 })
13599
13600 (define_expand "call_value"
13601   [(set (match_operand 0 "" "")
13602         (call (match_operand:QI 1 "" "")
13603               (match_operand:SI 2 "" "")))
13604    (use (match_operand:SI 3 "" ""))]
13605   ;; Operand 2 not used on the i386.
13606   ""
13607 {
13608   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13609   DONE;
13610 })
13611
13612 (define_expand "sibcall_value"
13613   [(set (match_operand 0 "" "")
13614         (call (match_operand:QI 1 "" "")
13615               (match_operand:SI 2 "" "")))
13616    (use (match_operand:SI 3 "" ""))]
13617   ;; Operand 2 not used on the i386.
13618   ""
13619 {
13620   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13621   DONE;
13622 })
13623
13624 ;; Call subroutine returning any type.
13625
13626 (define_expand "untyped_call"
13627   [(parallel [(call (match_operand 0 "" "")
13628                     (const_int 0))
13629               (match_operand 1 "" "")
13630               (match_operand 2 "" "")])]
13631   ""
13632 {
13633   int i;
13634
13635   /* In order to give reg-stack an easier job in validating two
13636      coprocessor registers as containing a possible return value,
13637      simply pretend the untyped call returns a complex long double
13638      value.  */
13639
13640   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13641                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13642                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13643                     NULL, 0);
13644
13645   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13646     {
13647       rtx set = XVECEXP (operands[2], 0, i);
13648       emit_move_insn (SET_DEST (set), SET_SRC (set));
13649     }
13650
13651   /* The optimizer does not know that the call sets the function value
13652      registers we stored in the result block.  We avoid problems by
13653      claiming that all hard registers are used and clobbered at this
13654      point.  */
13655   emit_insn (gen_blockage (const0_rtx));
13656
13657   DONE;
13658 })
13659 \f
13660 ;; Prologue and epilogue instructions
13661
13662 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13663 ;; all of memory.  This blocks insns from being moved across this point.
13664
13665 (define_insn "blockage"
13666   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13667   ""
13668   ""
13669   [(set_attr "length" "0")])
13670
13671 ;; Insn emitted into the body of a function to return from a function.
13672 ;; This is only done if the function's epilogue is known to be simple.
13673 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13674
13675 (define_expand "return"
13676   [(return)]
13677   "ix86_can_use_return_insn_p ()"
13678 {
13679   if (current_function_pops_args)
13680     {
13681       rtx popc = GEN_INT (current_function_pops_args);
13682       emit_jump_insn (gen_return_pop_internal (popc));
13683       DONE;
13684     }
13685 })
13686
13687 (define_insn "return_internal"
13688   [(return)]
13689   "reload_completed"
13690   "ret"
13691   [(set_attr "length" "1")
13692    (set_attr "length_immediate" "0")
13693    (set_attr "modrm" "0")])
13694
13695 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13696 ;; instruction Athlon and K8 have.
13697
13698 (define_insn "return_internal_long"
13699   [(return)
13700    (unspec [(const_int 0)] UNSPEC_REP)]
13701   "reload_completed"
13702   "rep {;} ret"
13703   [(set_attr "length" "1")
13704    (set_attr "length_immediate" "0")
13705    (set_attr "prefix_rep" "1")
13706    (set_attr "modrm" "0")])
13707
13708 (define_insn "return_pop_internal"
13709   [(return)
13710    (use (match_operand:SI 0 "const_int_operand" ""))]
13711   "reload_completed"
13712   "ret\t%0"
13713   [(set_attr "length" "3")
13714    (set_attr "length_immediate" "2")
13715    (set_attr "modrm" "0")])
13716
13717 (define_insn "return_indirect_internal"
13718   [(return)
13719    (use (match_operand:SI 0 "register_operand" "r"))]
13720   "reload_completed"
13721   "jmp\t%A0"
13722   [(set_attr "type" "ibr")
13723    (set_attr "length_immediate" "0")])
13724
13725 (define_insn "nop"
13726   [(const_int 0)]
13727   ""
13728   "nop"
13729   [(set_attr "length" "1")
13730    (set_attr "length_immediate" "0")
13731    (set_attr "modrm" "0")])
13732
13733 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13734 ;; branch prediction penalty for the third jump in a 16-byte
13735 ;; block on K8.
13736
13737 (define_insn "align"
13738   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13739   ""
13740 {
13741 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13742   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13743 #else
13744   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13745      The align insn is used to avoid 3 jump instructions in the row to improve
13746      branch prediction and the benefits hardly outweight the cost of extra 8
13747      nops on the average inserted by full alignment pseudo operation.  */
13748 #endif
13749   return "";
13750 }
13751   [(set_attr "length" "16")])
13752
13753 (define_expand "prologue"
13754   [(const_int 1)]
13755   ""
13756   "ix86_expand_prologue (); DONE;")
13757
13758 (define_insn "set_got"
13759   [(set (match_operand:SI 0 "register_operand" "=r")
13760         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13761    (clobber (reg:CC FLAGS_REG))]
13762   "!TARGET_64BIT"
13763   { return output_set_got (operands[0]); }
13764   [(set_attr "type" "multi")
13765    (set_attr "length" "12")])
13766
13767 (define_expand "epilogue"
13768   [(const_int 1)]
13769   ""
13770   "ix86_expand_epilogue (1); DONE;")
13771
13772 (define_expand "sibcall_epilogue"
13773   [(const_int 1)]
13774   ""
13775   "ix86_expand_epilogue (0); DONE;")
13776
13777 (define_expand "eh_return"
13778   [(use (match_operand 0 "register_operand" ""))]
13779   ""
13780 {
13781   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13782
13783   /* Tricky bit: we write the address of the handler to which we will
13784      be returning into someone else's stack frame, one word below the
13785      stack address we wish to restore.  */
13786   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13787   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13788   tmp = gen_rtx_MEM (Pmode, tmp);
13789   emit_move_insn (tmp, ra);
13790
13791   if (Pmode == SImode)
13792     emit_jump_insn (gen_eh_return_si (sa));
13793   else
13794     emit_jump_insn (gen_eh_return_di (sa));
13795   emit_barrier ();
13796   DONE;
13797 })
13798
13799 (define_insn_and_split "eh_return_si"
13800   [(set (pc) 
13801         (unspec [(match_operand:SI 0 "register_operand" "c")]
13802                  UNSPEC_EH_RETURN))]
13803   "!TARGET_64BIT"
13804   "#"
13805   "reload_completed"
13806   [(const_int 1)]
13807   "ix86_expand_epilogue (2); DONE;")
13808
13809 (define_insn_and_split "eh_return_di"
13810   [(set (pc) 
13811         (unspec [(match_operand:DI 0 "register_operand" "c")]
13812                  UNSPEC_EH_RETURN))]
13813   "TARGET_64BIT"
13814   "#"
13815   "reload_completed"
13816   [(const_int 1)]
13817   "ix86_expand_epilogue (2); DONE;")
13818
13819 (define_insn "leave"
13820   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13821    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13822    (clobber (mem:BLK (scratch)))]
13823   "!TARGET_64BIT"
13824   "leave"
13825   [(set_attr "type" "leave")])
13826
13827 (define_insn "leave_rex64"
13828   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13829    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13830    (clobber (mem:BLK (scratch)))]
13831   "TARGET_64BIT"
13832   "leave"
13833   [(set_attr "type" "leave")])
13834 \f
13835 (define_expand "ffssi2"
13836   [(parallel
13837      [(set (match_operand:SI 0 "register_operand" "") 
13838            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13839       (clobber (match_scratch:SI 2 ""))
13840       (clobber (reg:CC FLAGS_REG))])]
13841   ""
13842   "")
13843
13844 (define_insn_and_split "*ffs_cmove"
13845   [(set (match_operand:SI 0 "register_operand" "=r") 
13846         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13847    (clobber (match_scratch:SI 2 "=&r"))
13848    (clobber (reg:CC FLAGS_REG))]
13849   "TARGET_CMOVE"
13850   "#"
13851   "&& reload_completed"
13852   [(set (match_dup 2) (const_int -1))
13853    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13854               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13855    (set (match_dup 0) (if_then_else:SI
13856                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13857                         (match_dup 2)
13858                         (match_dup 0)))
13859    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13860               (clobber (reg:CC FLAGS_REG))])]
13861   "")
13862
13863 (define_insn_and_split "*ffs_no_cmove"
13864   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13865         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13866    (clobber (match_scratch:SI 2 "=&q"))
13867    (clobber (reg:CC FLAGS_REG))]
13868   ""
13869   "#"
13870   "reload_completed"
13871   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13872               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13873    (set (strict_low_part (match_dup 3))
13874         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13875    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13876               (clobber (reg:CC FLAGS_REG))])
13877    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13878               (clobber (reg:CC FLAGS_REG))])
13879    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13880               (clobber (reg:CC FLAGS_REG))])]
13881 {
13882   operands[3] = gen_lowpart (QImode, operands[2]);
13883   ix86_expand_clear (operands[2]);
13884 })
13885
13886 (define_insn "*ffssi_1"
13887   [(set (reg:CCZ FLAGS_REG)
13888         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13889                      (const_int 0)))
13890    (set (match_operand:SI 0 "register_operand" "=r")
13891         (ctz:SI (match_dup 1)))]
13892   ""
13893   "bsf{l}\t{%1, %0|%0, %1}"
13894   [(set_attr "prefix_0f" "1")])
13895
13896 (define_expand "ffsdi2"
13897   [(parallel
13898      [(set (match_operand:DI 0 "register_operand" "") 
13899            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13900       (clobber (match_scratch:DI 2 ""))
13901       (clobber (reg:CC FLAGS_REG))])]
13902   "TARGET_64BIT && TARGET_CMOVE"
13903   "")
13904
13905 (define_insn_and_split "*ffs_rex64"
13906   [(set (match_operand:DI 0 "register_operand" "=r") 
13907         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13908    (clobber (match_scratch:DI 2 "=&r"))
13909    (clobber (reg:CC FLAGS_REG))]
13910   "TARGET_64BIT && TARGET_CMOVE"
13911   "#"
13912   "&& reload_completed"
13913   [(set (match_dup 2) (const_int -1))
13914    (parallel [(set (reg:CCZ FLAGS_REG)
13915                    (compare:CCZ (match_dup 1) (const_int 0)))
13916               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13917    (set (match_dup 0) (if_then_else:DI
13918                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13919                         (match_dup 2)
13920                         (match_dup 0)))
13921    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13922               (clobber (reg:CC FLAGS_REG))])]
13923   "")
13924
13925 (define_insn "*ffsdi_1"
13926   [(set (reg:CCZ FLAGS_REG)
13927         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13928                      (const_int 0)))
13929    (set (match_operand:DI 0 "register_operand" "=r")
13930         (ctz:DI (match_dup 1)))]
13931   "TARGET_64BIT"
13932   "bsf{q}\t{%1, %0|%0, %1}"
13933   [(set_attr "prefix_0f" "1")])
13934
13935 (define_insn "ctzsi2"
13936   [(set (match_operand:SI 0 "register_operand" "=r")
13937         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13938    (clobber (reg:CC FLAGS_REG))]
13939   ""
13940   "bsf{l}\t{%1, %0|%0, %1}"
13941   [(set_attr "prefix_0f" "1")])
13942
13943 (define_insn "ctzdi2"
13944   [(set (match_operand:DI 0 "register_operand" "=r")
13945         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13946    (clobber (reg:CC FLAGS_REG))]
13947   "TARGET_64BIT"
13948   "bsf{q}\t{%1, %0|%0, %1}"
13949   [(set_attr "prefix_0f" "1")])
13950
13951 (define_expand "clzsi2"
13952   [(parallel
13953      [(set (match_operand:SI 0 "register_operand" "")
13954            (minus:SI (const_int 31)
13955                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13956       (clobber (reg:CC FLAGS_REG))])
13957    (parallel
13958      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13959       (clobber (reg:CC FLAGS_REG))])]
13960   ""
13961   "")
13962
13963 (define_insn "*bsr"
13964   [(set (match_operand:SI 0 "register_operand" "=r")
13965         (minus:SI (const_int 31)
13966                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13967    (clobber (reg:CC FLAGS_REG))]
13968   ""
13969   "bsr{l}\t{%1, %0|%0, %1}"
13970   [(set_attr "prefix_0f" "1")])
13971
13972 (define_expand "clzdi2"
13973   [(parallel
13974      [(set (match_operand:DI 0 "register_operand" "")
13975            (minus:DI (const_int 63)
13976                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13977       (clobber (reg:CC FLAGS_REG))])
13978    (parallel
13979      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13980       (clobber (reg:CC FLAGS_REG))])]
13981   "TARGET_64BIT"
13982   "")
13983
13984 (define_insn "*bsr_rex64"
13985   [(set (match_operand:DI 0 "register_operand" "=r")
13986         (minus:DI (const_int 63)
13987                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13988    (clobber (reg:CC FLAGS_REG))]
13989   "TARGET_64BIT"
13990   "bsr{q}\t{%1, %0|%0, %1}"
13991   [(set_attr "prefix_0f" "1")])
13992 \f
13993 ;; Thread-local storage patterns for ELF.
13994 ;;
13995 ;; Note that these code sequences must appear exactly as shown
13996 ;; in order to allow linker relaxation.
13997
13998 (define_insn "*tls_global_dynamic_32_gnu"
13999   [(set (match_operand:SI 0 "register_operand" "=a")
14000         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14001                     (match_operand:SI 2 "tls_symbolic_operand" "")
14002                     (match_operand:SI 3 "call_insn_operand" "")]
14003                     UNSPEC_TLS_GD))
14004    (clobber (match_scratch:SI 4 "=d"))
14005    (clobber (match_scratch:SI 5 "=c"))
14006    (clobber (reg:CC FLAGS_REG))]
14007   "!TARGET_64BIT && TARGET_GNU_TLS"
14008   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14009   [(set_attr "type" "multi")
14010    (set_attr "length" "12")])
14011
14012 (define_insn "*tls_global_dynamic_32_sun"
14013   [(set (match_operand:SI 0 "register_operand" "=a")
14014         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14015                     (match_operand:SI 2 "tls_symbolic_operand" "")
14016                     (match_operand:SI 3 "call_insn_operand" "")]
14017                     UNSPEC_TLS_GD))
14018    (clobber (match_scratch:SI 4 "=d"))
14019    (clobber (match_scratch:SI 5 "=c"))
14020    (clobber (reg:CC FLAGS_REG))]
14021   "!TARGET_64BIT && TARGET_SUN_TLS"
14022   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14023         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14024   [(set_attr "type" "multi")
14025    (set_attr "length" "14")])
14026
14027 (define_expand "tls_global_dynamic_32"
14028   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14029                    (unspec:SI
14030                     [(match_dup 2)
14031                      (match_operand:SI 1 "tls_symbolic_operand" "")
14032                      (match_dup 3)]
14033                     UNSPEC_TLS_GD))
14034               (clobber (match_scratch:SI 4 ""))
14035               (clobber (match_scratch:SI 5 ""))
14036               (clobber (reg:CC FLAGS_REG))])]
14037   ""
14038 {
14039   if (flag_pic)
14040     operands[2] = pic_offset_table_rtx;
14041   else
14042     {
14043       operands[2] = gen_reg_rtx (Pmode);
14044       emit_insn (gen_set_got (operands[2]));
14045     }
14046   operands[3] = ix86_tls_get_addr ();
14047 })
14048
14049 (define_insn "*tls_global_dynamic_64"
14050   [(set (match_operand:DI 0 "register_operand" "=a")
14051         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14052                       (match_operand:DI 3 "" "")))
14053    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14054               UNSPEC_TLS_GD)]
14055   "TARGET_64BIT"
14056   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14057   [(set_attr "type" "multi")
14058    (set_attr "length" "16")])
14059
14060 (define_expand "tls_global_dynamic_64"
14061   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14062                    (call (mem:QI (match_dup 2)) (const_int 0)))
14063               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14064                          UNSPEC_TLS_GD)])]
14065   ""
14066 {
14067   operands[2] = ix86_tls_get_addr ();
14068 })
14069
14070 (define_insn "*tls_local_dynamic_base_32_gnu"
14071   [(set (match_operand:SI 0 "register_operand" "=a")
14072         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14073                     (match_operand:SI 2 "call_insn_operand" "")]
14074                    UNSPEC_TLS_LD_BASE))
14075    (clobber (match_scratch:SI 3 "=d"))
14076    (clobber (match_scratch:SI 4 "=c"))
14077    (clobber (reg:CC FLAGS_REG))]
14078   "!TARGET_64BIT && TARGET_GNU_TLS"
14079   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14080   [(set_attr "type" "multi")
14081    (set_attr "length" "11")])
14082
14083 (define_insn "*tls_local_dynamic_base_32_sun"
14084   [(set (match_operand:SI 0 "register_operand" "=a")
14085         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14086                     (match_operand:SI 2 "call_insn_operand" "")]
14087                    UNSPEC_TLS_LD_BASE))
14088    (clobber (match_scratch:SI 3 "=d"))
14089    (clobber (match_scratch:SI 4 "=c"))
14090    (clobber (reg:CC FLAGS_REG))]
14091   "!TARGET_64BIT && TARGET_SUN_TLS"
14092   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14093         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14094   [(set_attr "type" "multi")
14095    (set_attr "length" "13")])
14096
14097 (define_expand "tls_local_dynamic_base_32"
14098   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14099                    (unspec:SI [(match_dup 1) (match_dup 2)]
14100                               UNSPEC_TLS_LD_BASE))
14101               (clobber (match_scratch:SI 3 ""))
14102               (clobber (match_scratch:SI 4 ""))
14103               (clobber (reg:CC FLAGS_REG))])]
14104   ""
14105 {
14106   if (flag_pic)
14107     operands[1] = pic_offset_table_rtx;
14108   else
14109     {
14110       operands[1] = gen_reg_rtx (Pmode);
14111       emit_insn (gen_set_got (operands[1]));
14112     }
14113   operands[2] = ix86_tls_get_addr ();
14114 })
14115
14116 (define_insn "*tls_local_dynamic_base_64"
14117   [(set (match_operand:DI 0 "register_operand" "=a")
14118         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14119                       (match_operand:DI 2 "" "")))
14120    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14121   "TARGET_64BIT"
14122   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14123   [(set_attr "type" "multi")
14124    (set_attr "length" "12")])
14125
14126 (define_expand "tls_local_dynamic_base_64"
14127   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14128                    (call (mem:QI (match_dup 1)) (const_int 0)))
14129               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14130   ""
14131 {
14132   operands[1] = ix86_tls_get_addr ();
14133 })
14134
14135 ;; Local dynamic of a single variable is a lose.  Show combine how
14136 ;; to convert that back to global dynamic.
14137
14138 (define_insn_and_split "*tls_local_dynamic_32_once"
14139   [(set (match_operand:SI 0 "register_operand" "=a")
14140         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14141                              (match_operand:SI 2 "call_insn_operand" "")]
14142                             UNSPEC_TLS_LD_BASE)
14143                  (const:SI (unspec:SI
14144                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14145                             UNSPEC_DTPOFF))))
14146    (clobber (match_scratch:SI 4 "=d"))
14147    (clobber (match_scratch:SI 5 "=c"))
14148    (clobber (reg:CC FLAGS_REG))]
14149   ""
14150   "#"
14151   ""
14152   [(parallel [(set (match_dup 0)
14153                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14154                               UNSPEC_TLS_GD))
14155               (clobber (match_dup 4))
14156               (clobber (match_dup 5))
14157               (clobber (reg:CC FLAGS_REG))])]
14158   "")
14159
14160 ;; Load and add the thread base pointer from %gs:0.
14161
14162 (define_insn "*load_tp_si"
14163   [(set (match_operand:SI 0 "register_operand" "=r")
14164         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14165   "!TARGET_64BIT"
14166   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14167   [(set_attr "type" "imov")
14168    (set_attr "modrm" "0")
14169    (set_attr "length" "7")
14170    (set_attr "memory" "load")
14171    (set_attr "imm_disp" "false")])
14172
14173 (define_insn "*add_tp_si"
14174   [(set (match_operand:SI 0 "register_operand" "=r")
14175         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14176                  (match_operand:SI 1 "register_operand" "0")))
14177    (clobber (reg:CC FLAGS_REG))]
14178   "!TARGET_64BIT"
14179   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14180   [(set_attr "type" "alu")
14181    (set_attr "modrm" "0")
14182    (set_attr "length" "7")
14183    (set_attr "memory" "load")
14184    (set_attr "imm_disp" "false")])
14185
14186 (define_insn "*load_tp_di"
14187   [(set (match_operand:DI 0 "register_operand" "=r")
14188         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14189   "TARGET_64BIT"
14190   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14191   [(set_attr "type" "imov")
14192    (set_attr "modrm" "0")
14193    (set_attr "length" "7")
14194    (set_attr "memory" "load")
14195    (set_attr "imm_disp" "false")])
14196
14197 (define_insn "*add_tp_di"
14198   [(set (match_operand:DI 0 "register_operand" "=r")
14199         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14200                  (match_operand:DI 1 "register_operand" "0")))
14201    (clobber (reg:CC FLAGS_REG))]
14202   "TARGET_64BIT"
14203   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14204   [(set_attr "type" "alu")
14205    (set_attr "modrm" "0")
14206    (set_attr "length" "7")
14207    (set_attr "memory" "load")
14208    (set_attr "imm_disp" "false")])
14209 \f
14210 ;; These patterns match the binary 387 instructions for addM3, subM3,
14211 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14212 ;; SFmode.  The first is the normal insn, the second the same insn but
14213 ;; with one operand a conversion, and the third the same insn but with
14214 ;; the other operand a conversion.  The conversion may be SFmode or
14215 ;; SImode if the target mode DFmode, but only SImode if the target mode
14216 ;; is SFmode.
14217
14218 ;; Gcc is slightly more smart about handling normal two address instructions
14219 ;; so use special patterns for add and mull.
14220
14221 (define_insn "*fop_sf_comm_mixed"
14222   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14223         (match_operator:SF 3 "binary_fp_operator"
14224                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14225                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14226   "TARGET_MIX_SSE_I387
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 (eq_attr "alternative" "1")
14232            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14233               (const_string "ssemul")
14234               (const_string "sseadd"))
14235            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14236               (const_string "fmul")
14237               (const_string "fop"))))
14238    (set_attr "mode" "SF")])
14239
14240 (define_insn "*fop_sf_comm_sse"
14241   [(set (match_operand:SF 0 "register_operand" "=x")
14242         (match_operator:SF 3 "binary_fp_operator"
14243                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14244                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14245   "TARGET_SSE_MATH
14246    && COMMUTATIVE_ARITH_P (operands[3])
14247    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14248   "* return output_387_binary_op (insn, operands);"
14249   [(set (attr "type") 
14250         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14251            (const_string "ssemul")
14252            (const_string "sseadd")))
14253    (set_attr "mode" "SF")])
14254
14255 (define_insn "*fop_sf_comm_i387"
14256   [(set (match_operand:SF 0 "register_operand" "=f")
14257         (match_operator:SF 3 "binary_fp_operator"
14258                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14259                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14260   "TARGET_80387
14261    && COMMUTATIVE_ARITH_P (operands[3])
14262    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14263   "* return output_387_binary_op (insn, operands);"
14264   [(set (attr "type") 
14265         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14266            (const_string "fmul")
14267            (const_string "fop")))
14268    (set_attr "mode" "SF")])
14269
14270 (define_insn "*fop_sf_1_mixed"
14271   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14272         (match_operator:SF 3 "binary_fp_operator"
14273                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14274                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14275   "TARGET_MIX_SSE_I387
14276    && !COMMUTATIVE_ARITH_P (operands[3])
14277    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14278   "* return output_387_binary_op (insn, operands);"
14279   [(set (attr "type") 
14280         (cond [(and (eq_attr "alternative" "2")
14281                     (match_operand:SF 3 "mult_operator" ""))
14282                  (const_string "ssemul")
14283                (and (eq_attr "alternative" "2")
14284                     (match_operand:SF 3 "div_operator" ""))
14285                  (const_string "ssediv")
14286                (eq_attr "alternative" "2")
14287                  (const_string "sseadd")
14288                (match_operand:SF 3 "mult_operator" "") 
14289                  (const_string "fmul")
14290                (match_operand:SF 3 "div_operator" "") 
14291                  (const_string "fdiv")
14292               ]
14293               (const_string "fop")))
14294    (set_attr "mode" "SF")])
14295
14296 (define_insn "*fop_sf_1_sse"
14297   [(set (match_operand:SF 0 "register_operand" "=x")
14298         (match_operator:SF 3 "binary_fp_operator"
14299                         [(match_operand:SF 1 "register_operand" "0")
14300                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14301   "TARGET_SSE_MATH
14302    && !COMMUTATIVE_ARITH_P (operands[3])"
14303   "* return output_387_binary_op (insn, operands);"
14304   [(set (attr "type") 
14305         (cond [(match_operand:SF 3 "mult_operator" "")
14306                  (const_string "ssemul")
14307                (match_operand:SF 3 "div_operator" "")
14308                  (const_string "ssediv")
14309               ]
14310               (const_string "sseadd")))
14311    (set_attr "mode" "SF")])
14312
14313 (define_insn "*fop_sf_1_i387"
14314   [(set (match_operand:SF 0 "register_operand" "=f,f")
14315         (match_operator:SF 3 "binary_fp_operator"
14316                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14317                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14318   "TARGET_80387
14319    && !COMMUTATIVE_ARITH_P (operands[3])
14320    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14321   "* return output_387_binary_op (insn, operands);"
14322   [(set (attr "type") 
14323         (cond [(match_operand:SF 3 "mult_operator" "") 
14324                  (const_string "fmul")
14325                (match_operand:SF 3 "div_operator" "") 
14326                  (const_string "fdiv")
14327               ]
14328               (const_string "fop")))
14329    (set_attr "mode" "SF")])
14330
14331
14332 ;; ??? Add SSE splitters for these!
14333 (define_insn "*fop_sf_2_i387"
14334   [(set (match_operand:SF 0 "register_operand" "=f,f")
14335         (match_operator:SF 3 "binary_fp_operator"
14336           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14337            (match_operand:SF 2 "register_operand" "0,0")]))]
14338   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14339   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14340   [(set (attr "type") 
14341         (cond [(match_operand:SF 3 "mult_operator" "") 
14342                  (const_string "fmul")
14343                (match_operand:SF 3 "div_operator" "") 
14344                  (const_string "fdiv")
14345               ]
14346               (const_string "fop")))
14347    (set_attr "fp_int_src" "true")
14348    (set_attr "mode" "SI")])
14349
14350 (define_insn "*fop_sf_3_i387"
14351   [(set (match_operand:SF 0 "register_operand" "=f,f")
14352         (match_operator:SF 3 "binary_fp_operator"
14353           [(match_operand:SF 1 "register_operand" "0,0")
14354            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14355   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14356   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14357   [(set (attr "type") 
14358         (cond [(match_operand:SF 3 "mult_operator" "") 
14359                  (const_string "fmul")
14360                (match_operand:SF 3 "div_operator" "") 
14361                  (const_string "fdiv")
14362               ]
14363               (const_string "fop")))
14364    (set_attr "fp_int_src" "true")
14365    (set_attr "mode" "SI")])
14366
14367 (define_insn "*fop_df_comm_mixed"
14368   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14369         (match_operator:DF 3 "binary_fp_operator"
14370                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14371                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14372   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14373    && COMMUTATIVE_ARITH_P (operands[3])
14374    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14375   "* return output_387_binary_op (insn, operands);"
14376   [(set (attr "type") 
14377         (if_then_else (eq_attr "alternative" "1")
14378            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14379               (const_string "ssemul")
14380               (const_string "sseadd"))
14381            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14382               (const_string "fmul")
14383               (const_string "fop"))))
14384    (set_attr "mode" "DF")])
14385
14386 (define_insn "*fop_df_comm_sse"
14387   [(set (match_operand:DF 0 "register_operand" "=Y")
14388         (match_operator:DF 3 "binary_fp_operator"
14389                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14390                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14391   "TARGET_SSE2 && TARGET_SSE_MATH
14392    && COMMUTATIVE_ARITH_P (operands[3])
14393    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14394   "* return output_387_binary_op (insn, operands);"
14395   [(set (attr "type") 
14396         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14397            (const_string "ssemul")
14398            (const_string "sseadd")))
14399    (set_attr "mode" "DF")])
14400
14401 (define_insn "*fop_df_comm_i387"
14402   [(set (match_operand:DF 0 "register_operand" "=f")
14403         (match_operator:DF 3 "binary_fp_operator"
14404                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14405                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14406   "TARGET_80387
14407    && COMMUTATIVE_ARITH_P (operands[3])
14408    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14409   "* return output_387_binary_op (insn, operands);"
14410   [(set (attr "type") 
14411         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14412            (const_string "fmul")
14413            (const_string "fop")))
14414    (set_attr "mode" "DF")])
14415
14416 (define_insn "*fop_df_1_mixed"
14417   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14418         (match_operator:DF 3 "binary_fp_operator"
14419                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14420                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14421   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14422    && !COMMUTATIVE_ARITH_P (operands[3])
14423    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14424   "* return output_387_binary_op (insn, operands);"
14425   [(set (attr "type") 
14426         (cond [(and (eq_attr "alternative" "2")
14427                     (match_operand:SF 3 "mult_operator" ""))
14428                  (const_string "ssemul")
14429                (and (eq_attr "alternative" "2")
14430                     (match_operand:SF 3 "div_operator" ""))
14431                  (const_string "ssediv")
14432                (eq_attr "alternative" "2")
14433                  (const_string "sseadd")
14434                (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 "mode" "DF")])
14441
14442 (define_insn "*fop_df_1_sse"
14443   [(set (match_operand:DF 0 "register_operand" "=Y")
14444         (match_operator:DF 3 "binary_fp_operator"
14445                         [(match_operand:DF 1 "register_operand" "0")
14446                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14447   "TARGET_SSE2 && TARGET_SSE_MATH
14448    && !COMMUTATIVE_ARITH_P (operands[3])"
14449   "* return output_387_binary_op (insn, operands);"
14450   [(set_attr "mode" "DF")
14451    (set (attr "type") 
14452         (cond [(match_operand:SF 3 "mult_operator" "")
14453                  (const_string "ssemul")
14454                (match_operand:SF 3 "div_operator" "")
14455                  (const_string "ssediv")
14456               ]
14457               (const_string "sseadd")))])
14458
14459 (define_insn "*fop_df_1_i387"
14460   [(set (match_operand:DF 0 "register_operand" "=f,f")
14461         (match_operator:DF 3 "binary_fp_operator"
14462                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14463                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14464   "TARGET_80387
14465    && !COMMUTATIVE_ARITH_P (operands[3])
14466    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
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" "DF")])
14476
14477 ;; ??? Add SSE splitters for these!
14478 (define_insn "*fop_df_2_i387"
14479   [(set (match_operand:DF 0 "register_operand" "=f,f")
14480         (match_operator:DF 3 "binary_fp_operator"
14481            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14482             (match_operand:DF 2 "register_operand" "0,0")]))]
14483   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14484   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14485   [(set (attr "type") 
14486         (cond [(match_operand:DF 3 "mult_operator" "") 
14487                  (const_string "fmul")
14488                (match_operand:DF 3 "div_operator" "") 
14489                  (const_string "fdiv")
14490               ]
14491               (const_string "fop")))
14492    (set_attr "fp_int_src" "true")
14493    (set_attr "mode" "SI")])
14494
14495 (define_insn "*fop_df_3_i387"
14496   [(set (match_operand:DF 0 "register_operand" "=f,f")
14497         (match_operator:DF 3 "binary_fp_operator"
14498            [(match_operand:DF 1 "register_operand" "0,0")
14499             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14500   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14501   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14502   [(set (attr "type") 
14503         (cond [(match_operand:DF 3 "mult_operator" "") 
14504                  (const_string "fmul")
14505                (match_operand:DF 3 "div_operator" "") 
14506                  (const_string "fdiv")
14507               ]
14508               (const_string "fop")))
14509    (set_attr "fp_int_src" "true")
14510    (set_attr "mode" "SI")])
14511
14512 (define_insn "*fop_df_4_i387"
14513   [(set (match_operand:DF 0 "register_operand" "=f,f")
14514         (match_operator:DF 3 "binary_fp_operator"
14515            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14516             (match_operand:DF 2 "register_operand" "0,f")]))]
14517   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14518    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14519   "* return output_387_binary_op (insn, operands);"
14520   [(set (attr "type") 
14521         (cond [(match_operand:DF 3 "mult_operator" "") 
14522                  (const_string "fmul")
14523                (match_operand:DF 3 "div_operator" "") 
14524                  (const_string "fdiv")
14525               ]
14526               (const_string "fop")))
14527    (set_attr "mode" "SF")])
14528
14529 (define_insn "*fop_df_5_i387"
14530   [(set (match_operand:DF 0 "register_operand" "=f,f")
14531         (match_operator:DF 3 "binary_fp_operator"
14532           [(match_operand:DF 1 "register_operand" "0,f")
14533            (float_extend:DF
14534             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14535   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14536   "* return output_387_binary_op (insn, operands);"
14537   [(set (attr "type") 
14538         (cond [(match_operand:DF 3 "mult_operator" "") 
14539                  (const_string "fmul")
14540                (match_operand:DF 3 "div_operator" "") 
14541                  (const_string "fdiv")
14542               ]
14543               (const_string "fop")))
14544    (set_attr "mode" "SF")])
14545
14546 (define_insn "*fop_df_6_i387"
14547   [(set (match_operand:DF 0 "register_operand" "=f,f")
14548         (match_operator:DF 3 "binary_fp_operator"
14549           [(float_extend:DF
14550             (match_operand:SF 1 "register_operand" "0,f"))
14551            (float_extend:DF
14552             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14553   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14554   "* return output_387_binary_op (insn, operands);"
14555   [(set (attr "type") 
14556         (cond [(match_operand:DF 3 "mult_operator" "") 
14557                  (const_string "fmul")
14558                (match_operand:DF 3 "div_operator" "") 
14559                  (const_string "fdiv")
14560               ]
14561               (const_string "fop")))
14562    (set_attr "mode" "SF")])
14563
14564 (define_insn "*fop_xf_comm_i387"
14565   [(set (match_operand:XF 0 "register_operand" "=f")
14566         (match_operator:XF 3 "binary_fp_operator"
14567                         [(match_operand:XF 1 "register_operand" "%0")
14568                          (match_operand:XF 2 "register_operand" "f")]))]
14569   "TARGET_80387
14570    && COMMUTATIVE_ARITH_P (operands[3])"
14571   "* return output_387_binary_op (insn, operands);"
14572   [(set (attr "type") 
14573         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14574            (const_string "fmul")
14575            (const_string "fop")))
14576    (set_attr "mode" "XF")])
14577
14578 (define_insn "*fop_xf_1_i387"
14579   [(set (match_operand:XF 0 "register_operand" "=f,f")
14580         (match_operator:XF 3 "binary_fp_operator"
14581                         [(match_operand:XF 1 "register_operand" "0,f")
14582                          (match_operand:XF 2 "register_operand" "f,0")]))]
14583   "TARGET_80387
14584    && !COMMUTATIVE_ARITH_P (operands[3])"
14585   "* return output_387_binary_op (insn, operands);"
14586   [(set (attr "type") 
14587         (cond [(match_operand:XF 3 "mult_operator" "") 
14588                  (const_string "fmul")
14589                (match_operand:XF 3 "div_operator" "") 
14590                  (const_string "fdiv")
14591               ]
14592               (const_string "fop")))
14593    (set_attr "mode" "XF")])
14594
14595 (define_insn "*fop_xf_2_i387"
14596   [(set (match_operand:XF 0 "register_operand" "=f,f")
14597         (match_operator:XF 3 "binary_fp_operator"
14598            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14599             (match_operand:XF 2 "register_operand" "0,0")]))]
14600   "TARGET_80387 && TARGET_USE_FIOP"
14601   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14602   [(set (attr "type") 
14603         (cond [(match_operand:XF 3 "mult_operator" "") 
14604                  (const_string "fmul")
14605                (match_operand:XF 3 "div_operator" "") 
14606                  (const_string "fdiv")
14607               ]
14608               (const_string "fop")))
14609    (set_attr "fp_int_src" "true")
14610    (set_attr "mode" "SI")])
14611
14612 (define_insn "*fop_xf_3_i387"
14613   [(set (match_operand:XF 0 "register_operand" "=f,f")
14614         (match_operator:XF 3 "binary_fp_operator"
14615           [(match_operand:XF 1 "register_operand" "0,0")
14616            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14617   "TARGET_80387 && TARGET_USE_FIOP"
14618   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14619   [(set (attr "type") 
14620         (cond [(match_operand:XF 3 "mult_operator" "") 
14621                  (const_string "fmul")
14622                (match_operand:XF 3 "div_operator" "") 
14623                  (const_string "fdiv")
14624               ]
14625               (const_string "fop")))
14626    (set_attr "fp_int_src" "true")
14627    (set_attr "mode" "SI")])
14628
14629 (define_insn "*fop_xf_4_i387"
14630   [(set (match_operand:XF 0 "register_operand" "=f,f")
14631         (match_operator:XF 3 "binary_fp_operator"
14632            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14633             (match_operand:XF 2 "register_operand" "0,f")]))]
14634   "TARGET_80387"
14635   "* return output_387_binary_op (insn, operands);"
14636   [(set (attr "type") 
14637         (cond [(match_operand:XF 3 "mult_operator" "") 
14638                  (const_string "fmul")
14639                (match_operand:XF 3 "div_operator" "") 
14640                  (const_string "fdiv")
14641               ]
14642               (const_string "fop")))
14643    (set_attr "mode" "SF")])
14644
14645 (define_insn "*fop_xf_5_i387"
14646   [(set (match_operand:XF 0 "register_operand" "=f,f")
14647         (match_operator:XF 3 "binary_fp_operator"
14648           [(match_operand:XF 1 "register_operand" "0,f")
14649            (float_extend:XF
14650             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14651   "TARGET_80387"
14652   "* return output_387_binary_op (insn, operands);"
14653   [(set (attr "type") 
14654         (cond [(match_operand:XF 3 "mult_operator" "") 
14655                  (const_string "fmul")
14656                (match_operand:XF 3 "div_operator" "") 
14657                  (const_string "fdiv")
14658               ]
14659               (const_string "fop")))
14660    (set_attr "mode" "SF")])
14661
14662 (define_insn "*fop_xf_6_i387"
14663   [(set (match_operand:XF 0 "register_operand" "=f,f")
14664         (match_operator:XF 3 "binary_fp_operator"
14665           [(float_extend:XF
14666             (match_operand 1 "register_operand" "0,f"))
14667            (float_extend:XF
14668             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14669   "TARGET_80387"
14670   "* return output_387_binary_op (insn, operands);"
14671   [(set (attr "type") 
14672         (cond [(match_operand:XF 3 "mult_operator" "") 
14673                  (const_string "fmul")
14674                (match_operand:XF 3 "div_operator" "") 
14675                  (const_string "fdiv")
14676               ]
14677               (const_string "fop")))
14678    (set_attr "mode" "SF")])
14679
14680 (define_split
14681   [(set (match_operand 0 "register_operand" "")
14682         (match_operator 3 "binary_fp_operator"
14683            [(float (match_operand:SI 1 "register_operand" ""))
14684             (match_operand 2 "register_operand" "")]))]
14685   "TARGET_80387 && reload_completed
14686    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14687   [(const_int 0)]
14688
14689   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14690   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14691   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14692                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14693                                           GET_MODE (operands[3]),
14694                                           operands[4],
14695                                           operands[2])));
14696   ix86_free_from_memory (GET_MODE (operands[1]));
14697   DONE;
14698 })
14699
14700 (define_split
14701   [(set (match_operand 0 "register_operand" "")
14702         (match_operator 3 "binary_fp_operator"
14703            [(match_operand 1 "register_operand" "")
14704             (float (match_operand:SI 2 "register_operand" ""))]))]
14705   "TARGET_80387 && reload_completed
14706    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14707   [(const_int 0)]
14708 {
14709   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14710   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14711   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14712                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14713                                           GET_MODE (operands[3]),
14714                                           operands[1],
14715                                           operands[4])));
14716   ix86_free_from_memory (GET_MODE (operands[2]));
14717   DONE;
14718 })
14719 \f
14720 ;; FPU special functions.
14721
14722 (define_expand "sqrtsf2"
14723   [(set (match_operand:SF 0 "register_operand" "")
14724         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14725   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14726 {
14727   if (!TARGET_SSE_MATH)
14728     operands[1] = force_reg (SFmode, operands[1]);
14729 })
14730
14731 (define_insn "*sqrtsf2_mixed"
14732   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14733         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14734   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14735   "@
14736    fsqrt
14737    sqrtss\t{%1, %0|%0, %1}"
14738   [(set_attr "type" "fpspc,sse")
14739    (set_attr "mode" "SF,SF")
14740    (set_attr "athlon_decode" "direct,*")])
14741
14742 (define_insn "*sqrtsf2_sse"
14743   [(set (match_operand:SF 0 "register_operand" "=x")
14744         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14745   "TARGET_SSE_MATH"
14746   "sqrtss\t{%1, %0|%0, %1}"
14747   [(set_attr "type" "sse")
14748    (set_attr "mode" "SF")
14749    (set_attr "athlon_decode" "*")])
14750
14751 (define_insn "*sqrtsf2_i387"
14752   [(set (match_operand:SF 0 "register_operand" "=f")
14753         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14754   "TARGET_USE_FANCY_MATH_387"
14755   "fsqrt"
14756   [(set_attr "type" "fpspc")
14757    (set_attr "mode" "SF")
14758    (set_attr "athlon_decode" "direct")])
14759
14760 (define_expand "sqrtdf2"
14761   [(set (match_operand:DF 0 "register_operand" "")
14762         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14763   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14764 {
14765   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14766     operands[1] = force_reg (DFmode, operands[1]);
14767 })
14768
14769 (define_insn "*sqrtdf2_mixed"
14770   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14771         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14772   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14773   "@
14774    fsqrt
14775    sqrtsd\t{%1, %0|%0, %1}"
14776   [(set_attr "type" "fpspc,sse")
14777    (set_attr "mode" "DF,DF")
14778    (set_attr "athlon_decode" "direct,*")])
14779
14780 (define_insn "*sqrtdf2_sse"
14781   [(set (match_operand:DF 0 "register_operand" "=Y")
14782         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14783   "TARGET_SSE2 && TARGET_SSE_MATH"
14784   "sqrtsd\t{%1, %0|%0, %1}"
14785   [(set_attr "type" "sse")
14786    (set_attr "mode" "DF")
14787    (set_attr "athlon_decode" "*")])
14788
14789 (define_insn "*sqrtdf2_i387"
14790   [(set (match_operand:DF 0 "register_operand" "=f")
14791         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14792   "TARGET_USE_FANCY_MATH_387"
14793   "fsqrt"
14794   [(set_attr "type" "fpspc")
14795    (set_attr "mode" "DF")
14796    (set_attr "athlon_decode" "direct")])
14797
14798 (define_insn "*sqrtextendsfdf2_i387"
14799   [(set (match_operand:DF 0 "register_operand" "=f")
14800         (sqrt:DF (float_extend:DF
14801                   (match_operand:SF 1 "register_operand" "0"))))]
14802   "TARGET_USE_FANCY_MATH_387
14803    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14804   "fsqrt"
14805   [(set_attr "type" "fpspc")
14806    (set_attr "mode" "DF")
14807    (set_attr "athlon_decode" "direct")])
14808
14809 (define_insn "sqrtxf2"
14810   [(set (match_operand:XF 0 "register_operand" "=f")
14811         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14812   "TARGET_USE_FANCY_MATH_387 
14813    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14814   "fsqrt"
14815   [(set_attr "type" "fpspc")
14816    (set_attr "mode" "XF")
14817    (set_attr "athlon_decode" "direct")])
14818
14819 (define_insn "*sqrtextendsfxf2_i387"
14820   [(set (match_operand:XF 0 "register_operand" "=f")
14821         (sqrt:XF (float_extend:XF
14822                   (match_operand:SF 1 "register_operand" "0"))))]
14823   "TARGET_USE_FANCY_MATH_387"
14824   "fsqrt"
14825   [(set_attr "type" "fpspc")
14826    (set_attr "mode" "XF")
14827    (set_attr "athlon_decode" "direct")])
14828
14829 (define_insn "*sqrtextenddfxf2_i387"
14830   [(set (match_operand:XF 0 "register_operand" "=f")
14831         (sqrt:XF (float_extend:XF
14832                   (match_operand:DF 1 "register_operand" "0"))))]
14833   "TARGET_USE_FANCY_MATH_387"
14834   "fsqrt"
14835   [(set_attr "type" "fpspc")
14836    (set_attr "mode" "XF")
14837    (set_attr "athlon_decode" "direct")])
14838
14839 (define_insn "fpremxf4"
14840   [(set (match_operand:XF 0 "register_operand" "=f")
14841         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14842                     (match_operand:XF 3 "register_operand" "1")]
14843                    UNSPEC_FPREM_F))
14844    (set (match_operand:XF 1 "register_operand" "=u")
14845         (unspec:XF [(match_dup 2) (match_dup 3)]
14846                    UNSPEC_FPREM_U))
14847    (set (reg:CCFP FPSR_REG)
14848         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14849   "TARGET_USE_FANCY_MATH_387
14850    && flag_unsafe_math_optimizations"
14851   "fprem"
14852   [(set_attr "type" "fpspc")
14853    (set_attr "mode" "XF")])
14854
14855 (define_expand "fmodsf3"
14856   [(use (match_operand:SF 0 "register_operand" ""))
14857    (use (match_operand:SF 1 "register_operand" ""))
14858    (use (match_operand:SF 2 "register_operand" ""))]
14859   "TARGET_USE_FANCY_MATH_387
14860    && flag_unsafe_math_optimizations"
14861 {
14862   rtx label = gen_label_rtx ();
14863
14864   rtx op1 = gen_reg_rtx (XFmode);
14865   rtx op2 = gen_reg_rtx (XFmode);
14866
14867   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14868   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14869
14870   emit_label (label);
14871
14872   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14873   ix86_emit_fp_unordered_jump (label);
14874
14875   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
14876   DONE;
14877 })
14878
14879 (define_expand "fmoddf3"
14880   [(use (match_operand:DF 0 "register_operand" ""))
14881    (use (match_operand:DF 1 "register_operand" ""))
14882    (use (match_operand:DF 2 "register_operand" ""))]
14883   "TARGET_USE_FANCY_MATH_387
14884    && flag_unsafe_math_optimizations"
14885 {
14886   rtx label = gen_label_rtx ();
14887
14888   rtx op1 = gen_reg_rtx (XFmode);
14889   rtx op2 = gen_reg_rtx (XFmode);
14890
14891   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14892   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14893
14894   emit_label (label);
14895
14896   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14897   ix86_emit_fp_unordered_jump (label);
14898
14899   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
14900   DONE;
14901 })
14902
14903 (define_expand "fmodxf3"
14904   [(use (match_operand:XF 0 "register_operand" ""))
14905    (use (match_operand:XF 1 "register_operand" ""))
14906    (use (match_operand:XF 2 "register_operand" ""))]
14907   "TARGET_USE_FANCY_MATH_387
14908    && flag_unsafe_math_optimizations"
14909 {
14910   rtx label = gen_label_rtx ();
14911
14912   emit_label (label);
14913
14914   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14915                            operands[1], operands[2]));
14916   ix86_emit_fp_unordered_jump (label);
14917
14918   emit_move_insn (operands[0], operands[1]);
14919   DONE;
14920 })
14921
14922 (define_insn "fprem1xf4"
14923   [(set (match_operand:XF 0 "register_operand" "=f")
14924         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14925                     (match_operand:XF 3 "register_operand" "1")]
14926                    UNSPEC_FPREM1_F))
14927    (set (match_operand:XF 1 "register_operand" "=u")
14928         (unspec:XF [(match_dup 2) (match_dup 3)]
14929                    UNSPEC_FPREM1_U))
14930    (set (reg:CCFP FPSR_REG)
14931         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14932   "TARGET_USE_FANCY_MATH_387
14933    && flag_unsafe_math_optimizations"
14934   "fprem1"
14935   [(set_attr "type" "fpspc")
14936    (set_attr "mode" "XF")])
14937
14938 (define_expand "dremsf3"
14939   [(use (match_operand:SF 0 "register_operand" ""))
14940    (use (match_operand:SF 1 "register_operand" ""))
14941    (use (match_operand:SF 2 "register_operand" ""))]
14942   "TARGET_USE_FANCY_MATH_387
14943    && flag_unsafe_math_optimizations"
14944 {
14945   rtx label = gen_label_rtx ();
14946
14947   rtx op1 = gen_reg_rtx (XFmode);
14948   rtx op2 = gen_reg_rtx (XFmode);
14949
14950   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14951   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14952
14953   emit_label (label);
14954
14955   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14956   ix86_emit_fp_unordered_jump (label);
14957
14958   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
14959   DONE;
14960 })
14961
14962 (define_expand "dremdf3"
14963   [(use (match_operand:DF 0 "register_operand" ""))
14964    (use (match_operand:DF 1 "register_operand" ""))
14965    (use (match_operand:DF 2 "register_operand" ""))]
14966   "TARGET_USE_FANCY_MATH_387
14967    && flag_unsafe_math_optimizations"
14968 {
14969   rtx label = gen_label_rtx ();
14970
14971   rtx op1 = gen_reg_rtx (XFmode);
14972   rtx op2 = gen_reg_rtx (XFmode);
14973
14974   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14975   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14976
14977   emit_label (label);
14978
14979   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14980   ix86_emit_fp_unordered_jump (label);
14981
14982   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
14983   DONE;
14984 })
14985
14986 (define_expand "dremxf3"
14987   [(use (match_operand:XF 0 "register_operand" ""))
14988    (use (match_operand:XF 1 "register_operand" ""))
14989    (use (match_operand:XF 2 "register_operand" ""))]
14990   "TARGET_USE_FANCY_MATH_387
14991    && flag_unsafe_math_optimizations"
14992 {
14993   rtx label = gen_label_rtx ();
14994
14995   emit_label (label);
14996
14997   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14998                             operands[1], operands[2]));
14999   ix86_emit_fp_unordered_jump (label);
15000
15001   emit_move_insn (operands[0], operands[1]);
15002   DONE;
15003 })
15004
15005 (define_insn "*sindf2"
15006   [(set (match_operand:DF 0 "register_operand" "=f")
15007         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15008   "TARGET_USE_FANCY_MATH_387
15009    && flag_unsafe_math_optimizations"
15010   "fsin"
15011   [(set_attr "type" "fpspc")
15012    (set_attr "mode" "DF")])
15013
15014 (define_insn "*sinsf2"
15015   [(set (match_operand:SF 0 "register_operand" "=f")
15016         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15017   "TARGET_USE_FANCY_MATH_387
15018    && flag_unsafe_math_optimizations"
15019   "fsin"
15020   [(set_attr "type" "fpspc")
15021    (set_attr "mode" "SF")])
15022
15023 (define_insn "*sinextendsfdf2"
15024   [(set (match_operand:DF 0 "register_operand" "=f")
15025         (unspec:DF [(float_extend:DF
15026                      (match_operand:SF 1 "register_operand" "0"))]
15027                    UNSPEC_SIN))]
15028   "TARGET_USE_FANCY_MATH_387
15029    && flag_unsafe_math_optimizations"
15030   "fsin"
15031   [(set_attr "type" "fpspc")
15032    (set_attr "mode" "DF")])
15033
15034 (define_insn "*sinxf2"
15035   [(set (match_operand:XF 0 "register_operand" "=f")
15036         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15037   "TARGET_USE_FANCY_MATH_387
15038    && flag_unsafe_math_optimizations"
15039   "fsin"
15040   [(set_attr "type" "fpspc")
15041    (set_attr "mode" "XF")])
15042
15043 (define_insn "*cosdf2"
15044   [(set (match_operand:DF 0 "register_operand" "=f")
15045         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15046   "TARGET_USE_FANCY_MATH_387
15047    && flag_unsafe_math_optimizations"
15048   "fcos"
15049   [(set_attr "type" "fpspc")
15050    (set_attr "mode" "DF")])
15051
15052 (define_insn "*cossf2"
15053   [(set (match_operand:SF 0 "register_operand" "=f")
15054         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15055   "TARGET_USE_FANCY_MATH_387
15056    && flag_unsafe_math_optimizations"
15057   "fcos"
15058   [(set_attr "type" "fpspc")
15059    (set_attr "mode" "SF")])
15060
15061 (define_insn "*cosextendsfdf2"
15062   [(set (match_operand:DF 0 "register_operand" "=f")
15063         (unspec:DF [(float_extend:DF
15064                      (match_operand:SF 1 "register_operand" "0"))]
15065                    UNSPEC_COS))]
15066   "TARGET_USE_FANCY_MATH_387
15067    && flag_unsafe_math_optimizations"
15068   "fcos"
15069   [(set_attr "type" "fpspc")
15070    (set_attr "mode" "DF")])
15071
15072 (define_insn "*cosxf2"
15073   [(set (match_operand:XF 0 "register_operand" "=f")
15074         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15075   "TARGET_USE_FANCY_MATH_387
15076    && flag_unsafe_math_optimizations"
15077   "fcos"
15078   [(set_attr "type" "fpspc")
15079    (set_attr "mode" "XF")])
15080
15081 ;; With sincos pattern defined, sin and cos builtin function will be
15082 ;; expanded to sincos pattern with one of its outputs left unused. 
15083 ;; Cse pass  will detected, if two sincos patterns can be combined,
15084 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15085 ;; depending on the unused output.
15086
15087 (define_insn "sincosdf3"
15088   [(set (match_operand:DF 0 "register_operand" "=f")
15089         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15090                    UNSPEC_SINCOS_COS))
15091    (set (match_operand:DF 1 "register_operand" "=u")
15092         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15093   "TARGET_USE_FANCY_MATH_387
15094    && flag_unsafe_math_optimizations"
15095   "fsincos"
15096   [(set_attr "type" "fpspc")
15097    (set_attr "mode" "DF")])
15098
15099 (define_split
15100   [(set (match_operand:DF 0 "register_operand" "")
15101         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15102                    UNSPEC_SINCOS_COS))
15103    (set (match_operand:DF 1 "register_operand" "")
15104         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15105   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15106    && !reload_completed && !reload_in_progress"
15107   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15108   "")
15109
15110 (define_split
15111   [(set (match_operand:DF 0 "register_operand" "")
15112         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15113                    UNSPEC_SINCOS_COS))
15114    (set (match_operand:DF 1 "register_operand" "")
15115         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15116   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15117    && !reload_completed && !reload_in_progress"
15118   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15119   "")
15120
15121 (define_insn "sincossf3"
15122   [(set (match_operand:SF 0 "register_operand" "=f")
15123         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15124                    UNSPEC_SINCOS_COS))
15125    (set (match_operand:SF 1 "register_operand" "=u")
15126         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15127   "TARGET_USE_FANCY_MATH_387
15128    && flag_unsafe_math_optimizations"
15129   "fsincos"
15130   [(set_attr "type" "fpspc")
15131    (set_attr "mode" "SF")])
15132
15133 (define_split
15134   [(set (match_operand:SF 0 "register_operand" "")
15135         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15136                    UNSPEC_SINCOS_COS))
15137    (set (match_operand:SF 1 "register_operand" "")
15138         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15139   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15140    && !reload_completed && !reload_in_progress"
15141   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15142   "")
15143
15144 (define_split
15145   [(set (match_operand:SF 0 "register_operand" "")
15146         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15147                    UNSPEC_SINCOS_COS))
15148    (set (match_operand:SF 1 "register_operand" "")
15149         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15150   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15151    && !reload_completed && !reload_in_progress"
15152   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15153   "")
15154
15155 (define_insn "*sincosextendsfdf3"
15156   [(set (match_operand:DF 0 "register_operand" "=f")
15157         (unspec:DF [(float_extend:DF
15158                      (match_operand:SF 2 "register_operand" "0"))]
15159                    UNSPEC_SINCOS_COS))
15160    (set (match_operand:DF 1 "register_operand" "=u")
15161         (unspec:DF [(float_extend:DF
15162                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15163   "TARGET_USE_FANCY_MATH_387
15164    && flag_unsafe_math_optimizations"
15165   "fsincos"
15166   [(set_attr "type" "fpspc")
15167    (set_attr "mode" "DF")])
15168
15169 (define_split
15170   [(set (match_operand:DF 0 "register_operand" "")
15171         (unspec:DF [(float_extend:DF
15172                      (match_operand:SF 2 "register_operand" ""))]
15173                    UNSPEC_SINCOS_COS))
15174    (set (match_operand:DF 1 "register_operand" "")
15175         (unspec:DF [(float_extend:DF
15176                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15177   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15178    && !reload_completed && !reload_in_progress"
15179   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15180                                    (match_dup 2))] UNSPEC_SIN))]
15181   "")
15182
15183 (define_split
15184   [(set (match_operand:DF 0 "register_operand" "")
15185         (unspec:DF [(float_extend:DF
15186                      (match_operand:SF 2 "register_operand" ""))]
15187                    UNSPEC_SINCOS_COS))
15188    (set (match_operand:DF 1 "register_operand" "")
15189         (unspec:DF [(float_extend:DF
15190                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15191   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15192    && !reload_completed && !reload_in_progress"
15193   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15194                                    (match_dup 2))] UNSPEC_COS))]
15195   "")
15196
15197 (define_insn "sincosxf3"
15198   [(set (match_operand:XF 0 "register_operand" "=f")
15199         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15200                    UNSPEC_SINCOS_COS))
15201    (set (match_operand:XF 1 "register_operand" "=u")
15202         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15203   "TARGET_USE_FANCY_MATH_387
15204    && flag_unsafe_math_optimizations"
15205   "fsincos"
15206   [(set_attr "type" "fpspc")
15207    (set_attr "mode" "XF")])
15208
15209 (define_split
15210   [(set (match_operand:XF 0 "register_operand" "")
15211         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15212                    UNSPEC_SINCOS_COS))
15213    (set (match_operand:XF 1 "register_operand" "")
15214         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15215   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15216    && !reload_completed && !reload_in_progress"
15217   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15218   "")
15219
15220 (define_split
15221   [(set (match_operand:XF 0 "register_operand" "")
15222         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15223                    UNSPEC_SINCOS_COS))
15224    (set (match_operand:XF 1 "register_operand" "")
15225         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15226   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15227    && !reload_completed && !reload_in_progress"
15228   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15229   "")
15230
15231 (define_insn "*tandf3_1"
15232   [(set (match_operand:DF 0 "register_operand" "=f")
15233         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15234                    UNSPEC_TAN_ONE))
15235    (set (match_operand:DF 1 "register_operand" "=u")
15236         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15237   "TARGET_USE_FANCY_MATH_387
15238    && flag_unsafe_math_optimizations"
15239   "fptan"
15240   [(set_attr "type" "fpspc")
15241    (set_attr "mode" "DF")])
15242
15243 ;; optimize sequence: fptan
15244 ;;                    fstp    %st(0)
15245 ;;                    fld1
15246 ;; into fptan insn.
15247
15248 (define_peephole2
15249   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15250                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15251                              UNSPEC_TAN_ONE))
15252              (set (match_operand:DF 1 "register_operand" "")
15253                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15254    (set (match_dup 0)
15255         (match_operand:DF 3 "immediate_operand" ""))]
15256   "standard_80387_constant_p (operands[3]) == 2"
15257   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15258              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15259   "")
15260
15261 (define_expand "tandf2"
15262   [(parallel [(set (match_dup 2)
15263                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15264                               UNSPEC_TAN_ONE))
15265               (set (match_operand:DF 0 "register_operand" "")
15266                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15267   "TARGET_USE_FANCY_MATH_387
15268    && flag_unsafe_math_optimizations"
15269 {
15270   operands[2] = gen_reg_rtx (DFmode);
15271 })
15272
15273 (define_insn "*tansf3_1"
15274   [(set (match_operand:SF 0 "register_operand" "=f")
15275         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15276                    UNSPEC_TAN_ONE))
15277    (set (match_operand:SF 1 "register_operand" "=u")
15278         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15279   "TARGET_USE_FANCY_MATH_387
15280    && flag_unsafe_math_optimizations"
15281   "fptan"
15282   [(set_attr "type" "fpspc")
15283    (set_attr "mode" "SF")])
15284
15285 ;; optimize sequence: fptan
15286 ;;                    fstp    %st(0)
15287 ;;                    fld1
15288 ;; into fptan insn.
15289
15290 (define_peephole2
15291   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15292                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15293                              UNSPEC_TAN_ONE))
15294              (set (match_operand:SF 1 "register_operand" "")
15295                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15296    (set (match_dup 0)
15297         (match_operand:SF 3 "immediate_operand" ""))]
15298   "standard_80387_constant_p (operands[3]) == 2"
15299   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15300              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15301   "")
15302
15303 (define_expand "tansf2"
15304   [(parallel [(set (match_dup 2)
15305                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15306                               UNSPEC_TAN_ONE))
15307               (set (match_operand:SF 0 "register_operand" "")
15308                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15309   "TARGET_USE_FANCY_MATH_387
15310    && flag_unsafe_math_optimizations"
15311 {
15312   operands[2] = gen_reg_rtx (SFmode);
15313 })
15314
15315 (define_insn "*tanxf3_1"
15316   [(set (match_operand:XF 0 "register_operand" "=f")
15317         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15318                    UNSPEC_TAN_ONE))
15319    (set (match_operand:XF 1 "register_operand" "=u")
15320         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15321   "TARGET_USE_FANCY_MATH_387
15322    && flag_unsafe_math_optimizations"
15323   "fptan"
15324   [(set_attr "type" "fpspc")
15325    (set_attr "mode" "XF")])
15326
15327 ;; optimize sequence: fptan
15328 ;;                    fstp    %st(0)
15329 ;;                    fld1
15330 ;; into fptan insn.
15331
15332 (define_peephole2
15333   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15334                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15335                              UNSPEC_TAN_ONE))
15336              (set (match_operand:XF 1 "register_operand" "")
15337                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15338    (set (match_dup 0)
15339         (match_operand:XF 3 "immediate_operand" ""))]
15340   "standard_80387_constant_p (operands[3]) == 2"
15341   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15342              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15343   "")
15344
15345 (define_expand "tanxf2"
15346   [(parallel [(set (match_dup 2)
15347                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15348                               UNSPEC_TAN_ONE))
15349               (set (match_operand:XF 0 "register_operand" "")
15350                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15351   "TARGET_USE_FANCY_MATH_387
15352    && flag_unsafe_math_optimizations"
15353 {
15354   operands[2] = gen_reg_rtx (XFmode);
15355 })
15356
15357 (define_insn "atan2df3_1"
15358   [(set (match_operand:DF 0 "register_operand" "=f")
15359         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15360                     (match_operand:DF 1 "register_operand" "u")]
15361                    UNSPEC_FPATAN))
15362    (clobber (match_scratch:DF 3 "=1"))]
15363   "TARGET_USE_FANCY_MATH_387
15364    && flag_unsafe_math_optimizations"
15365   "fpatan"
15366   [(set_attr "type" "fpspc")
15367    (set_attr "mode" "DF")])
15368
15369 (define_expand "atan2df3"
15370   [(use (match_operand:DF 0 "register_operand" "=f"))
15371    (use (match_operand:DF 2 "register_operand" "0"))
15372    (use (match_operand:DF 1 "register_operand" "u"))]
15373   "TARGET_USE_FANCY_MATH_387
15374    && flag_unsafe_math_optimizations"
15375 {
15376   rtx copy = gen_reg_rtx (DFmode);
15377   emit_move_insn (copy, operands[1]);
15378   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15379   DONE;
15380 })
15381
15382 (define_expand "atandf2"
15383   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15384                    (unspec:DF [(match_dup 2)
15385                                (match_operand:DF 1 "register_operand" "")]
15386                     UNSPEC_FPATAN))
15387               (clobber (match_scratch:DF 3 ""))])]
15388   "TARGET_USE_FANCY_MATH_387
15389    && flag_unsafe_math_optimizations"
15390 {
15391   operands[2] = gen_reg_rtx (DFmode);
15392   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15393 })
15394
15395 (define_insn "atan2sf3_1"
15396   [(set (match_operand:SF 0 "register_operand" "=f")
15397         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15398                     (match_operand:SF 1 "register_operand" "u")]
15399                    UNSPEC_FPATAN))
15400    (clobber (match_scratch:SF 3 "=1"))]
15401   "TARGET_USE_FANCY_MATH_387
15402    && flag_unsafe_math_optimizations"
15403   "fpatan"
15404   [(set_attr "type" "fpspc")
15405    (set_attr "mode" "SF")])
15406
15407 (define_expand "atan2sf3"
15408   [(use (match_operand:SF 0 "register_operand" "=f"))
15409    (use (match_operand:SF 2 "register_operand" "0"))
15410    (use (match_operand:SF 1 "register_operand" "u"))]
15411   "TARGET_USE_FANCY_MATH_387
15412    && flag_unsafe_math_optimizations"
15413 {
15414   rtx copy = gen_reg_rtx (SFmode);
15415   emit_move_insn (copy, operands[1]);
15416   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15417   DONE;
15418 })
15419
15420 (define_expand "atansf2"
15421   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15422                    (unspec:SF [(match_dup 2)
15423                                (match_operand:SF 1 "register_operand" "")]
15424                     UNSPEC_FPATAN))
15425               (clobber (match_scratch:SF 3 ""))])]
15426   "TARGET_USE_FANCY_MATH_387
15427    && flag_unsafe_math_optimizations"
15428 {
15429   operands[2] = gen_reg_rtx (SFmode);
15430   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15431 })
15432
15433 (define_insn "atan2xf3_1"
15434   [(set (match_operand:XF 0 "register_operand" "=f")
15435         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15436                     (match_operand:XF 1 "register_operand" "u")]
15437                    UNSPEC_FPATAN))
15438    (clobber (match_scratch:XF 3 "=1"))]
15439   "TARGET_USE_FANCY_MATH_387
15440    && flag_unsafe_math_optimizations"
15441   "fpatan"
15442   [(set_attr "type" "fpspc")
15443    (set_attr "mode" "XF")])
15444
15445 (define_expand "atan2xf3"
15446   [(use (match_operand:XF 0 "register_operand" "=f"))
15447    (use (match_operand:XF 2 "register_operand" "0"))
15448    (use (match_operand:XF 1 "register_operand" "u"))]
15449   "TARGET_USE_FANCY_MATH_387
15450    && flag_unsafe_math_optimizations"
15451 {
15452   rtx copy = gen_reg_rtx (XFmode);
15453   emit_move_insn (copy, operands[1]);
15454   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15455   DONE;
15456 })
15457
15458 (define_expand "atanxf2"
15459   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15460                    (unspec:XF [(match_dup 2)
15461                                (match_operand:XF 1 "register_operand" "")]
15462                     UNSPEC_FPATAN))
15463               (clobber (match_scratch:XF 3 ""))])]
15464   "TARGET_USE_FANCY_MATH_387
15465    && flag_unsafe_math_optimizations"
15466 {
15467   operands[2] = gen_reg_rtx (XFmode);
15468   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15469 })
15470
15471 (define_expand "asindf2"
15472   [(set (match_dup 2)
15473         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15474    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15475    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15476    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15477    (parallel [(set (match_dup 7)
15478                    (unspec:XF [(match_dup 6) (match_dup 2)]
15479                               UNSPEC_FPATAN))
15480               (clobber (match_scratch:XF 8 ""))])
15481    (set (match_operand:DF 0 "register_operand" "")
15482         (float_truncate:DF (match_dup 7)))]
15483   "TARGET_USE_FANCY_MATH_387
15484    && flag_unsafe_math_optimizations"
15485 {
15486   int i;
15487
15488   for (i=2; i<8; i++)
15489     operands[i] = gen_reg_rtx (XFmode);
15490
15491   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15492 })
15493
15494 (define_expand "asinsf2"
15495   [(set (match_dup 2)
15496         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15497    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15498    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15499    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15500    (parallel [(set (match_dup 7)
15501                    (unspec:XF [(match_dup 6) (match_dup 2)]
15502                               UNSPEC_FPATAN))
15503               (clobber (match_scratch:XF 8 ""))])
15504    (set (match_operand:SF 0 "register_operand" "")
15505         (float_truncate:SF (match_dup 7)))]
15506   "TARGET_USE_FANCY_MATH_387
15507    && flag_unsafe_math_optimizations"
15508 {
15509   int i;
15510
15511   for (i=2; i<8; i++)
15512     operands[i] = gen_reg_rtx (XFmode);
15513
15514   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15515 })
15516
15517 (define_expand "asinxf2"
15518   [(set (match_dup 2)
15519         (mult:XF (match_operand:XF 1 "register_operand" "")
15520                  (match_dup 1)))
15521    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15522    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15523    (parallel [(set (match_operand:XF 0 "register_operand" "")
15524                    (unspec:XF [(match_dup 5) (match_dup 1)]
15525                               UNSPEC_FPATAN))
15526               (clobber (match_scratch:XF 6 ""))])]
15527   "TARGET_USE_FANCY_MATH_387
15528    && flag_unsafe_math_optimizations"
15529 {
15530   int i;
15531
15532   for (i=2; i<6; i++)
15533     operands[i] = gen_reg_rtx (XFmode);
15534
15535   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15536 })
15537
15538 (define_expand "acosdf2"
15539   [(set (match_dup 2)
15540         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15541    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15542    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15543    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15544    (parallel [(set (match_dup 7)
15545                    (unspec:XF [(match_dup 2) (match_dup 6)]
15546                               UNSPEC_FPATAN))
15547               (clobber (match_scratch:XF 8 ""))])
15548    (set (match_operand:DF 0 "register_operand" "")
15549         (float_truncate:DF (match_dup 7)))]
15550   "TARGET_USE_FANCY_MATH_387
15551    && flag_unsafe_math_optimizations"
15552 {
15553   int i;
15554
15555   for (i=2; i<8; i++)
15556     operands[i] = gen_reg_rtx (XFmode);
15557
15558   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15559 })
15560
15561 (define_expand "acossf2"
15562   [(set (match_dup 2)
15563         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15564    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15565    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15566    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15567    (parallel [(set (match_dup 7)
15568                    (unspec:XF [(match_dup 2) (match_dup 6)]
15569                               UNSPEC_FPATAN))
15570               (clobber (match_scratch:XF 8 ""))])
15571    (set (match_operand:SF 0 "register_operand" "")
15572         (float_truncate:SF (match_dup 7)))]
15573   "TARGET_USE_FANCY_MATH_387
15574    && flag_unsafe_math_optimizations"
15575 {
15576   int i;
15577
15578   for (i=2; i<8; i++)
15579     operands[i] = gen_reg_rtx (XFmode);
15580
15581   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15582 })
15583
15584 (define_expand "acosxf2"
15585   [(set (match_dup 2)
15586         (mult:XF (match_operand:XF 1 "register_operand" "")
15587                  (match_dup 1)))
15588    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15589    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15590    (parallel [(set (match_operand:XF 0 "register_operand" "")
15591                    (unspec:XF [(match_dup 1) (match_dup 5)]
15592                               UNSPEC_FPATAN))
15593               (clobber (match_scratch:XF 6 ""))])]
15594   "TARGET_USE_FANCY_MATH_387
15595    && flag_unsafe_math_optimizations"
15596 {
15597   int i;
15598
15599   for (i=2; i<6; i++)
15600     operands[i] = gen_reg_rtx (XFmode);
15601
15602   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15603 })
15604
15605 (define_insn "fyl2x_xf3"
15606   [(set (match_operand:XF 0 "register_operand" "=f")
15607         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15608                     (match_operand:XF 1 "register_operand" "u")]
15609                    UNSPEC_FYL2X))
15610    (clobber (match_scratch:XF 3 "=1"))]
15611   "TARGET_USE_FANCY_MATH_387
15612    && flag_unsafe_math_optimizations"
15613   "fyl2x"
15614   [(set_attr "type" "fpspc")
15615    (set_attr "mode" "XF")])
15616
15617 (define_expand "logsf2"
15618   [(set (match_dup 2)
15619         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15620    (parallel [(set (match_dup 4)
15621                    (unspec:XF [(match_dup 2)
15622                                (match_dup 3)] UNSPEC_FYL2X))
15623               (clobber (match_scratch:XF 5 ""))])
15624    (set (match_operand:SF 0 "register_operand" "")
15625         (float_truncate:SF (match_dup 4)))]
15626   "TARGET_USE_FANCY_MATH_387
15627    && flag_unsafe_math_optimizations"
15628 {
15629   rtx temp;
15630
15631   operands[2] = gen_reg_rtx (XFmode);
15632   operands[3] = gen_reg_rtx (XFmode);
15633   operands[4] = gen_reg_rtx (XFmode);
15634
15635   temp = standard_80387_constant_rtx (4); /* fldln2 */
15636   emit_move_insn (operands[3], temp);
15637 })
15638
15639 (define_expand "logdf2"
15640   [(set (match_dup 2)
15641         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15642    (parallel [(set (match_dup 4)
15643                    (unspec:XF [(match_dup 2)
15644                                (match_dup 3)] UNSPEC_FYL2X))
15645               (clobber (match_scratch:XF 5 ""))])
15646    (set (match_operand:DF 0 "register_operand" "")
15647         (float_truncate:DF (match_dup 4)))]
15648   "TARGET_USE_FANCY_MATH_387
15649    && flag_unsafe_math_optimizations"
15650 {
15651   rtx temp;
15652
15653   operands[2] = gen_reg_rtx (XFmode);
15654   operands[3] = gen_reg_rtx (XFmode);
15655   operands[4] = gen_reg_rtx (XFmode);
15656
15657   temp = standard_80387_constant_rtx (4); /* fldln2 */
15658   emit_move_insn (operands[3], temp);
15659 })
15660
15661 (define_expand "logxf2"
15662   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15663                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15664                                (match_dup 2)] UNSPEC_FYL2X))
15665               (clobber (match_scratch:XF 3 ""))])]
15666   "TARGET_USE_FANCY_MATH_387
15667    && flag_unsafe_math_optimizations"
15668 {
15669   rtx temp;
15670
15671   operands[2] = gen_reg_rtx (XFmode);
15672   temp = standard_80387_constant_rtx (4); /* fldln2 */
15673   emit_move_insn (operands[2], temp);
15674 })
15675
15676 (define_expand "log10sf2"
15677   [(set (match_dup 2)
15678         (float_extend:XF (match_operand:SF 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:SF 0 "register_operand" "")
15684         (float_truncate:SF (match_dup 4)))]
15685   "TARGET_USE_FANCY_MATH_387
15686    && flag_unsafe_math_optimizations"
15687 {
15688   rtx temp;
15689
15690   operands[2] = gen_reg_rtx (XFmode);
15691   operands[3] = gen_reg_rtx (XFmode);
15692   operands[4] = gen_reg_rtx (XFmode);
15693
15694   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15695   emit_move_insn (operands[3], temp);
15696 })
15697
15698 (define_expand "log10df2"
15699   [(set (match_dup 2)
15700         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15701    (parallel [(set (match_dup 4)
15702                    (unspec:XF [(match_dup 2)
15703                                (match_dup 3)] UNSPEC_FYL2X))
15704               (clobber (match_scratch:XF 5 ""))])
15705    (set (match_operand:DF 0 "register_operand" "")
15706         (float_truncate:DF (match_dup 4)))]
15707   "TARGET_USE_FANCY_MATH_387
15708    && flag_unsafe_math_optimizations"
15709 {
15710   rtx temp;
15711
15712   operands[2] = gen_reg_rtx (XFmode);
15713   operands[3] = gen_reg_rtx (XFmode);
15714   operands[4] = gen_reg_rtx (XFmode);
15715
15716   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15717   emit_move_insn (operands[3], temp);
15718 })
15719
15720 (define_expand "log10xf2"
15721   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15722                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15723                                (match_dup 2)] UNSPEC_FYL2X))
15724               (clobber (match_scratch:XF 3 ""))])]
15725   "TARGET_USE_FANCY_MATH_387
15726    && flag_unsafe_math_optimizations"
15727 {
15728   rtx temp;
15729
15730   operands[2] = gen_reg_rtx (XFmode);
15731   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15732   emit_move_insn (operands[2], temp);
15733 })
15734
15735 (define_expand "log2sf2"
15736   [(set (match_dup 2)
15737         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15738    (parallel [(set (match_dup 4)
15739                    (unspec:XF [(match_dup 2)
15740                                (match_dup 3)] UNSPEC_FYL2X))
15741               (clobber (match_scratch:XF 5 ""))])
15742    (set (match_operand:SF 0 "register_operand" "")
15743         (float_truncate:SF (match_dup 4)))]
15744   "TARGET_USE_FANCY_MATH_387
15745    && flag_unsafe_math_optimizations"
15746 {
15747   operands[2] = gen_reg_rtx (XFmode);
15748   operands[3] = gen_reg_rtx (XFmode);
15749   operands[4] = gen_reg_rtx (XFmode);
15750
15751   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15752 })
15753
15754 (define_expand "log2df2"
15755   [(set (match_dup 2)
15756         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15757    (parallel [(set (match_dup 4)
15758                    (unspec:XF [(match_dup 2)
15759                                (match_dup 3)] UNSPEC_FYL2X))
15760               (clobber (match_scratch:XF 5 ""))])
15761    (set (match_operand:DF 0 "register_operand" "")
15762         (float_truncate:DF (match_dup 4)))]
15763   "TARGET_USE_FANCY_MATH_387
15764    && flag_unsafe_math_optimizations"
15765 {
15766   operands[2] = gen_reg_rtx (XFmode);
15767   operands[3] = gen_reg_rtx (XFmode);
15768   operands[4] = gen_reg_rtx (XFmode);
15769
15770   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15771 })
15772
15773 (define_expand "log2xf2"
15774   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15775                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15776                                (match_dup 2)] UNSPEC_FYL2X))
15777               (clobber (match_scratch:XF 3 ""))])]
15778   "TARGET_USE_FANCY_MATH_387
15779    && flag_unsafe_math_optimizations"
15780 {
15781   operands[2] = gen_reg_rtx (XFmode);
15782   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15783 })
15784
15785 (define_insn "fyl2xp1_xf3"
15786   [(set (match_operand:XF 0 "register_operand" "=f")
15787         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15788                     (match_operand:XF 1 "register_operand" "u")]
15789                    UNSPEC_FYL2XP1))
15790    (clobber (match_scratch:XF 3 "=1"))]
15791   "TARGET_USE_FANCY_MATH_387
15792    && flag_unsafe_math_optimizations"
15793   "fyl2xp1"
15794   [(set_attr "type" "fpspc")
15795    (set_attr "mode" "XF")])
15796
15797 (define_expand "log1psf2"
15798   [(use (match_operand:XF 0 "register_operand" ""))
15799    (use (match_operand:XF 1 "register_operand" ""))]
15800   "TARGET_USE_FANCY_MATH_387
15801    && flag_unsafe_math_optimizations"
15802 {
15803   rtx op0 = gen_reg_rtx (XFmode);
15804   rtx op1 = gen_reg_rtx (XFmode);
15805
15806   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15807   ix86_emit_i387_log1p (op0, op1);
15808   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
15809   DONE;
15810 })
15811
15812 (define_expand "log1pdf2"
15813   [(use (match_operand:XF 0 "register_operand" ""))
15814    (use (match_operand:XF 1 "register_operand" ""))]
15815   "TARGET_USE_FANCY_MATH_387
15816    && flag_unsafe_math_optimizations"
15817 {
15818   rtx op0 = gen_reg_rtx (XFmode);
15819   rtx op1 = gen_reg_rtx (XFmode);
15820
15821   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15822   ix86_emit_i387_log1p (op0, op1);
15823   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
15824   DONE;
15825 })
15826
15827 (define_expand "log1pxf2"
15828   [(use (match_operand:XF 0 "register_operand" ""))
15829    (use (match_operand:XF 1 "register_operand" ""))]
15830   "TARGET_USE_FANCY_MATH_387
15831    && flag_unsafe_math_optimizations"
15832 {
15833   ix86_emit_i387_log1p (operands[0], operands[1]);
15834   DONE;
15835 })
15836
15837 (define_insn "*fxtractxf3"
15838   [(set (match_operand:XF 0 "register_operand" "=f")
15839         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15840                    UNSPEC_XTRACT_FRACT))
15841    (set (match_operand:XF 1 "register_operand" "=u")
15842         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15843   "TARGET_USE_FANCY_MATH_387
15844    && flag_unsafe_math_optimizations"
15845   "fxtract"
15846   [(set_attr "type" "fpspc")
15847    (set_attr "mode" "XF")])
15848
15849 (define_expand "logbsf2"
15850   [(set (match_dup 2)
15851         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15852    (parallel [(set (match_dup 3)
15853                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15854               (set (match_dup 4)
15855                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15856    (set (match_operand:SF 0 "register_operand" "")
15857         (float_truncate:SF (match_dup 4)))]
15858   "TARGET_USE_FANCY_MATH_387
15859    && flag_unsafe_math_optimizations"
15860 {
15861   operands[2] = gen_reg_rtx (XFmode);
15862   operands[3] = gen_reg_rtx (XFmode);
15863   operands[4] = gen_reg_rtx (XFmode);
15864 })
15865
15866 (define_expand "logbdf2"
15867   [(set (match_dup 2)
15868         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15869    (parallel [(set (match_dup 3)
15870                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15871               (set (match_dup 4)
15872                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15873    (set (match_operand:DF 0 "register_operand" "")
15874         (float_truncate:DF (match_dup 4)))]
15875   "TARGET_USE_FANCY_MATH_387
15876    && flag_unsafe_math_optimizations"
15877 {
15878   operands[2] = gen_reg_rtx (XFmode);
15879   operands[3] = gen_reg_rtx (XFmode);
15880   operands[4] = gen_reg_rtx (XFmode);
15881 })
15882
15883 (define_expand "logbxf2"
15884   [(parallel [(set (match_dup 2)
15885                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15886                               UNSPEC_XTRACT_FRACT))
15887               (set (match_operand:XF 0 "register_operand" "")
15888                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15889   "TARGET_USE_FANCY_MATH_387
15890    && flag_unsafe_math_optimizations"
15891 {
15892   operands[2] = gen_reg_rtx (XFmode);
15893 })
15894
15895 (define_expand "ilogbsi2"
15896   [(parallel [(set (match_dup 2)
15897                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15898                               UNSPEC_XTRACT_FRACT))
15899               (set (match_operand:XF 3 "register_operand" "")
15900                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15901    (parallel [(set (match_operand:SI 0 "register_operand" "")
15902                    (fix:SI (match_dup 3)))
15903               (clobber (reg:CC FLAGS_REG))])]
15904   "TARGET_USE_FANCY_MATH_387
15905    && flag_unsafe_math_optimizations"
15906 {
15907   operands[2] = gen_reg_rtx (XFmode);
15908   operands[3] = gen_reg_rtx (XFmode);
15909 })
15910
15911 (define_insn "*f2xm1xf2"
15912   [(set (match_operand:XF 0 "register_operand" "=f")
15913         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15914          UNSPEC_F2XM1))]
15915   "TARGET_USE_FANCY_MATH_387
15916    && flag_unsafe_math_optimizations"
15917   "f2xm1"
15918   [(set_attr "type" "fpspc")
15919    (set_attr "mode" "XF")])
15920
15921 (define_insn "*fscalexf4"
15922   [(set (match_operand:XF 0 "register_operand" "=f")
15923         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15924                     (match_operand:XF 3 "register_operand" "1")]
15925                    UNSPEC_FSCALE_FRACT))
15926    (set (match_operand:XF 1 "register_operand" "=u")
15927         (unspec:XF [(match_dup 2) (match_dup 3)]
15928                    UNSPEC_FSCALE_EXP))]
15929   "TARGET_USE_FANCY_MATH_387
15930    && flag_unsafe_math_optimizations"
15931   "fscale"
15932   [(set_attr "type" "fpspc")
15933    (set_attr "mode" "XF")])
15934
15935 (define_expand "expsf2"
15936   [(set (match_dup 2)
15937         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15938    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15939    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15940    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15941    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15942    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15943    (parallel [(set (match_dup 10)
15944                    (unspec:XF [(match_dup 9) (match_dup 5)]
15945                               UNSPEC_FSCALE_FRACT))
15946               (set (match_dup 11)
15947                    (unspec:XF [(match_dup 9) (match_dup 5)]
15948                               UNSPEC_FSCALE_EXP))])
15949    (set (match_operand:SF 0 "register_operand" "")
15950         (float_truncate:SF (match_dup 10)))]
15951   "TARGET_USE_FANCY_MATH_387
15952    && flag_unsafe_math_optimizations"
15953 {
15954   rtx temp;
15955   int i;
15956
15957   for (i=2; i<12; i++)
15958     operands[i] = gen_reg_rtx (XFmode);
15959   temp = standard_80387_constant_rtx (5); /* fldl2e */
15960   emit_move_insn (operands[3], temp);
15961   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15962 })
15963
15964 (define_expand "expdf2"
15965   [(set (match_dup 2)
15966         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15967    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15968    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15969    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15970    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15971    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15972    (parallel [(set (match_dup 10)
15973                    (unspec:XF [(match_dup 9) (match_dup 5)]
15974                               UNSPEC_FSCALE_FRACT))
15975               (set (match_dup 11)
15976                    (unspec:XF [(match_dup 9) (match_dup 5)]
15977                               UNSPEC_FSCALE_EXP))])
15978    (set (match_operand:DF 0 "register_operand" "")
15979         (float_truncate:DF (match_dup 10)))]
15980   "TARGET_USE_FANCY_MATH_387
15981    && flag_unsafe_math_optimizations"
15982 {
15983   rtx temp;
15984   int i;
15985
15986   for (i=2; i<12; i++)
15987     operands[i] = gen_reg_rtx (XFmode);
15988   temp = standard_80387_constant_rtx (5); /* fldl2e */
15989   emit_move_insn (operands[3], temp);
15990   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15991 })
15992
15993 (define_expand "expxf2"
15994   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15995                                (match_dup 2)))
15996    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15997    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15998    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15999    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16000    (parallel [(set (match_operand:XF 0 "register_operand" "")
16001                    (unspec:XF [(match_dup 8) (match_dup 4)]
16002                               UNSPEC_FSCALE_FRACT))
16003               (set (match_dup 9)
16004                    (unspec:XF [(match_dup 8) (match_dup 4)]
16005                               UNSPEC_FSCALE_EXP))])]
16006   "TARGET_USE_FANCY_MATH_387
16007    && flag_unsafe_math_optimizations"
16008 {
16009   rtx temp;
16010   int i;
16011
16012   for (i=2; i<10; i++)
16013     operands[i] = gen_reg_rtx (XFmode);
16014   temp = standard_80387_constant_rtx (5); /* fldl2e */
16015   emit_move_insn (operands[2], temp);
16016   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16017 })
16018
16019 (define_expand "exp10sf2"
16020   [(set (match_dup 2)
16021         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16022    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16023    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16024    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16025    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16026    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16027    (parallel [(set (match_dup 10)
16028                    (unspec:XF [(match_dup 9) (match_dup 5)]
16029                               UNSPEC_FSCALE_FRACT))
16030               (set (match_dup 11)
16031                    (unspec:XF [(match_dup 9) (match_dup 5)]
16032                               UNSPEC_FSCALE_EXP))])
16033    (set (match_operand:SF 0 "register_operand" "")
16034         (float_truncate:SF (match_dup 10)))]
16035   "TARGET_USE_FANCY_MATH_387
16036    && flag_unsafe_math_optimizations"
16037 {
16038   rtx temp;
16039   int i;
16040
16041   for (i=2; i<12; i++)
16042     operands[i] = gen_reg_rtx (XFmode);
16043   temp = standard_80387_constant_rtx (6); /* fldl2t */
16044   emit_move_insn (operands[3], temp);
16045   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16046 })
16047
16048 (define_expand "exp10df2"
16049   [(set (match_dup 2)
16050         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16051    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16052    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16053    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16054    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16055    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16056    (parallel [(set (match_dup 10)
16057                    (unspec:XF [(match_dup 9) (match_dup 5)]
16058                               UNSPEC_FSCALE_FRACT))
16059               (set (match_dup 11)
16060                    (unspec:XF [(match_dup 9) (match_dup 5)]
16061                               UNSPEC_FSCALE_EXP))])
16062    (set (match_operand:DF 0 "register_operand" "")
16063         (float_truncate:DF (match_dup 10)))]
16064   "TARGET_USE_FANCY_MATH_387
16065    && flag_unsafe_math_optimizations"
16066 {
16067   rtx temp;
16068   int i;
16069
16070   for (i=2; i<12; i++)
16071     operands[i] = gen_reg_rtx (XFmode);
16072   temp = standard_80387_constant_rtx (6); /* fldl2t */
16073   emit_move_insn (operands[3], temp);
16074   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16075 })
16076
16077 (define_expand "exp10xf2"
16078   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16079                                (match_dup 2)))
16080    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16081    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16082    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16083    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16084    (parallel [(set (match_operand:XF 0 "register_operand" "")
16085                    (unspec:XF [(match_dup 8) (match_dup 4)]
16086                               UNSPEC_FSCALE_FRACT))
16087               (set (match_dup 9)
16088                    (unspec:XF [(match_dup 8) (match_dup 4)]
16089                               UNSPEC_FSCALE_EXP))])]
16090   "TARGET_USE_FANCY_MATH_387
16091    && flag_unsafe_math_optimizations"
16092 {
16093   rtx temp;
16094   int i;
16095
16096   for (i=2; i<10; i++)
16097     operands[i] = gen_reg_rtx (XFmode);
16098   temp = standard_80387_constant_rtx (6); /* fldl2t */
16099   emit_move_insn (operands[2], temp);
16100   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16101 })
16102
16103 (define_expand "exp2sf2"
16104   [(set (match_dup 2)
16105         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16106    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16107    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16108    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16109    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16110    (parallel [(set (match_dup 8)
16111                    (unspec:XF [(match_dup 7) (match_dup 3)]
16112                               UNSPEC_FSCALE_FRACT))
16113               (set (match_dup 9)
16114                    (unspec:XF [(match_dup 7) (match_dup 3)]
16115                               UNSPEC_FSCALE_EXP))])
16116    (set (match_operand:SF 0 "register_operand" "")
16117         (float_truncate:SF (match_dup 8)))]
16118   "TARGET_USE_FANCY_MATH_387
16119    && flag_unsafe_math_optimizations"
16120 {
16121   int i;
16122
16123   for (i=2; i<10; i++)
16124     operands[i] = gen_reg_rtx (XFmode);
16125   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16126 })
16127
16128 (define_expand "exp2df2"
16129   [(set (match_dup 2)
16130         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16131    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16132    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16133    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16134    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16135    (parallel [(set (match_dup 8)
16136                    (unspec:XF [(match_dup 7) (match_dup 3)]
16137                               UNSPEC_FSCALE_FRACT))
16138               (set (match_dup 9)
16139                    (unspec:XF [(match_dup 7) (match_dup 3)]
16140                               UNSPEC_FSCALE_EXP))])
16141    (set (match_operand:DF 0 "register_operand" "")
16142         (float_truncate:DF (match_dup 8)))]
16143   "TARGET_USE_FANCY_MATH_387
16144    && flag_unsafe_math_optimizations"
16145 {
16146   int i;
16147
16148   for (i=2; i<10; i++)
16149     operands[i] = gen_reg_rtx (XFmode);
16150   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16151 })
16152
16153 (define_expand "exp2xf2"
16154   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16155    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16156    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16157    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16158    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16159    (parallel [(set (match_operand:XF 0 "register_operand" "")
16160                    (unspec:XF [(match_dup 7) (match_dup 3)]
16161                               UNSPEC_FSCALE_FRACT))
16162               (set (match_dup 8)
16163                    (unspec:XF [(match_dup 7) (match_dup 3)]
16164                               UNSPEC_FSCALE_EXP))])]
16165   "TARGET_USE_FANCY_MATH_387
16166    && flag_unsafe_math_optimizations"
16167 {
16168   int i;
16169
16170   for (i=2; i<9; i++)
16171     operands[i] = gen_reg_rtx (XFmode);
16172   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16173 })
16174
16175 (define_expand "expm1df2"
16176   [(set (match_dup 2)
16177         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16178    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16179    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16180    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16181    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16182    (parallel [(set (match_dup 8)
16183                    (unspec:XF [(match_dup 7) (match_dup 5)]
16184                               UNSPEC_FSCALE_FRACT))
16185                    (set (match_dup 9)
16186                    (unspec:XF [(match_dup 7) (match_dup 5)]
16187                               UNSPEC_FSCALE_EXP))])
16188    (parallel [(set (match_dup 11)
16189                    (unspec:XF [(match_dup 10) (match_dup 9)]
16190                               UNSPEC_FSCALE_FRACT))
16191               (set (match_dup 12)
16192                    (unspec:XF [(match_dup 10) (match_dup 9)]
16193                               UNSPEC_FSCALE_EXP))])
16194    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16195    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16196    (set (match_operand:DF 0 "register_operand" "")
16197         (float_truncate:DF (match_dup 14)))]
16198   "TARGET_USE_FANCY_MATH_387
16199    && flag_unsafe_math_optimizations"
16200 {
16201   rtx temp;
16202   int i;
16203
16204   for (i=2; i<15; i++)
16205     operands[i] = gen_reg_rtx (XFmode);
16206   temp = standard_80387_constant_rtx (5); /* fldl2e */
16207   emit_move_insn (operands[3], temp);
16208   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16209 })
16210
16211 (define_expand "expm1sf2"
16212   [(set (match_dup 2)
16213         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16214    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16215    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16216    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16217    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16218    (parallel [(set (match_dup 8)
16219                    (unspec:XF [(match_dup 7) (match_dup 5)]
16220                               UNSPEC_FSCALE_FRACT))
16221                    (set (match_dup 9)
16222                    (unspec:XF [(match_dup 7) (match_dup 5)]
16223                               UNSPEC_FSCALE_EXP))])
16224    (parallel [(set (match_dup 11)
16225                    (unspec:XF [(match_dup 10) (match_dup 9)]
16226                               UNSPEC_FSCALE_FRACT))
16227               (set (match_dup 12)
16228                    (unspec:XF [(match_dup 10) (match_dup 9)]
16229                               UNSPEC_FSCALE_EXP))])
16230    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16231    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16232    (set (match_operand:SF 0 "register_operand" "")
16233         (float_truncate:SF (match_dup 14)))]
16234   "TARGET_USE_FANCY_MATH_387
16235    && flag_unsafe_math_optimizations"
16236 {
16237   rtx temp;
16238   int i;
16239
16240   for (i=2; i<15; i++)
16241     operands[i] = gen_reg_rtx (XFmode);
16242   temp = standard_80387_constant_rtx (5); /* fldl2e */
16243   emit_move_insn (operands[3], temp);
16244   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16245 })
16246
16247 (define_expand "expm1xf2"
16248   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16249                                (match_dup 2)))
16250    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16251    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16252    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16253    (parallel [(set (match_dup 7)
16254                    (unspec:XF [(match_dup 6) (match_dup 4)]
16255                               UNSPEC_FSCALE_FRACT))
16256                    (set (match_dup 8)
16257                    (unspec:XF [(match_dup 6) (match_dup 4)]
16258                               UNSPEC_FSCALE_EXP))])
16259    (parallel [(set (match_dup 10)
16260                    (unspec:XF [(match_dup 9) (match_dup 8)]
16261                               UNSPEC_FSCALE_FRACT))
16262               (set (match_dup 11)
16263                    (unspec:XF [(match_dup 9) (match_dup 8)]
16264                               UNSPEC_FSCALE_EXP))])
16265    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16266    (set (match_operand:XF 0 "register_operand" "")
16267         (plus:XF (match_dup 12) (match_dup 7)))]
16268   "TARGET_USE_FANCY_MATH_387
16269    && flag_unsafe_math_optimizations"
16270 {
16271   rtx temp;
16272   int i;
16273
16274   for (i=2; i<13; i++)
16275     operands[i] = gen_reg_rtx (XFmode);
16276   temp = standard_80387_constant_rtx (5); /* fldl2e */
16277   emit_move_insn (operands[2], temp);
16278   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16279 })
16280 \f
16281
16282 (define_insn "frndintxf2"
16283   [(set (match_operand:XF 0 "register_operand" "=f")
16284         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16285          UNSPEC_FRNDINT))]
16286   "TARGET_USE_FANCY_MATH_387
16287    && flag_unsafe_math_optimizations"
16288   "frndint"
16289   [(set_attr "type" "fpspc")
16290    (set_attr "mode" "XF")])
16291
16292 (define_expand "rintdf2"
16293   [(use (match_operand:DF 0 "register_operand" ""))
16294    (use (match_operand:DF 1 "register_operand" ""))]
16295   "TARGET_USE_FANCY_MATH_387
16296    && flag_unsafe_math_optimizations"
16297 {
16298   rtx op0 = gen_reg_rtx (XFmode);
16299   rtx op1 = gen_reg_rtx (XFmode);
16300
16301   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16302   emit_insn (gen_frndintxf2 (op0, op1));
16303
16304   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16305   DONE;
16306 })
16307
16308 (define_expand "rintsf2"
16309   [(use (match_operand:SF 0 "register_operand" ""))
16310    (use (match_operand:SF 1 "register_operand" ""))]
16311   "TARGET_USE_FANCY_MATH_387
16312    && flag_unsafe_math_optimizations"
16313 {
16314   rtx op0 = gen_reg_rtx (XFmode);
16315   rtx op1 = gen_reg_rtx (XFmode);
16316
16317   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16318   emit_insn (gen_frndintxf2 (op0, op1));
16319
16320   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16321   DONE;
16322 })
16323
16324 (define_expand "rintxf2"
16325   [(use (match_operand:XF 0 "register_operand" ""))
16326    (use (match_operand:XF 1 "register_operand" ""))]
16327   "TARGET_USE_FANCY_MATH_387
16328    && flag_unsafe_math_optimizations"
16329 {
16330   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16331   DONE;
16332 })
16333
16334 (define_insn "frndintxf2_floor"
16335   [(set (match_operand:XF 0 "register_operand" "=f")
16336         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16337          UNSPEC_FRNDINT_FLOOR))
16338    (use (match_operand:HI 2 "memory_operand" "m"))
16339    (use (match_operand:HI 3 "memory_operand" "m"))]
16340   "TARGET_USE_FANCY_MATH_387
16341    && flag_unsafe_math_optimizations"
16342   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16343   [(set_attr "type" "frndint")
16344    (set_attr "i387_cw" "floor")
16345    (set_attr "mode" "XF")])
16346
16347 (define_expand "floordf2"
16348   [(use (match_operand:DF 0 "register_operand" ""))
16349    (use (match_operand:DF 1 "register_operand" ""))]
16350   "TARGET_USE_FANCY_MATH_387
16351    && flag_unsafe_math_optimizations"
16352 {
16353   rtx op0 = gen_reg_rtx (XFmode);
16354   rtx op1 = gen_reg_rtx (XFmode);
16355   rtx op2 = assign_386_stack_local (HImode, 1);
16356   rtx op3 = assign_386_stack_local (HImode, 2);
16357         
16358   ix86_optimize_mode_switching = 1;
16359
16360   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16361   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16362
16363   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16364   DONE;
16365 })
16366
16367 (define_expand "floorsf2"
16368   [(use (match_operand:SF 0 "register_operand" ""))
16369    (use (match_operand:SF 1 "register_operand" ""))]
16370   "TARGET_USE_FANCY_MATH_387
16371    && flag_unsafe_math_optimizations"
16372 {
16373   rtx op0 = gen_reg_rtx (XFmode);
16374   rtx op1 = gen_reg_rtx (XFmode);
16375   rtx op2 = assign_386_stack_local (HImode, 1);
16376   rtx op3 = assign_386_stack_local (HImode, 2);
16377         
16378   ix86_optimize_mode_switching = 1;
16379
16380   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16381   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16382
16383   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16384   DONE;
16385 })
16386
16387 (define_expand "floorxf2"
16388   [(use (match_operand:XF 0 "register_operand" ""))
16389    (use (match_operand:XF 1 "register_operand" ""))]
16390   "TARGET_USE_FANCY_MATH_387
16391    && flag_unsafe_math_optimizations"
16392 {
16393   rtx op2 = assign_386_stack_local (HImode, 1);
16394   rtx op3 = assign_386_stack_local (HImode, 2);
16395         
16396   ix86_optimize_mode_switching = 1;
16397
16398   emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16399   DONE;
16400 })
16401
16402 (define_insn "frndintxf2_ceil"
16403   [(set (match_operand:XF 0 "register_operand" "=f")
16404         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16405          UNSPEC_FRNDINT_CEIL))
16406    (use (match_operand:HI 2 "memory_operand" "m"))
16407    (use (match_operand:HI 3 "memory_operand" "m"))]
16408   "TARGET_USE_FANCY_MATH_387
16409    && flag_unsafe_math_optimizations"
16410   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16411   [(set_attr "type" "frndint")
16412    (set_attr "i387_cw" "ceil")
16413    (set_attr "mode" "XF")])
16414
16415 (define_expand "ceildf2"
16416   [(use (match_operand:DF 0 "register_operand" ""))
16417    (use (match_operand:DF 1 "register_operand" ""))]
16418   "TARGET_USE_FANCY_MATH_387
16419    && flag_unsafe_math_optimizations"
16420 {
16421   rtx op0 = gen_reg_rtx (XFmode);
16422   rtx op1 = gen_reg_rtx (XFmode);
16423   rtx op2 = assign_386_stack_local (HImode, 1);
16424   rtx op3 = assign_386_stack_local (HImode, 2);
16425         
16426   ix86_optimize_mode_switching = 1;
16427
16428   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16429   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16430
16431   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16432   DONE;
16433 })
16434
16435 (define_expand "ceilsf2"
16436   [(use (match_operand:SF 0 "register_operand" ""))
16437    (use (match_operand:SF 1 "register_operand" ""))]
16438   "TARGET_USE_FANCY_MATH_387
16439    && flag_unsafe_math_optimizations"
16440 {
16441   rtx op0 = gen_reg_rtx (XFmode);
16442   rtx op1 = gen_reg_rtx (XFmode);
16443   rtx op2 = assign_386_stack_local (HImode, 1);
16444   rtx op3 = assign_386_stack_local (HImode, 2);
16445         
16446   ix86_optimize_mode_switching = 1;
16447
16448   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16449   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16450
16451   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16452   DONE;
16453 })
16454
16455 (define_expand "ceilxf2"
16456   [(use (match_operand:XF 0 "register_operand" ""))
16457    (use (match_operand:XF 1 "register_operand" ""))]
16458   "TARGET_USE_FANCY_MATH_387
16459    && flag_unsafe_math_optimizations"
16460 {
16461   rtx op2 = assign_386_stack_local (HImode, 1);
16462   rtx op3 = assign_386_stack_local (HImode, 2);
16463         
16464   ix86_optimize_mode_switching = 1;
16465
16466   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16467   DONE;
16468 })
16469
16470 (define_insn "frndintxf2_trunc"
16471   [(set (match_operand:XF 0 "register_operand" "=f")
16472         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16473          UNSPEC_FRNDINT_TRUNC))
16474    (use (match_operand:HI 2 "memory_operand" "m"))
16475    (use (match_operand:HI 3 "memory_operand" "m"))]
16476   "TARGET_USE_FANCY_MATH_387
16477    && flag_unsafe_math_optimizations"
16478   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16479   [(set_attr "type" "frndint")
16480    (set_attr "i387_cw" "trunc")
16481    (set_attr "mode" "XF")])
16482
16483 (define_expand "btruncdf2"
16484   [(use (match_operand:DF 0 "register_operand" ""))
16485    (use (match_operand:DF 1 "register_operand" ""))]
16486   "TARGET_USE_FANCY_MATH_387
16487    && flag_unsafe_math_optimizations"
16488 {
16489   rtx op0 = gen_reg_rtx (XFmode);
16490   rtx op1 = gen_reg_rtx (XFmode);
16491   rtx op2 = assign_386_stack_local (HImode, 1);
16492   rtx op3 = assign_386_stack_local (HImode, 2);
16493         
16494   ix86_optimize_mode_switching = 1;
16495
16496   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16497   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16498
16499   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16500   DONE;
16501 })
16502
16503 (define_expand "btruncsf2"
16504   [(use (match_operand:SF 0 "register_operand" ""))
16505    (use (match_operand:SF 1 "register_operand" ""))]
16506   "TARGET_USE_FANCY_MATH_387
16507    && flag_unsafe_math_optimizations"
16508 {
16509   rtx op0 = gen_reg_rtx (XFmode);
16510   rtx op1 = gen_reg_rtx (XFmode);
16511   rtx op2 = assign_386_stack_local (HImode, 1);
16512   rtx op3 = assign_386_stack_local (HImode, 2);
16513         
16514   ix86_optimize_mode_switching = 1;
16515
16516   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16517   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16518
16519   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16520   DONE;
16521 })
16522
16523 (define_expand "btruncxf2"
16524   [(use (match_operand:XF 0 "register_operand" ""))
16525    (use (match_operand:XF 1 "register_operand" ""))]
16526   "TARGET_USE_FANCY_MATH_387
16527    && flag_unsafe_math_optimizations"
16528 {
16529   rtx op2 = assign_386_stack_local (HImode, 1);
16530   rtx op3 = assign_386_stack_local (HImode, 2);
16531         
16532   ix86_optimize_mode_switching = 1;
16533
16534   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16535   DONE;
16536 })
16537
16538 (define_insn "frndintxf2_mask_pm"
16539   [(set (match_operand:XF 0 "register_operand" "=f")
16540         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16541          UNSPEC_FRNDINT_MASK_PM))
16542    (use (match_operand:HI 2 "memory_operand" "m"))
16543    (use (match_operand:HI 3 "memory_operand" "m"))]
16544   "TARGET_USE_FANCY_MATH_387
16545    && flag_unsafe_math_optimizations"
16546   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16547   [(set_attr "type" "frndint")
16548    (set_attr "i387_cw" "mask_pm")
16549    (set_attr "mode" "XF")])
16550
16551 (define_expand "nearbyintdf2"
16552   [(use (match_operand:DF 0 "register_operand" ""))
16553    (use (match_operand:DF 1 "register_operand" ""))]
16554   "TARGET_USE_FANCY_MATH_387
16555    && flag_unsafe_math_optimizations"
16556 {
16557   rtx op0 = gen_reg_rtx (XFmode);
16558   rtx op1 = gen_reg_rtx (XFmode);
16559   rtx op2 = assign_386_stack_local (HImode, 1);
16560   rtx op3 = assign_386_stack_local (HImode, 2);
16561         
16562   ix86_optimize_mode_switching = 1;
16563
16564   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16565   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16566
16567   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16568   DONE;
16569 })
16570
16571 (define_expand "nearbyintsf2"
16572   [(use (match_operand:SF 0 "register_operand" ""))
16573    (use (match_operand:SF 1 "register_operand" ""))]
16574   "TARGET_USE_FANCY_MATH_387
16575    && flag_unsafe_math_optimizations"
16576 {
16577   rtx op0 = gen_reg_rtx (XFmode);
16578   rtx op1 = gen_reg_rtx (XFmode);
16579   rtx op2 = assign_386_stack_local (HImode, 1);
16580   rtx op3 = assign_386_stack_local (HImode, 2);
16581         
16582   ix86_optimize_mode_switching = 1;
16583
16584   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16585   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16586
16587   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16588   DONE;
16589 })
16590
16591 (define_expand "nearbyintxf2"
16592   [(use (match_operand:XF 0 "register_operand" ""))
16593    (use (match_operand:XF 1 "register_operand" ""))]
16594   "TARGET_USE_FANCY_MATH_387
16595    && flag_unsafe_math_optimizations"
16596 {
16597   rtx op2 = assign_386_stack_local (HImode, 1);
16598   rtx op3 = assign_386_stack_local (HImode, 2);
16599         
16600   ix86_optimize_mode_switching = 1;
16601
16602   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16603                                      op2, op3));
16604   DONE;
16605 })
16606
16607 \f
16608 ;; Block operation instructions
16609
16610 (define_insn "cld"
16611  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16612  ""
16613  "cld"
16614   [(set_attr "type" "cld")])
16615
16616 (define_expand "movmemsi"
16617   [(use (match_operand:BLK 0 "memory_operand" ""))
16618    (use (match_operand:BLK 1 "memory_operand" ""))
16619    (use (match_operand:SI 2 "nonmemory_operand" ""))
16620    (use (match_operand:SI 3 "const_int_operand" ""))]
16621   "! optimize_size"
16622 {
16623  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16624    DONE;
16625  else
16626    FAIL;
16627 })
16628
16629 (define_expand "movmemdi"
16630   [(use (match_operand:BLK 0 "memory_operand" ""))
16631    (use (match_operand:BLK 1 "memory_operand" ""))
16632    (use (match_operand:DI 2 "nonmemory_operand" ""))
16633    (use (match_operand:DI 3 "const_int_operand" ""))]
16634   "TARGET_64BIT"
16635 {
16636  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16637    DONE;
16638  else
16639    FAIL;
16640 })
16641
16642 ;; Most CPUs don't like single string operations
16643 ;; Handle this case here to simplify previous expander.
16644
16645 (define_expand "strmov"
16646   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16647    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16648    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16649               (clobber (reg:CC FLAGS_REG))])
16650    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16651               (clobber (reg:CC FLAGS_REG))])]
16652   ""
16653 {
16654   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16655
16656   /* If .md ever supports :P for Pmode, these can be directly
16657      in the pattern above.  */
16658   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16659   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16660
16661   if (TARGET_SINGLE_STRINGOP || optimize_size)
16662     {
16663       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16664                                       operands[2], operands[3],
16665                                       operands[5], operands[6]));
16666       DONE;
16667     }
16668
16669   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16670 })
16671
16672 (define_expand "strmov_singleop"
16673   [(parallel [(set (match_operand 1 "memory_operand" "")
16674                    (match_operand 3 "memory_operand" ""))
16675               (set (match_operand 0 "register_operand" "")
16676                    (match_operand 4 "" ""))
16677               (set (match_operand 2 "register_operand" "")
16678                    (match_operand 5 "" ""))
16679               (use (reg:SI DIRFLAG_REG))])]
16680   "TARGET_SINGLE_STRINGOP || optimize_size"
16681   "")
16682
16683 (define_insn "*strmovdi_rex_1"
16684   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16685         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16686    (set (match_operand:DI 0 "register_operand" "=D")
16687         (plus:DI (match_dup 2)
16688                  (const_int 8)))
16689    (set (match_operand:DI 1 "register_operand" "=S")
16690         (plus:DI (match_dup 3)
16691                  (const_int 8)))
16692    (use (reg:SI DIRFLAG_REG))]
16693   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16694   "movsq"
16695   [(set_attr "type" "str")
16696    (set_attr "mode" "DI")
16697    (set_attr "memory" "both")])
16698
16699 (define_insn "*strmovsi_1"
16700   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16701         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16702    (set (match_operand:SI 0 "register_operand" "=D")
16703         (plus:SI (match_dup 2)
16704                  (const_int 4)))
16705    (set (match_operand:SI 1 "register_operand" "=S")
16706         (plus:SI (match_dup 3)
16707                  (const_int 4)))
16708    (use (reg:SI DIRFLAG_REG))]
16709   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16710   "{movsl|movsd}"
16711   [(set_attr "type" "str")
16712    (set_attr "mode" "SI")
16713    (set_attr "memory" "both")])
16714
16715 (define_insn "*strmovsi_rex_1"
16716   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16717         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16718    (set (match_operand:DI 0 "register_operand" "=D")
16719         (plus:DI (match_dup 2)
16720                  (const_int 4)))
16721    (set (match_operand:DI 1 "register_operand" "=S")
16722         (plus:DI (match_dup 3)
16723                  (const_int 4)))
16724    (use (reg:SI DIRFLAG_REG))]
16725   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16726   "{movsl|movsd}"
16727   [(set_attr "type" "str")
16728    (set_attr "mode" "SI")
16729    (set_attr "memory" "both")])
16730
16731 (define_insn "*strmovhi_1"
16732   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16733         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16734    (set (match_operand:SI 0 "register_operand" "=D")
16735         (plus:SI (match_dup 2)
16736                  (const_int 2)))
16737    (set (match_operand:SI 1 "register_operand" "=S")
16738         (plus:SI (match_dup 3)
16739                  (const_int 2)))
16740    (use (reg:SI DIRFLAG_REG))]
16741   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16742   "movsw"
16743   [(set_attr "type" "str")
16744    (set_attr "memory" "both")
16745    (set_attr "mode" "HI")])
16746
16747 (define_insn "*strmovhi_rex_1"
16748   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16749         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16750    (set (match_operand:DI 0 "register_operand" "=D")
16751         (plus:DI (match_dup 2)
16752                  (const_int 2)))
16753    (set (match_operand:DI 1 "register_operand" "=S")
16754         (plus:DI (match_dup 3)
16755                  (const_int 2)))
16756    (use (reg:SI DIRFLAG_REG))]
16757   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16758   "movsw"
16759   [(set_attr "type" "str")
16760    (set_attr "memory" "both")
16761    (set_attr "mode" "HI")])
16762
16763 (define_insn "*strmovqi_1"
16764   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16765         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16766    (set (match_operand:SI 0 "register_operand" "=D")
16767         (plus:SI (match_dup 2)
16768                  (const_int 1)))
16769    (set (match_operand:SI 1 "register_operand" "=S")
16770         (plus:SI (match_dup 3)
16771                  (const_int 1)))
16772    (use (reg:SI DIRFLAG_REG))]
16773   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16774   "movsb"
16775   [(set_attr "type" "str")
16776    (set_attr "memory" "both")
16777    (set_attr "mode" "QI")])
16778
16779 (define_insn "*strmovqi_rex_1"
16780   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16781         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16782    (set (match_operand:DI 0 "register_operand" "=D")
16783         (plus:DI (match_dup 2)
16784                  (const_int 1)))
16785    (set (match_operand:DI 1 "register_operand" "=S")
16786         (plus:DI (match_dup 3)
16787                  (const_int 1)))
16788    (use (reg:SI DIRFLAG_REG))]
16789   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16790   "movsb"
16791   [(set_attr "type" "str")
16792    (set_attr "memory" "both")
16793    (set_attr "mode" "QI")])
16794
16795 (define_expand "rep_mov"
16796   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16797               (set (match_operand 0 "register_operand" "")
16798                    (match_operand 5 "" ""))
16799               (set (match_operand 2 "register_operand" "")
16800                    (match_operand 6 "" ""))
16801               (set (match_operand 1 "memory_operand" "")
16802                    (match_operand 3 "memory_operand" ""))
16803               (use (match_dup 4))
16804               (use (reg:SI DIRFLAG_REG))])]
16805   ""
16806   "")
16807
16808 (define_insn "*rep_movdi_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 (ashift:DI (match_operand:DI 5 "register_operand" "2")
16812                             (const_int 3))
16813                  (match_operand:DI 3 "register_operand" "0")))
16814    (set (match_operand:DI 1 "register_operand" "=S") 
16815         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16816                  (match_operand:DI 4 "register_operand" "1")))
16817    (set (mem:BLK (match_dup 3))
16818         (mem:BLK (match_dup 4)))
16819    (use (match_dup 5))
16820    (use (reg:SI DIRFLAG_REG))]
16821   "TARGET_64BIT"
16822   "{rep\;movsq|rep movsq}"
16823   [(set_attr "type" "str")
16824    (set_attr "prefix_rep" "1")
16825    (set_attr "memory" "both")
16826    (set_attr "mode" "DI")])
16827
16828 (define_insn "*rep_movsi"
16829   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16830    (set (match_operand:SI 0 "register_operand" "=D") 
16831         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16832                             (const_int 2))
16833                  (match_operand:SI 3 "register_operand" "0")))
16834    (set (match_operand:SI 1 "register_operand" "=S") 
16835         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16836                  (match_operand:SI 4 "register_operand" "1")))
16837    (set (mem:BLK (match_dup 3))
16838         (mem:BLK (match_dup 4)))
16839    (use (match_dup 5))
16840    (use (reg:SI DIRFLAG_REG))]
16841   "!TARGET_64BIT"
16842   "{rep\;movsl|rep movsd}"
16843   [(set_attr "type" "str")
16844    (set_attr "prefix_rep" "1")
16845    (set_attr "memory" "both")
16846    (set_attr "mode" "SI")])
16847
16848 (define_insn "*rep_movsi_rex64"
16849   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16850    (set (match_operand:DI 0 "register_operand" "=D") 
16851         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16852                             (const_int 2))
16853                  (match_operand:DI 3 "register_operand" "0")))
16854    (set (match_operand:DI 1 "register_operand" "=S") 
16855         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16856                  (match_operand:DI 4 "register_operand" "1")))
16857    (set (mem:BLK (match_dup 3))
16858         (mem:BLK (match_dup 4)))
16859    (use (match_dup 5))
16860    (use (reg:SI DIRFLAG_REG))]
16861   "TARGET_64BIT"
16862   "{rep\;movsl|rep movsd}"
16863   [(set_attr "type" "str")
16864    (set_attr "prefix_rep" "1")
16865    (set_attr "memory" "both")
16866    (set_attr "mode" "SI")])
16867
16868 (define_insn "*rep_movqi"
16869   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16870    (set (match_operand:SI 0 "register_operand" "=D") 
16871         (plus:SI (match_operand:SI 3 "register_operand" "0")
16872                  (match_operand:SI 5 "register_operand" "2")))
16873    (set (match_operand:SI 1 "register_operand" "=S") 
16874         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16875    (set (mem:BLK (match_dup 3))
16876         (mem:BLK (match_dup 4)))
16877    (use (match_dup 5))
16878    (use (reg:SI DIRFLAG_REG))]
16879   "!TARGET_64BIT"
16880   "{rep\;movsb|rep movsb}"
16881   [(set_attr "type" "str")
16882    (set_attr "prefix_rep" "1")
16883    (set_attr "memory" "both")
16884    (set_attr "mode" "SI")])
16885
16886 (define_insn "*rep_movqi_rex64"
16887   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16888    (set (match_operand:DI 0 "register_operand" "=D") 
16889         (plus:DI (match_operand:DI 3 "register_operand" "0")
16890                  (match_operand:DI 5 "register_operand" "2")))
16891    (set (match_operand:DI 1 "register_operand" "=S") 
16892         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16893    (set (mem:BLK (match_dup 3))
16894         (mem:BLK (match_dup 4)))
16895    (use (match_dup 5))
16896    (use (reg:SI DIRFLAG_REG))]
16897   "TARGET_64BIT"
16898   "{rep\;movsb|rep movsb}"
16899   [(set_attr "type" "str")
16900    (set_attr "prefix_rep" "1")
16901    (set_attr "memory" "both")
16902    (set_attr "mode" "SI")])
16903
16904 (define_expand "clrmemsi"
16905    [(use (match_operand:BLK 0 "memory_operand" ""))
16906     (use (match_operand:SI 1 "nonmemory_operand" ""))
16907     (use (match_operand 2 "const_int_operand" ""))]
16908   ""
16909 {
16910  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16911    DONE;
16912  else
16913    FAIL;
16914 })
16915
16916 (define_expand "clrmemdi"
16917    [(use (match_operand:BLK 0 "memory_operand" ""))
16918     (use (match_operand:DI 1 "nonmemory_operand" ""))
16919     (use (match_operand 2 "const_int_operand" ""))]
16920   "TARGET_64BIT"
16921 {
16922  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16923    DONE;
16924  else
16925    FAIL;
16926 })
16927
16928 ;; Most CPUs don't like single string operations
16929 ;; Handle this case here to simplify previous expander.
16930
16931 (define_expand "strset"
16932   [(set (match_operand 1 "memory_operand" "")
16933         (match_operand 2 "register_operand" ""))
16934    (parallel [(set (match_operand 0 "register_operand" "")
16935                    (match_dup 3))
16936               (clobber (reg:CC FLAGS_REG))])]
16937   ""
16938 {
16939   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16940     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16941
16942   /* If .md ever supports :P for Pmode, this can be directly
16943      in the pattern above.  */
16944   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16945                               GEN_INT (GET_MODE_SIZE (GET_MODE
16946                                                       (operands[2]))));
16947   if (TARGET_SINGLE_STRINGOP || optimize_size)
16948     {
16949       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16950                                       operands[3]));
16951       DONE;
16952     }
16953 })
16954
16955 (define_expand "strset_singleop"
16956   [(parallel [(set (match_operand 1 "memory_operand" "")
16957                    (match_operand 2 "register_operand" ""))
16958               (set (match_operand 0 "register_operand" "")
16959                    (match_operand 3 "" ""))
16960               (use (reg:SI DIRFLAG_REG))])]
16961   "TARGET_SINGLE_STRINGOP || optimize_size"
16962   "")
16963
16964 (define_insn "*strsetdi_rex_1"
16965   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16966         (match_operand:DI 2 "register_operand" "a"))
16967    (set (match_operand:DI 0 "register_operand" "=D")
16968         (plus:DI (match_dup 1)
16969                  (const_int 8)))
16970    (use (reg:SI DIRFLAG_REG))]
16971   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16972   "stosq"
16973   [(set_attr "type" "str")
16974    (set_attr "memory" "store")
16975    (set_attr "mode" "DI")])
16976
16977 (define_insn "*strsetsi_1"
16978   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16979         (match_operand:SI 2 "register_operand" "a"))
16980    (set (match_operand:SI 0 "register_operand" "=D")
16981         (plus:SI (match_dup 1)
16982                  (const_int 4)))
16983    (use (reg:SI DIRFLAG_REG))]
16984   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16985   "{stosl|stosd}"
16986   [(set_attr "type" "str")
16987    (set_attr "memory" "store")
16988    (set_attr "mode" "SI")])
16989
16990 (define_insn "*strsetsi_rex_1"
16991   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16992         (match_operand:SI 2 "register_operand" "a"))
16993    (set (match_operand:DI 0 "register_operand" "=D")
16994         (plus:DI (match_dup 1)
16995                  (const_int 4)))
16996    (use (reg:SI DIRFLAG_REG))]
16997   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16998   "{stosl|stosd}"
16999   [(set_attr "type" "str")
17000    (set_attr "memory" "store")
17001    (set_attr "mode" "SI")])
17002
17003 (define_insn "*strsethi_1"
17004   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17005         (match_operand:HI 2 "register_operand" "a"))
17006    (set (match_operand:SI 0 "register_operand" "=D")
17007         (plus:SI (match_dup 1)
17008                  (const_int 2)))
17009    (use (reg:SI DIRFLAG_REG))]
17010   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17011   "stosw"
17012   [(set_attr "type" "str")
17013    (set_attr "memory" "store")
17014    (set_attr "mode" "HI")])
17015
17016 (define_insn "*strsethi_rex_1"
17017   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17018         (match_operand:HI 2 "register_operand" "a"))
17019    (set (match_operand:DI 0 "register_operand" "=D")
17020         (plus:DI (match_dup 1)
17021                  (const_int 2)))
17022    (use (reg:SI DIRFLAG_REG))]
17023   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17024   "stosw"
17025   [(set_attr "type" "str")
17026    (set_attr "memory" "store")
17027    (set_attr "mode" "HI")])
17028
17029 (define_insn "*strsetqi_1"
17030   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17031         (match_operand:QI 2 "register_operand" "a"))
17032    (set (match_operand:SI 0 "register_operand" "=D")
17033         (plus:SI (match_dup 1)
17034                  (const_int 1)))
17035    (use (reg:SI DIRFLAG_REG))]
17036   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17037   "stosb"
17038   [(set_attr "type" "str")
17039    (set_attr "memory" "store")
17040    (set_attr "mode" "QI")])
17041
17042 (define_insn "*strsetqi_rex_1"
17043   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17044         (match_operand:QI 2 "register_operand" "a"))
17045    (set (match_operand:DI 0 "register_operand" "=D")
17046         (plus:DI (match_dup 1)
17047                  (const_int 1)))
17048    (use (reg:SI DIRFLAG_REG))]
17049   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17050   "stosb"
17051   [(set_attr "type" "str")
17052    (set_attr "memory" "store")
17053    (set_attr "mode" "QI")])
17054
17055 (define_expand "rep_stos"
17056   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17057               (set (match_operand 0 "register_operand" "")
17058                    (match_operand 4 "" ""))
17059               (set (match_operand 2 "memory_operand" "") (const_int 0))
17060               (use (match_operand 3 "register_operand" ""))
17061               (use (match_dup 1))
17062               (use (reg:SI DIRFLAG_REG))])]
17063   ""
17064   "")
17065
17066 (define_insn "*rep_stosdi_rex64"
17067   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17068    (set (match_operand:DI 0 "register_operand" "=D") 
17069         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17070                             (const_int 3))
17071                  (match_operand:DI 3 "register_operand" "0")))
17072    (set (mem:BLK (match_dup 3))
17073         (const_int 0))
17074    (use (match_operand:DI 2 "register_operand" "a"))
17075    (use (match_dup 4))
17076    (use (reg:SI DIRFLAG_REG))]
17077   "TARGET_64BIT"
17078   "{rep\;stosq|rep stosq}"
17079   [(set_attr "type" "str")
17080    (set_attr "prefix_rep" "1")
17081    (set_attr "memory" "store")
17082    (set_attr "mode" "DI")])
17083
17084 (define_insn "*rep_stossi"
17085   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17086    (set (match_operand:SI 0 "register_operand" "=D") 
17087         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17088                             (const_int 2))
17089                  (match_operand:SI 3 "register_operand" "0")))
17090    (set (mem:BLK (match_dup 3))
17091         (const_int 0))
17092    (use (match_operand:SI 2 "register_operand" "a"))
17093    (use (match_dup 4))
17094    (use (reg:SI DIRFLAG_REG))]
17095   "!TARGET_64BIT"
17096   "{rep\;stosl|rep stosd}"
17097   [(set_attr "type" "str")
17098    (set_attr "prefix_rep" "1")
17099    (set_attr "memory" "store")
17100    (set_attr "mode" "SI")])
17101
17102 (define_insn "*rep_stossi_rex64"
17103   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17104    (set (match_operand:DI 0 "register_operand" "=D") 
17105         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17106                             (const_int 2))
17107                  (match_operand:DI 3 "register_operand" "0")))
17108    (set (mem:BLK (match_dup 3))
17109         (const_int 0))
17110    (use (match_operand:SI 2 "register_operand" "a"))
17111    (use (match_dup 4))
17112    (use (reg:SI DIRFLAG_REG))]
17113   "TARGET_64BIT"
17114   "{rep\;stosl|rep stosd}"
17115   [(set_attr "type" "str")
17116    (set_attr "prefix_rep" "1")
17117    (set_attr "memory" "store")
17118    (set_attr "mode" "SI")])
17119
17120 (define_insn "*rep_stosqi"
17121   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17122    (set (match_operand:SI 0 "register_operand" "=D") 
17123         (plus:SI (match_operand:SI 3 "register_operand" "0")
17124                  (match_operand:SI 4 "register_operand" "1")))
17125    (set (mem:BLK (match_dup 3))
17126         (const_int 0))
17127    (use (match_operand:QI 2 "register_operand" "a"))
17128    (use (match_dup 4))
17129    (use (reg:SI DIRFLAG_REG))]
17130   "!TARGET_64BIT"
17131   "{rep\;stosb|rep stosb}"
17132   [(set_attr "type" "str")
17133    (set_attr "prefix_rep" "1")
17134    (set_attr "memory" "store")
17135    (set_attr "mode" "QI")])
17136
17137 (define_insn "*rep_stosqi_rex64"
17138   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17139    (set (match_operand:DI 0 "register_operand" "=D") 
17140         (plus:DI (match_operand:DI 3 "register_operand" "0")
17141                  (match_operand:DI 4 "register_operand" "1")))
17142    (set (mem:BLK (match_dup 3))
17143         (const_int 0))
17144    (use (match_operand:QI 2 "register_operand" "a"))
17145    (use (match_dup 4))
17146    (use (reg:SI DIRFLAG_REG))]
17147   "TARGET_64BIT"
17148   "{rep\;stosb|rep stosb}"
17149   [(set_attr "type" "str")
17150    (set_attr "prefix_rep" "1")
17151    (set_attr "memory" "store")
17152    (set_attr "mode" "QI")])
17153
17154 (define_expand "cmpstrsi"
17155   [(set (match_operand:SI 0 "register_operand" "")
17156         (compare:SI (match_operand:BLK 1 "general_operand" "")
17157                     (match_operand:BLK 2 "general_operand" "")))
17158    (use (match_operand 3 "general_operand" ""))
17159    (use (match_operand 4 "immediate_operand" ""))]
17160   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17161 {
17162   rtx addr1, addr2, out, outlow, count, countreg, align;
17163
17164   /* Can't use this if the user has appropriated esi or edi.  */
17165   if (global_regs[4] || global_regs[5])
17166     FAIL;
17167
17168   out = operands[0];
17169   if (GET_CODE (out) != REG)
17170     out = gen_reg_rtx (SImode);
17171
17172   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17173   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17174   if (addr1 != XEXP (operands[1], 0))
17175     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17176   if (addr2 != XEXP (operands[2], 0))
17177     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17178
17179   count = operands[3];
17180   countreg = ix86_zero_extend_to_Pmode (count);
17181
17182   /* %%% Iff we are testing strict equality, we can use known alignment
17183      to good advantage.  This may be possible with combine, particularly
17184      once cc0 is dead.  */
17185   align = operands[4];
17186
17187   emit_insn (gen_cld ());
17188   if (GET_CODE (count) == CONST_INT)
17189     {
17190       if (INTVAL (count) == 0)
17191         {
17192           emit_move_insn (operands[0], const0_rtx);
17193           DONE;
17194         }
17195       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17196                                     operands[1], operands[2]));
17197     }
17198   else
17199     {
17200       if (TARGET_64BIT)
17201         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17202       else
17203         emit_insn (gen_cmpsi_1 (countreg, countreg));
17204       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17205                                  operands[1], operands[2]));
17206     }
17207
17208   outlow = gen_lowpart (QImode, out);
17209   emit_insn (gen_cmpintqi (outlow));
17210   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17211
17212   if (operands[0] != out)
17213     emit_move_insn (operands[0], out);
17214
17215   DONE;
17216 })
17217
17218 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17219
17220 (define_expand "cmpintqi"
17221   [(set (match_dup 1)
17222         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17223    (set (match_dup 2)
17224         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17225    (parallel [(set (match_operand:QI 0 "register_operand" "")
17226                    (minus:QI (match_dup 1)
17227                              (match_dup 2)))
17228               (clobber (reg:CC FLAGS_REG))])]
17229   ""
17230   "operands[1] = gen_reg_rtx (QImode);
17231    operands[2] = gen_reg_rtx (QImode);")
17232
17233 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17234 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17235
17236 (define_expand "cmpstrqi_nz_1"
17237   [(parallel [(set (reg:CC FLAGS_REG)
17238                    (compare:CC (match_operand 4 "memory_operand" "")
17239                                (match_operand 5 "memory_operand" "")))
17240               (use (match_operand 2 "register_operand" ""))
17241               (use (match_operand:SI 3 "immediate_operand" ""))
17242               (use (reg:SI DIRFLAG_REG))
17243               (clobber (match_operand 0 "register_operand" ""))
17244               (clobber (match_operand 1 "register_operand" ""))
17245               (clobber (match_dup 2))])]
17246   ""
17247   "")
17248
17249 (define_insn "*cmpstrqi_nz_1"
17250   [(set (reg:CC FLAGS_REG)
17251         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17252                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17253    (use (match_operand:SI 6 "register_operand" "2"))
17254    (use (match_operand:SI 3 "immediate_operand" "i"))
17255    (use (reg:SI DIRFLAG_REG))
17256    (clobber (match_operand:SI 0 "register_operand" "=S"))
17257    (clobber (match_operand:SI 1 "register_operand" "=D"))
17258    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17259   "!TARGET_64BIT"
17260   "repz{\;| }cmpsb"
17261   [(set_attr "type" "str")
17262    (set_attr "mode" "QI")
17263    (set_attr "prefix_rep" "1")])
17264
17265 (define_insn "*cmpstrqi_nz_rex_1"
17266   [(set (reg:CC FLAGS_REG)
17267         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17268                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17269    (use (match_operand:DI 6 "register_operand" "2"))
17270    (use (match_operand:SI 3 "immediate_operand" "i"))
17271    (use (reg:SI DIRFLAG_REG))
17272    (clobber (match_operand:DI 0 "register_operand" "=S"))
17273    (clobber (match_operand:DI 1 "register_operand" "=D"))
17274    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17275   "TARGET_64BIT"
17276   "repz{\;| }cmpsb"
17277   [(set_attr "type" "str")
17278    (set_attr "mode" "QI")
17279    (set_attr "prefix_rep" "1")])
17280
17281 ;; The same, but the count is not known to not be zero.
17282
17283 (define_expand "cmpstrqi_1"
17284   [(parallel [(set (reg:CC FLAGS_REG)
17285                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17286                                      (const_int 0))
17287                   (compare:CC (match_operand 4 "memory_operand" "")
17288                               (match_operand 5 "memory_operand" ""))
17289                   (const_int 0)))
17290               (use (match_operand:SI 3 "immediate_operand" ""))
17291               (use (reg:CC FLAGS_REG))
17292               (use (reg:SI DIRFLAG_REG))
17293               (clobber (match_operand 0 "register_operand" ""))
17294               (clobber (match_operand 1 "register_operand" ""))
17295               (clobber (match_dup 2))])]
17296   ""
17297   "")
17298
17299 (define_insn "*cmpstrqi_1"
17300   [(set (reg:CC FLAGS_REG)
17301         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17302                              (const_int 0))
17303           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17304                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17305           (const_int 0)))
17306    (use (match_operand:SI 3 "immediate_operand" "i"))
17307    (use (reg:CC FLAGS_REG))
17308    (use (reg:SI DIRFLAG_REG))
17309    (clobber (match_operand:SI 0 "register_operand" "=S"))
17310    (clobber (match_operand:SI 1 "register_operand" "=D"))
17311    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17312   "!TARGET_64BIT"
17313   "repz{\;| }cmpsb"
17314   [(set_attr "type" "str")
17315    (set_attr "mode" "QI")
17316    (set_attr "prefix_rep" "1")])
17317
17318 (define_insn "*cmpstrqi_rex_1"
17319   [(set (reg:CC FLAGS_REG)
17320         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17321                              (const_int 0))
17322           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17323                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17324           (const_int 0)))
17325    (use (match_operand:SI 3 "immediate_operand" "i"))
17326    (use (reg:CC FLAGS_REG))
17327    (use (reg:SI DIRFLAG_REG))
17328    (clobber (match_operand:DI 0 "register_operand" "=S"))
17329    (clobber (match_operand:DI 1 "register_operand" "=D"))
17330    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17331   "TARGET_64BIT"
17332   "repz{\;| }cmpsb"
17333   [(set_attr "type" "str")
17334    (set_attr "mode" "QI")
17335    (set_attr "prefix_rep" "1")])
17336
17337 (define_expand "strlensi"
17338   [(set (match_operand:SI 0 "register_operand" "")
17339         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17340                     (match_operand:QI 2 "immediate_operand" "")
17341                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17342   ""
17343 {
17344  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17345    DONE;
17346  else
17347    FAIL;
17348 })
17349
17350 (define_expand "strlendi"
17351   [(set (match_operand:DI 0 "register_operand" "")
17352         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17353                     (match_operand:QI 2 "immediate_operand" "")
17354                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17355   ""
17356 {
17357  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17358    DONE;
17359  else
17360    FAIL;
17361 })
17362
17363 (define_expand "strlenqi_1"
17364   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17365               (use (reg:SI DIRFLAG_REG))
17366               (clobber (match_operand 1 "register_operand" ""))
17367               (clobber (reg:CC FLAGS_REG))])]
17368   ""
17369   "")
17370
17371 (define_insn "*strlenqi_1"
17372   [(set (match_operand:SI 0 "register_operand" "=&c")
17373         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17374                     (match_operand:QI 2 "register_operand" "a")
17375                     (match_operand:SI 3 "immediate_operand" "i")
17376                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17377    (use (reg:SI DIRFLAG_REG))
17378    (clobber (match_operand:SI 1 "register_operand" "=D"))
17379    (clobber (reg:CC FLAGS_REG))]
17380   "!TARGET_64BIT"
17381   "repnz{\;| }scasb"
17382   [(set_attr "type" "str")
17383    (set_attr "mode" "QI")
17384    (set_attr "prefix_rep" "1")])
17385
17386 (define_insn "*strlenqi_rex_1"
17387   [(set (match_operand:DI 0 "register_operand" "=&c")
17388         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17389                     (match_operand:QI 2 "register_operand" "a")
17390                     (match_operand:DI 3 "immediate_operand" "i")
17391                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17392    (use (reg:SI DIRFLAG_REG))
17393    (clobber (match_operand:DI 1 "register_operand" "=D"))
17394    (clobber (reg:CC FLAGS_REG))]
17395   "TARGET_64BIT"
17396   "repnz{\;| }scasb"
17397   [(set_attr "type" "str")
17398    (set_attr "mode" "QI")
17399    (set_attr "prefix_rep" "1")])
17400
17401 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17402 ;; handled in combine, but it is not currently up to the task.
17403 ;; When used for their truth value, the cmpstr* expanders generate
17404 ;; code like this:
17405 ;;
17406 ;;   repz cmpsb
17407 ;;   seta       %al
17408 ;;   setb       %dl
17409 ;;   cmpb       %al, %dl
17410 ;;   jcc        label
17411 ;;
17412 ;; The intermediate three instructions are unnecessary.
17413
17414 ;; This one handles cmpstr*_nz_1...
17415 (define_peephole2
17416   [(parallel[
17417      (set (reg:CC FLAGS_REG)
17418           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17419                       (mem:BLK (match_operand 5 "register_operand" ""))))
17420      (use (match_operand 6 "register_operand" ""))
17421      (use (match_operand:SI 3 "immediate_operand" ""))
17422      (use (reg:SI DIRFLAG_REG))
17423      (clobber (match_operand 0 "register_operand" ""))
17424      (clobber (match_operand 1 "register_operand" ""))
17425      (clobber (match_operand 2 "register_operand" ""))])
17426    (set (match_operand:QI 7 "register_operand" "")
17427         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17428    (set (match_operand:QI 8 "register_operand" "")
17429         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17430    (set (reg FLAGS_REG)
17431         (compare (match_dup 7) (match_dup 8)))
17432   ]
17433   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17434   [(parallel[
17435      (set (reg:CC FLAGS_REG)
17436           (compare:CC (mem:BLK (match_dup 4))
17437                       (mem:BLK (match_dup 5))))
17438      (use (match_dup 6))
17439      (use (match_dup 3))
17440      (use (reg:SI DIRFLAG_REG))
17441      (clobber (match_dup 0))
17442      (clobber (match_dup 1))
17443      (clobber (match_dup 2))])]
17444   "")
17445
17446 ;; ...and this one handles cmpstr*_1.
17447 (define_peephole2
17448   [(parallel[
17449      (set (reg:CC FLAGS_REG)
17450           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17451                                (const_int 0))
17452             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17453                         (mem:BLK (match_operand 5 "register_operand" "")))
17454             (const_int 0)))
17455      (use (match_operand:SI 3 "immediate_operand" ""))
17456      (use (reg:CC FLAGS_REG))
17457      (use (reg:SI DIRFLAG_REG))
17458      (clobber (match_operand 0 "register_operand" ""))
17459      (clobber (match_operand 1 "register_operand" ""))
17460      (clobber (match_operand 2 "register_operand" ""))])
17461    (set (match_operand:QI 7 "register_operand" "")
17462         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17463    (set (match_operand:QI 8 "register_operand" "")
17464         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17465    (set (reg FLAGS_REG)
17466         (compare (match_dup 7) (match_dup 8)))
17467   ]
17468   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17469   [(parallel[
17470      (set (reg:CC FLAGS_REG)
17471           (if_then_else:CC (ne (match_dup 6)
17472                                (const_int 0))
17473             (compare:CC (mem:BLK (match_dup 4))
17474                         (mem:BLK (match_dup 5)))
17475             (const_int 0)))
17476      (use (match_dup 3))
17477      (use (reg:CC FLAGS_REG))
17478      (use (reg:SI DIRFLAG_REG))
17479      (clobber (match_dup 0))
17480      (clobber (match_dup 1))
17481      (clobber (match_dup 2))])]
17482   "")
17483
17484
17485 \f
17486 ;; Conditional move instructions.
17487
17488 (define_expand "movdicc"
17489   [(set (match_operand:DI 0 "register_operand" "")
17490         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17491                          (match_operand:DI 2 "general_operand" "")
17492                          (match_operand:DI 3 "general_operand" "")))]
17493   "TARGET_64BIT"
17494   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17495
17496 (define_insn "x86_movdicc_0_m1_rex64"
17497   [(set (match_operand:DI 0 "register_operand" "=r")
17498         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17499           (const_int -1)
17500           (const_int 0)))
17501    (clobber (reg:CC FLAGS_REG))]
17502   "TARGET_64BIT"
17503   "sbb{q}\t%0, %0"
17504   ; Since we don't have the proper number of operands for an alu insn,
17505   ; fill in all the blanks.
17506   [(set_attr "type" "alu")
17507    (set_attr "pent_pair" "pu")
17508    (set_attr "memory" "none")
17509    (set_attr "imm_disp" "false")
17510    (set_attr "mode" "DI")
17511    (set_attr "length_immediate" "0")])
17512
17513 (define_insn "movdicc_c_rex64"
17514   [(set (match_operand:DI 0 "register_operand" "=r,r")
17515         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17516                                 [(reg FLAGS_REG) (const_int 0)])
17517                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17518                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17519   "TARGET_64BIT && TARGET_CMOVE
17520    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17521   "@
17522    cmov%O2%C1\t{%2, %0|%0, %2}
17523    cmov%O2%c1\t{%3, %0|%0, %3}"
17524   [(set_attr "type" "icmov")
17525    (set_attr "mode" "DI")])
17526
17527 (define_expand "movsicc"
17528   [(set (match_operand:SI 0 "register_operand" "")
17529         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17530                          (match_operand:SI 2 "general_operand" "")
17531                          (match_operand:SI 3 "general_operand" "")))]
17532   ""
17533   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17534
17535 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17536 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17537 ;; So just document what we're doing explicitly.
17538
17539 (define_insn "x86_movsicc_0_m1"
17540   [(set (match_operand:SI 0 "register_operand" "=r")
17541         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17542           (const_int -1)
17543           (const_int 0)))
17544    (clobber (reg:CC FLAGS_REG))]
17545   ""
17546   "sbb{l}\t%0, %0"
17547   ; Since we don't have the proper number of operands for an alu insn,
17548   ; fill in all the blanks.
17549   [(set_attr "type" "alu")
17550    (set_attr "pent_pair" "pu")
17551    (set_attr "memory" "none")
17552    (set_attr "imm_disp" "false")
17553    (set_attr "mode" "SI")
17554    (set_attr "length_immediate" "0")])
17555
17556 (define_insn "*movsicc_noc"
17557   [(set (match_operand:SI 0 "register_operand" "=r,r")
17558         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17559                                 [(reg FLAGS_REG) (const_int 0)])
17560                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17561                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17562   "TARGET_CMOVE
17563    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17564   "@
17565    cmov%O2%C1\t{%2, %0|%0, %2}
17566    cmov%O2%c1\t{%3, %0|%0, %3}"
17567   [(set_attr "type" "icmov")
17568    (set_attr "mode" "SI")])
17569
17570 (define_expand "movhicc"
17571   [(set (match_operand:HI 0 "register_operand" "")
17572         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17573                          (match_operand:HI 2 "general_operand" "")
17574                          (match_operand:HI 3 "general_operand" "")))]
17575   "TARGET_HIMODE_MATH"
17576   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17577
17578 (define_insn "*movhicc_noc"
17579   [(set (match_operand:HI 0 "register_operand" "=r,r")
17580         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17581                                 [(reg FLAGS_REG) (const_int 0)])
17582                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17583                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17584   "TARGET_CMOVE
17585    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17586   "@
17587    cmov%O2%C1\t{%2, %0|%0, %2}
17588    cmov%O2%c1\t{%3, %0|%0, %3}"
17589   [(set_attr "type" "icmov")
17590    (set_attr "mode" "HI")])
17591
17592 (define_expand "movqicc"
17593   [(set (match_operand:QI 0 "register_operand" "")
17594         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17595                          (match_operand:QI 2 "general_operand" "")
17596                          (match_operand:QI 3 "general_operand" "")))]
17597   "TARGET_QIMODE_MATH"
17598   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17599
17600 (define_insn_and_split "*movqicc_noc"
17601   [(set (match_operand:QI 0 "register_operand" "=r,r")
17602         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17603                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17604                       (match_operand:QI 2 "register_operand" "r,0")
17605                       (match_operand:QI 3 "register_operand" "0,r")))]
17606   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17607   "#"
17608   "&& reload_completed"
17609   [(set (match_dup 0)
17610         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17611                       (match_dup 2)
17612                       (match_dup 3)))]
17613   "operands[0] = gen_lowpart (SImode, operands[0]);
17614    operands[2] = gen_lowpart (SImode, operands[2]);
17615    operands[3] = gen_lowpart (SImode, operands[3]);"
17616   [(set_attr "type" "icmov")
17617    (set_attr "mode" "SI")])
17618
17619 (define_expand "movsfcc"
17620   [(set (match_operand:SF 0 "register_operand" "")
17621         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17622                          (match_operand:SF 2 "register_operand" "")
17623                          (match_operand:SF 3 "register_operand" "")))]
17624   "TARGET_CMOVE"
17625   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17626
17627 (define_insn "*movsfcc_1"
17628   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17629         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17630                                 [(reg FLAGS_REG) (const_int 0)])
17631                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17632                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17633   "TARGET_CMOVE
17634    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17635   "@
17636    fcmov%F1\t{%2, %0|%0, %2}
17637    fcmov%f1\t{%3, %0|%0, %3}
17638    cmov%O2%C1\t{%2, %0|%0, %2}
17639    cmov%O2%c1\t{%3, %0|%0, %3}"
17640   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17641    (set_attr "mode" "SF,SF,SI,SI")])
17642
17643 (define_expand "movdfcc"
17644   [(set (match_operand:DF 0 "register_operand" "")
17645         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17646                          (match_operand:DF 2 "register_operand" "")
17647                          (match_operand:DF 3 "register_operand" "")))]
17648   "TARGET_CMOVE"
17649   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17650
17651 (define_insn "*movdfcc_1"
17652   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17653         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17654                                 [(reg FLAGS_REG) (const_int 0)])
17655                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17656                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17657   "!TARGET_64BIT && TARGET_CMOVE
17658    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17659   "@
17660    fcmov%F1\t{%2, %0|%0, %2}
17661    fcmov%f1\t{%3, %0|%0, %3}
17662    #
17663    #"
17664   [(set_attr "type" "fcmov,fcmov,multi,multi")
17665    (set_attr "mode" "DF")])
17666
17667 (define_insn "*movdfcc_1_rex64"
17668   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17669         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17670                                 [(reg FLAGS_REG) (const_int 0)])
17671                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17672                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17673   "TARGET_64BIT && TARGET_CMOVE
17674    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17675   "@
17676    fcmov%F1\t{%2, %0|%0, %2}
17677    fcmov%f1\t{%3, %0|%0, %3}
17678    cmov%O2%C1\t{%2, %0|%0, %2}
17679    cmov%O2%c1\t{%3, %0|%0, %3}"
17680   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17681    (set_attr "mode" "DF")])
17682
17683 (define_split
17684   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17685         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17686                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17687                       (match_operand:DF 2 "nonimmediate_operand" "")
17688                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17689   "!TARGET_64BIT && reload_completed"
17690   [(set (match_dup 2)
17691         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17692                       (match_dup 5)
17693                       (match_dup 7)))
17694    (set (match_dup 3)
17695         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17696                       (match_dup 6)
17697                       (match_dup 8)))]
17698   "split_di (operands+2, 1, operands+5, operands+6);
17699    split_di (operands+3, 1, operands+7, operands+8);
17700    split_di (operands, 1, operands+2, operands+3);")
17701
17702 (define_expand "movxfcc"
17703   [(set (match_operand:XF 0 "register_operand" "")
17704         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17705                          (match_operand:XF 2 "register_operand" "")
17706                          (match_operand:XF 3 "register_operand" "")))]
17707   "TARGET_CMOVE"
17708   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17709
17710 (define_insn "*movxfcc_1"
17711   [(set (match_operand:XF 0 "register_operand" "=f,f")
17712         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17713                                 [(reg FLAGS_REG) (const_int 0)])
17714                       (match_operand:XF 2 "register_operand" "f,0")
17715                       (match_operand:XF 3 "register_operand" "0,f")))]
17716   "TARGET_CMOVE"
17717   "@
17718    fcmov%F1\t{%2, %0|%0, %2}
17719    fcmov%f1\t{%3, %0|%0, %3}"
17720   [(set_attr "type" "fcmov")
17721    (set_attr "mode" "XF")])
17722
17723 (define_expand "minsf3"
17724   [(parallel [
17725      (set (match_operand:SF 0 "register_operand" "")
17726           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17727                                (match_operand:SF 2 "nonimmediate_operand" ""))
17728                            (match_dup 1)
17729                            (match_dup 2)))
17730      (clobber (reg:CC FLAGS_REG))])]
17731   "TARGET_SSE"
17732   "")
17733
17734 (define_insn "*minsf"
17735   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17736         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17737                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17738                          (match_dup 1)
17739                          (match_dup 2)))
17740    (clobber (reg:CC FLAGS_REG))]
17741   "TARGET_SSE && TARGET_IEEE_FP"
17742   "#")
17743
17744 (define_insn "*minsf_nonieee"
17745   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17746         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17747                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17748                          (match_dup 1)
17749                          (match_dup 2)))
17750    (clobber (reg:CC FLAGS_REG))]
17751   "TARGET_SSE && !TARGET_IEEE_FP
17752    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17753   "#")
17754
17755 (define_split
17756   [(set (match_operand:SF 0 "register_operand" "")
17757         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17758                              (match_operand:SF 2 "nonimmediate_operand" ""))
17759                          (match_operand:SF 3 "register_operand" "")
17760                          (match_operand:SF 4 "nonimmediate_operand" "")))
17761    (clobber (reg:CC FLAGS_REG))]
17762   "SSE_REG_P (operands[0]) && reload_completed
17763    && ((operands_match_p (operands[1], operands[3])
17764         && operands_match_p (operands[2], operands[4]))
17765        || (operands_match_p (operands[1], operands[4])
17766            && operands_match_p (operands[2], operands[3])))"
17767   [(set (match_dup 0)
17768         (if_then_else:SF (lt (match_dup 1)
17769                              (match_dup 2))
17770                          (match_dup 1)
17771                          (match_dup 2)))])
17772
17773 ;; Conditional addition patterns
17774 (define_expand "addqicc"
17775   [(match_operand:QI 0 "register_operand" "")
17776    (match_operand 1 "comparison_operator" "")
17777    (match_operand:QI 2 "register_operand" "")
17778    (match_operand:QI 3 "const_int_operand" "")]
17779   ""
17780   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17781
17782 (define_expand "addhicc"
17783   [(match_operand:HI 0 "register_operand" "")
17784    (match_operand 1 "comparison_operator" "")
17785    (match_operand:HI 2 "register_operand" "")
17786    (match_operand:HI 3 "const_int_operand" "")]
17787   ""
17788   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17789
17790 (define_expand "addsicc"
17791   [(match_operand:SI 0 "register_operand" "")
17792    (match_operand 1 "comparison_operator" "")
17793    (match_operand:SI 2 "register_operand" "")
17794    (match_operand:SI 3 "const_int_operand" "")]
17795   ""
17796   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17797
17798 (define_expand "adddicc"
17799   [(match_operand:DI 0 "register_operand" "")
17800    (match_operand 1 "comparison_operator" "")
17801    (match_operand:DI 2 "register_operand" "")
17802    (match_operand:DI 3 "const_int_operand" "")]
17803   "TARGET_64BIT"
17804   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17805
17806 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17807
17808 (define_split
17809   [(set (match_operand:SF 0 "fp_register_operand" "")
17810         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17811                              (match_operand:SF 2 "register_operand" ""))
17812                          (match_operand:SF 3 "register_operand" "")
17813                          (match_operand:SF 4 "register_operand" "")))
17814    (clobber (reg:CC FLAGS_REG))]
17815   "reload_completed
17816    && ((operands_match_p (operands[1], operands[3])
17817         && operands_match_p (operands[2], operands[4]))
17818        || (operands_match_p (operands[1], operands[4])
17819            && operands_match_p (operands[2], operands[3])))"
17820   [(set (reg:CCFP FLAGS_REG)
17821         (compare:CCFP (match_dup 2)
17822                       (match_dup 1)))
17823    (set (match_dup 0)
17824         (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17825                          (match_dup 1)
17826                          (match_dup 2)))])
17827
17828 (define_insn "*minsf_sse"
17829   [(set (match_operand:SF 0 "register_operand" "=x")
17830         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17831                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17832                          (match_dup 1)
17833                          (match_dup 2)))]
17834   "TARGET_SSE && reload_completed"
17835   "minss\t{%2, %0|%0, %2}"
17836   [(set_attr "type" "sse")
17837    (set_attr "mode" "SF")])
17838
17839 (define_expand "mindf3"
17840   [(parallel [
17841      (set (match_operand:DF 0 "register_operand" "")
17842           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17843                                (match_operand:DF 2 "nonimmediate_operand" ""))
17844                            (match_dup 1)
17845                            (match_dup 2)))
17846      (clobber (reg:CC FLAGS_REG))])]
17847   "TARGET_SSE2 && TARGET_SSE_MATH"
17848   "#")
17849
17850 (define_insn "*mindf"
17851   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17852         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17853                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17854                          (match_dup 1)
17855                          (match_dup 2)))
17856    (clobber (reg:CC FLAGS_REG))]
17857   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17858   "#")
17859
17860 (define_insn "*mindf_nonieee"
17861   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17862         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17863                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17864                          (match_dup 1)
17865                          (match_dup 2)))
17866    (clobber (reg:CC FLAGS_REG))]
17867   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17868    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17869   "#")
17870
17871 (define_split
17872   [(set (match_operand:DF 0 "register_operand" "")
17873         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17874                              (match_operand:DF 2 "nonimmediate_operand" ""))
17875                          (match_operand:DF 3 "register_operand" "")
17876                          (match_operand:DF 4 "nonimmediate_operand" "")))
17877    (clobber (reg:CC FLAGS_REG))]
17878   "SSE_REG_P (operands[0]) && reload_completed
17879    && ((operands_match_p (operands[1], operands[3])
17880         && operands_match_p (operands[2], operands[4]))
17881        || (operands_match_p (operands[1], operands[4])
17882            && operands_match_p (operands[2], operands[3])))"
17883   [(set (match_dup 0)
17884         (if_then_else:DF (lt (match_dup 1)
17885                              (match_dup 2))
17886                          (match_dup 1)
17887                          (match_dup 2)))])
17888
17889 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17890 (define_split
17891   [(set (match_operand:DF 0 "fp_register_operand" "")
17892         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17893                              (match_operand:DF 2 "register_operand" ""))
17894                          (match_operand:DF 3 "register_operand" "")
17895                          (match_operand:DF 4 "register_operand" "")))
17896    (clobber (reg:CC FLAGS_REG))]
17897   "reload_completed
17898    && ((operands_match_p (operands[1], operands[3])
17899         && operands_match_p (operands[2], operands[4]))
17900        || (operands_match_p (operands[1], operands[4])
17901            && operands_match_p (operands[2], operands[3])))"
17902   [(set (reg:CCFP FLAGS_REG)
17903         (compare:CCFP (match_dup 2)
17904                       (match_dup 1)))
17905    (set (match_dup 0)
17906         (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17907                          (match_dup 1)
17908                          (match_dup 2)))])
17909
17910 (define_insn "*mindf_sse"
17911   [(set (match_operand:DF 0 "register_operand" "=Y")
17912         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17913                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17914                          (match_dup 1)
17915                          (match_dup 2)))]
17916   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17917   "minsd\t{%2, %0|%0, %2}"
17918   [(set_attr "type" "sse")
17919    (set_attr "mode" "DF")])
17920
17921 (define_expand "maxsf3"
17922   [(parallel [
17923      (set (match_operand:SF 0 "register_operand" "")
17924           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17925                                (match_operand:SF 2 "nonimmediate_operand" ""))
17926                            (match_dup 1)
17927                            (match_dup 2)))
17928      (clobber (reg:CC FLAGS_REG))])]
17929   "TARGET_SSE"
17930   "#")
17931
17932 (define_insn "*maxsf"
17933   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17934         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17935                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17936                          (match_dup 1)
17937                          (match_dup 2)))
17938    (clobber (reg:CC FLAGS_REG))]
17939   "TARGET_SSE && TARGET_IEEE_FP"
17940   "#")
17941
17942 (define_insn "*maxsf_nonieee"
17943   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17944         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17945                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17946                          (match_dup 1)
17947                          (match_dup 2)))
17948    (clobber (reg:CC FLAGS_REG))]
17949   "TARGET_SSE && !TARGET_IEEE_FP
17950    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17951   "#")
17952
17953 (define_split
17954   [(set (match_operand:SF 0 "register_operand" "")
17955         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17956                              (match_operand:SF 2 "nonimmediate_operand" ""))
17957                          (match_operand:SF 3 "register_operand" "")
17958                          (match_operand:SF 4 "nonimmediate_operand" "")))
17959    (clobber (reg:CC FLAGS_REG))]
17960   "SSE_REG_P (operands[0]) && reload_completed
17961    && ((operands_match_p (operands[1], operands[3])
17962         && operands_match_p (operands[2], operands[4]))
17963        || (operands_match_p (operands[1], operands[4])
17964            && operands_match_p (operands[2], operands[3])))"
17965   [(set (match_dup 0)
17966         (if_then_else:SF (gt (match_dup 1)
17967                              (match_dup 2))
17968                          (match_dup 1)
17969                          (match_dup 2)))])
17970
17971 (define_split
17972   [(set (match_operand:SF 0 "fp_register_operand" "")
17973         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17974                              (match_operand:SF 2 "register_operand" ""))
17975                          (match_operand:SF 3 "register_operand" "")
17976                          (match_operand:SF 4 "register_operand" "")))
17977    (clobber (reg:CC FLAGS_REG))]
17978   "reload_completed
17979    && ((operands_match_p (operands[1], operands[3])
17980         && operands_match_p (operands[2], operands[4]))
17981        || (operands_match_p (operands[1], operands[4])
17982            && operands_match_p (operands[2], operands[3])))"
17983   [(set (reg:CCFP FLAGS_REG)
17984         (compare:CCFP (match_dup 1)
17985                       (match_dup 2)))
17986    (set (match_dup 0)
17987         (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17988                          (match_dup 1)
17989                          (match_dup 2)))])
17990
17991 (define_insn "*maxsf_sse"
17992   [(set (match_operand:SF 0 "register_operand" "=x")
17993         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17994                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17995                          (match_dup 1)
17996                          (match_dup 2)))]
17997   "TARGET_SSE && reload_completed"
17998   "maxss\t{%2, %0|%0, %2}"
17999   [(set_attr "type" "sse")
18000    (set_attr "mode" "SF")])
18001
18002 (define_expand "maxdf3"
18003   [(parallel [
18004      (set (match_operand:DF 0 "register_operand" "")
18005           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18006                                (match_operand:DF 2 "nonimmediate_operand" ""))
18007                            (match_dup 1)
18008                            (match_dup 2)))
18009      (clobber (reg:CC FLAGS_REG))])]
18010   "TARGET_SSE2 && TARGET_SSE_MATH"
18011   "#")
18012
18013 (define_insn "*maxdf"
18014   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
18015         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
18016                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
18017                          (match_dup 1)
18018                          (match_dup 2)))
18019    (clobber (reg:CC FLAGS_REG))]
18020   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
18021   "#")
18022
18023 (define_insn "*maxdf_nonieee"
18024   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
18025         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
18026                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
18027                          (match_dup 1)
18028                          (match_dup 2)))
18029    (clobber (reg:CC FLAGS_REG))]
18030   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
18031    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18032   "#")
18033
18034 (define_split
18035   [(set (match_operand:DF 0 "register_operand" "")
18036         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18037                              (match_operand:DF 2 "nonimmediate_operand" ""))
18038                          (match_operand:DF 3 "register_operand" "")
18039                          (match_operand:DF 4 "nonimmediate_operand" "")))
18040    (clobber (reg:CC FLAGS_REG))]
18041   "SSE_REG_P (operands[0]) && reload_completed
18042    && ((operands_match_p (operands[1], operands[3])
18043         && operands_match_p (operands[2], operands[4]))
18044        || (operands_match_p (operands[1], operands[4])
18045            && operands_match_p (operands[2], operands[3])))"
18046   [(set (match_dup 0)
18047         (if_then_else:DF (gt (match_dup 1)
18048                              (match_dup 2))
18049                          (match_dup 1)
18050                          (match_dup 2)))])
18051
18052 (define_split
18053   [(set (match_operand:DF 0 "fp_register_operand" "")
18054         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18055                              (match_operand:DF 2 "register_operand" ""))
18056                          (match_operand:DF 3 "register_operand" "")
18057                          (match_operand:DF 4 "register_operand" "")))
18058    (clobber (reg:CC FLAGS_REG))]
18059   "reload_completed
18060    && ((operands_match_p (operands[1], operands[3])
18061         && operands_match_p (operands[2], operands[4]))
18062        || (operands_match_p (operands[1], operands[4])
18063            && operands_match_p (operands[2], operands[3])))"
18064   [(set (reg:CCFP FLAGS_REG)
18065         (compare:CCFP (match_dup 1)
18066                       (match_dup 2)))
18067    (set (match_dup 0)
18068         (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
18069                          (match_dup 1)
18070                          (match_dup 2)))])
18071
18072 (define_insn "*maxdf_sse"
18073   [(set (match_operand:DF 0 "register_operand" "=Y")
18074         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
18075                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
18076                          (match_dup 1)
18077                          (match_dup 2)))]
18078   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
18079   "maxsd\t{%2, %0|%0, %2}"
18080   [(set_attr "type" "sse")
18081    (set_attr "mode" "DF")])
18082 \f
18083 ;; Misc patterns (?)
18084
18085 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18086 ;; Otherwise there will be nothing to keep
18087 ;; 
18088 ;; [(set (reg ebp) (reg esp))]
18089 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18090 ;;  (clobber (eflags)]
18091 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18092 ;;
18093 ;; in proper program order.
18094 (define_insn "pro_epilogue_adjust_stack_1"
18095   [(set (match_operand:SI 0 "register_operand" "=r,r")
18096         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18097                  (match_operand:SI 2 "immediate_operand" "i,i")))
18098    (clobber (reg:CC FLAGS_REG))
18099    (clobber (mem:BLK (scratch)))]
18100   "!TARGET_64BIT"
18101 {
18102   switch (get_attr_type (insn))
18103     {
18104     case TYPE_IMOV:
18105       return "mov{l}\t{%1, %0|%0, %1}";
18106
18107     case TYPE_ALU:
18108       if (GET_CODE (operands[2]) == CONST_INT
18109           && (INTVAL (operands[2]) == 128
18110               || (INTVAL (operands[2]) < 0
18111                   && INTVAL (operands[2]) != -128)))
18112         {
18113           operands[2] = GEN_INT (-INTVAL (operands[2]));
18114           return "sub{l}\t{%2, %0|%0, %2}";
18115         }
18116       return "add{l}\t{%2, %0|%0, %2}";
18117
18118     case TYPE_LEA:
18119       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18120       return "lea{l}\t{%a2, %0|%0, %a2}";
18121
18122     default:
18123       abort ();
18124     }
18125 }
18126   [(set (attr "type")
18127         (cond [(eq_attr "alternative" "0")
18128                  (const_string "alu")
18129                (match_operand:SI 2 "const0_operand" "")
18130                  (const_string "imov")
18131               ]
18132               (const_string "lea")))
18133    (set_attr "mode" "SI")])
18134
18135 (define_insn "pro_epilogue_adjust_stack_rex64"
18136   [(set (match_operand:DI 0 "register_operand" "=r,r")
18137         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18138                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18139    (clobber (reg:CC FLAGS_REG))
18140    (clobber (mem:BLK (scratch)))]
18141   "TARGET_64BIT"
18142 {
18143   switch (get_attr_type (insn))
18144     {
18145     case TYPE_IMOV:
18146       return "mov{q}\t{%1, %0|%0, %1}";
18147
18148     case TYPE_ALU:
18149       if (GET_CODE (operands[2]) == CONST_INT
18150           /* Avoid overflows.  */
18151           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18152           && (INTVAL (operands[2]) == 128
18153               || (INTVAL (operands[2]) < 0
18154                   && INTVAL (operands[2]) != -128)))
18155         {
18156           operands[2] = GEN_INT (-INTVAL (operands[2]));
18157           return "sub{q}\t{%2, %0|%0, %2}";
18158         }
18159       return "add{q}\t{%2, %0|%0, %2}";
18160
18161     case TYPE_LEA:
18162       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18163       return "lea{q}\t{%a2, %0|%0, %a2}";
18164
18165     default:
18166       abort ();
18167     }
18168 }
18169   [(set (attr "type")
18170         (cond [(eq_attr "alternative" "0")
18171                  (const_string "alu")
18172                (match_operand:DI 2 "const0_operand" "")
18173                  (const_string "imov")
18174               ]
18175               (const_string "lea")))
18176    (set_attr "mode" "DI")])
18177
18178 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18179   [(set (match_operand:DI 0 "register_operand" "=r,r")
18180         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18181                  (match_operand:DI 3 "immediate_operand" "i,i")))
18182    (use (match_operand:DI 2 "register_operand" "r,r"))
18183    (clobber (reg:CC FLAGS_REG))
18184    (clobber (mem:BLK (scratch)))]
18185   "TARGET_64BIT"
18186 {
18187   switch (get_attr_type (insn))
18188     {
18189     case TYPE_ALU:
18190       return "add{q}\t{%2, %0|%0, %2}";
18191
18192     case TYPE_LEA:
18193       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18194       return "lea{q}\t{%a2, %0|%0, %a2}";
18195
18196     default:
18197       abort ();
18198     }
18199 }
18200   [(set_attr "type" "alu,lea")
18201    (set_attr "mode" "DI")])
18202
18203 ;; Placeholder for the conditional moves.  This one is split either to SSE
18204 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
18205 ;; fact is that compares supported by the cmp??ss instructions are exactly
18206 ;; swapped of those supported by cmove sequence.
18207 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18208 ;; supported by i387 comparisons and we do need to emit two conditional moves
18209 ;; in tandem.
18210
18211 (define_insn "sse_movsfcc"
18212   [(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")
18213         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18214                         [(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")
18215                          (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")])
18216                       (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")
18217                       (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")))
18218    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18219    (clobber (reg:CC FLAGS_REG))]
18220   "TARGET_SSE
18221    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18222    /* Avoid combine from being smart and converting min/max
18223       instruction patterns into conditional moves.  */
18224    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18225         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18226        || !rtx_equal_p (operands[4], operands[2])
18227        || !rtx_equal_p (operands[5], operands[3]))
18228    && (!TARGET_IEEE_FP
18229        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18230   "#")
18231
18232 (define_insn "sse_movsfcc_eq"
18233   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18234         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18235                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18236                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18237                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18238    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18239    (clobber (reg:CC FLAGS_REG))]
18240   "TARGET_SSE
18241    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18242   "#")
18243
18244 (define_insn "sse_movdfcc"
18245   [(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")
18246         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18247                         [(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")
18248                          (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")])
18249                       (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")
18250                       (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")))
18251    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18252    (clobber (reg:CC FLAGS_REG))]
18253   "TARGET_SSE2
18254    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18255    /* Avoid combine from being smart and converting min/max
18256       instruction patterns into conditional moves.  */
18257    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18258         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18259        || !rtx_equal_p (operands[4], operands[2])
18260        || !rtx_equal_p (operands[5], operands[3]))
18261    && (!TARGET_IEEE_FP
18262        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18263   "#")
18264
18265 (define_insn "sse_movdfcc_eq"
18266   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18267         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18268                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18269                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18270                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18271    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18272    (clobber (reg:CC FLAGS_REG))]
18273   "TARGET_SSE
18274    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18275   "#")
18276
18277 ;; For non-sse moves just expand the usual cmove sequence.
18278 (define_split
18279   [(set (match_operand 0 "register_operand" "")
18280         (if_then_else (match_operator 1 "comparison_operator"
18281                         [(match_operand 4 "nonimmediate_operand" "")
18282                          (match_operand 5 "register_operand" "")])
18283                       (match_operand 2 "nonimmediate_operand" "")
18284                       (match_operand 3 "nonimmediate_operand" "")))
18285    (clobber (match_operand 6 "" ""))
18286    (clobber (reg:CC FLAGS_REG))]
18287   "!SSE_REG_P (operands[0]) && reload_completed
18288    && (GET_MODE (operands[0]) == SFmode
18289        || (TARGET_SSE2 && GET_MODE (operands[0]) == DFmode))"
18290   [(const_int 0)]
18291 {
18292    ix86_compare_op0 = operands[5];
18293    ix86_compare_op1 = operands[4];
18294    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18295                                  VOIDmode, operands[5], operands[4]);
18296    ix86_expand_fp_movcc (operands);
18297    DONE;
18298 })
18299
18300 ;; Split SSE based conditional move into sequence:
18301 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
18302 ;; and   op2, op0   -  zero op2 if comparison was false
18303 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
18304 ;; or    op2, op0   -  get the nonzero one into the result.
18305 (define_split
18306   [(set (match_operand:SF 0 "register_operand" "")
18307         (if_then_else:SF (match_operator:SF 1 "sse_comparison_operator"
18308                            [(match_operand:SF 4 "register_operand" "")
18309                             (match_operand:SF 5 "nonimmediate_operand" "")])
18310                          (match_operand:SF 2 "register_operand" "")
18311                          (match_operand:SF 3 "register_operand" "")))
18312    (clobber (match_operand 6 "" ""))
18313    (clobber (reg:CC FLAGS_REG))]
18314   "SSE_REG_P (operands[0]) && reload_completed"
18315   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18316    (set (match_dup 2) (and:V4SF (match_dup 2)
18317                                 (match_dup 8)))
18318    (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18319                                           (match_dup 3)))
18320    (set (match_dup 0) (ior:V4SF (match_dup 6)
18321                                 (match_dup 7)))]
18322 {
18323   /* If op2 == op3, op3 would be clobbered before it is used.  */
18324   if (operands_match_p (operands[2], operands[3]))
18325     {
18326       emit_move_insn (operands[0], operands[2]);
18327       DONE;
18328     }
18329
18330   PUT_MODE (operands[1], GET_MODE (operands[0]));
18331   if (operands_match_p (operands[0], operands[4]))
18332     operands[6] = operands[4], operands[7] = operands[2];
18333   else
18334     operands[6] = operands[2], operands[7] = operands[4];
18335   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18336   operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18337   operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18338   operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18339   operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18340   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18341 })
18342
18343 (define_split
18344   [(set (match_operand:DF 0 "register_operand" "")
18345         (if_then_else:DF (match_operator:DF 1 "sse_comparison_operator"
18346                            [(match_operand:DF 4 "register_operand" "")
18347                             (match_operand:DF 5 "nonimmediate_operand" "")])
18348                          (match_operand:DF 2 "register_operand" "")
18349                          (match_operand:DF 3 "register_operand" "")))
18350    (clobber (match_operand 6 "" ""))
18351    (clobber (reg:CC FLAGS_REG))]
18352   "SSE_REG_P (operands[0]) && reload_completed"
18353   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18354    (set (match_dup 2) (and:V2DF (match_dup 2)
18355                                 (match_dup 8)))
18356    (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18357                                           (match_dup 3)))
18358    (set (match_dup 0) (ior:V2DF (match_dup 6)
18359                                 (match_dup 7)))]
18360 {
18361   if (GET_MODE (operands[2]) == DFmode
18362       && TARGET_SSE_PARTIAL_REGS && !optimize_size)
18363     {
18364       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18365       emit_insn (gen_sse2_unpcklpd (op, op, op));
18366       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18367       emit_insn (gen_sse2_unpcklpd (op, op, op));
18368     }
18369
18370   /* If op2 == op3, op3 would be clobbered before it is used.  */
18371   if (operands_match_p (operands[2], operands[3]))
18372     {
18373       emit_move_insn (operands[0], operands[2]);
18374       DONE;
18375     }
18376
18377   PUT_MODE (operands[1], GET_MODE (operands[0]));
18378   if (operands_match_p (operands[0], operands[4]))
18379     operands[6] = operands[4], operands[7] = operands[2];
18380   else
18381     operands[6] = operands[2], operands[7] = operands[4];
18382   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18383   operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18384   operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18385   operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18386   operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18387   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18388 })
18389
18390 ;; Special case of conditional move we can handle effectively.
18391 ;; Do not brother with the integer/floating point case, since these are
18392 ;; bot considerably slower, unlike in the generic case.
18393 (define_insn "*sse_movsfcc_const0_1"
18394   [(set (match_operand:SF 0 "register_operand" "=&x")
18395         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18396                         [(match_operand:SF 4 "register_operand" "0")
18397                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18398                       (match_operand:SF 2 "register_operand" "x")
18399                       (match_operand:SF 3 "const0_operand" "X")))]
18400   "TARGET_SSE"
18401   "#")
18402
18403 (define_insn "*sse_movsfcc_const0_2"
18404   [(set (match_operand:SF 0 "register_operand" "=&x")
18405         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18406                         [(match_operand:SF 4 "register_operand" "0")
18407                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18408                       (match_operand:SF 2 "const0_operand" "X")
18409                       (match_operand:SF 3 "register_operand" "x")))]
18410   "TARGET_SSE"
18411   "#")
18412
18413 (define_insn "*sse_movsfcc_const0_3"
18414   [(set (match_operand:SF 0 "register_operand" "=&x")
18415         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18416                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18417                          (match_operand:SF 5 "register_operand" "0")])
18418                       (match_operand:SF 2 "register_operand" "x")
18419                       (match_operand:SF 3 "const0_operand" "X")))]
18420   "TARGET_SSE"
18421   "#")
18422
18423 (define_insn "*sse_movsfcc_const0_4"
18424   [(set (match_operand:SF 0 "register_operand" "=&x")
18425         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18426                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18427                          (match_operand:SF 5 "register_operand" "0")])
18428                       (match_operand:SF 2 "const0_operand" "X")
18429                       (match_operand:SF 3 "register_operand" "x")))]
18430   "TARGET_SSE"
18431   "#")
18432
18433 (define_insn "*sse_movdfcc_const0_1"
18434   [(set (match_operand:DF 0 "register_operand" "=&Y")
18435         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18436                         [(match_operand:DF 4 "register_operand" "0")
18437                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18438                       (match_operand:DF 2 "register_operand" "Y")
18439                       (match_operand:DF 3 "const0_operand" "X")))]
18440   "TARGET_SSE2"
18441   "#")
18442
18443 (define_insn "*sse_movdfcc_const0_2"
18444   [(set (match_operand:DF 0 "register_operand" "=&Y")
18445         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18446                         [(match_operand:DF 4 "register_operand" "0")
18447                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18448                       (match_operand:DF 2 "const0_operand" "X")
18449                       (match_operand:DF 3 "register_operand" "Y")))]
18450   "TARGET_SSE2"
18451   "#")
18452
18453 (define_insn "*sse_movdfcc_const0_3"
18454   [(set (match_operand:DF 0 "register_operand" "=&Y")
18455         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18456                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18457                          (match_operand:DF 5 "register_operand" "0")])
18458                       (match_operand:DF 2 "register_operand" "Y")
18459                       (match_operand:DF 3 "const0_operand" "X")))]
18460   "TARGET_SSE2"
18461   "#")
18462
18463 (define_insn "*sse_movdfcc_const0_4"
18464   [(set (match_operand:DF 0 "register_operand" "=&Y")
18465         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18466                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18467                          (match_operand:DF 5 "register_operand" "0")])
18468                       (match_operand:DF 2 "const0_operand" "X")
18469                       (match_operand:DF 3 "register_operand" "Y")))]
18470   "TARGET_SSE2"
18471   "#")
18472
18473 (define_split
18474   [(set (match_operand:SF 0 "register_operand" "")
18475         (if_then_else:SF (match_operator 1 "comparison_operator"
18476                            [(match_operand:SF 4 "nonimmediate_operand" "")
18477                             (match_operand:SF 5 "nonimmediate_operand" "")])
18478                          (match_operand:SF 2 "nonmemory_operand" "")
18479                          (match_operand:SF 3 "nonmemory_operand" "")))]
18480   "SSE_REG_P (operands[0]) && reload_completed
18481    && (const0_operand (operands[2], GET_MODE (operands[0]))
18482        || const0_operand (operands[3], GET_MODE (operands[0])))"
18483   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18484    (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18485 {
18486   PUT_MODE (operands[1], GET_MODE (operands[0]));
18487   if (!sse_comparison_operator (operands[1], VOIDmode)
18488       || !rtx_equal_p (operands[0], operands[4]))
18489     {
18490       rtx tmp = operands[5];
18491       operands[5] = operands[4];
18492       operands[4] = tmp;
18493       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18494     }
18495   if (!rtx_equal_p (operands[0], operands[4]))
18496     abort ();
18497   operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18498   if (const0_operand (operands[2], GET_MODE (operands[2])))
18499     {
18500       operands[7] = operands[3];
18501       operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18502     }
18503   else
18504     {
18505       operands[7] = operands[2];
18506       operands[6] = operands[8];
18507     }
18508   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18509 })
18510
18511 (define_split
18512   [(set (match_operand:DF 0 "register_operand" "")
18513         (if_then_else:DF (match_operator 1 "comparison_operator"
18514                            [(match_operand:DF 4 "nonimmediate_operand" "")
18515                             (match_operand:DF 5 "nonimmediate_operand" "")])
18516                          (match_operand:DF 2 "nonmemory_operand" "")
18517                          (match_operand:DF 3 "nonmemory_operand" "")))]
18518   "SSE_REG_P (operands[0]) && reload_completed
18519    && (const0_operand (operands[2], GET_MODE (operands[0]))
18520        || const0_operand (operands[3], GET_MODE (operands[0])))"
18521   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18522    (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18523 {
18524   if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18525       && GET_MODE (operands[2]) == DFmode)
18526     {
18527       if (REG_P (operands[2]))
18528         {
18529           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18530           emit_insn (gen_sse2_unpcklpd (op, op, op));
18531         }
18532       if (REG_P (operands[3]))
18533         {
18534           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18535           emit_insn (gen_sse2_unpcklpd (op, op, op));
18536         }
18537     }
18538   PUT_MODE (operands[1], GET_MODE (operands[0]));
18539   if (!sse_comparison_operator (operands[1], VOIDmode)
18540       || !rtx_equal_p (operands[0], operands[4]))
18541     {
18542       rtx tmp = operands[5];
18543       operands[5] = operands[4];
18544       operands[4] = tmp;
18545       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18546     }
18547   if (!rtx_equal_p (operands[0], operands[4]))
18548     abort ();
18549   operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18550   if (const0_operand (operands[2], GET_MODE (operands[2])))
18551     {
18552       operands[7] = operands[3];
18553       operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18554     }
18555   else
18556     {
18557       operands[7] = operands[2];
18558       operands[6] = operands[8];
18559     }
18560   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18561 })
18562
18563 (define_expand "allocate_stack_worker"
18564   [(match_operand:SI 0 "register_operand" "")]
18565   "TARGET_STACK_PROBE"
18566 {
18567   if (reload_completed)
18568     {
18569       if (TARGET_64BIT)
18570         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18571       else
18572         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18573     }
18574   else
18575     {
18576       if (TARGET_64BIT)
18577         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18578       else
18579         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18580     }
18581   DONE;
18582 })
18583
18584 (define_insn "allocate_stack_worker_1"
18585   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18586     UNSPECV_STACK_PROBE)
18587    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18588    (clobber (match_scratch:SI 1 "=0"))
18589    (clobber (reg:CC FLAGS_REG))]
18590   "!TARGET_64BIT && TARGET_STACK_PROBE"
18591   "call\t__alloca"
18592   [(set_attr "type" "multi")
18593    (set_attr "length" "5")])
18594
18595 (define_expand "allocate_stack_worker_postreload"
18596   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18597                                     UNSPECV_STACK_PROBE)
18598               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18599               (clobber (match_dup 0))
18600               (clobber (reg:CC FLAGS_REG))])]
18601   ""
18602   "")
18603
18604 (define_insn "allocate_stack_worker_rex64"
18605   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18606     UNSPECV_STACK_PROBE)
18607    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18608    (clobber (match_scratch:DI 1 "=0"))
18609    (clobber (reg:CC FLAGS_REG))]
18610   "TARGET_64BIT && TARGET_STACK_PROBE"
18611   "call\t__alloca"
18612   [(set_attr "type" "multi")
18613    (set_attr "length" "5")])
18614
18615 (define_expand "allocate_stack_worker_rex64_postreload"
18616   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18617                                     UNSPECV_STACK_PROBE)
18618               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18619               (clobber (match_dup 0))
18620               (clobber (reg:CC FLAGS_REG))])]
18621   ""
18622   "")
18623
18624 (define_expand "allocate_stack"
18625   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18626                    (minus:SI (reg:SI SP_REG)
18627                              (match_operand:SI 1 "general_operand" "")))
18628               (clobber (reg:CC FLAGS_REG))])
18629    (parallel [(set (reg:SI SP_REG)
18630                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18631               (clobber (reg:CC FLAGS_REG))])]
18632   "TARGET_STACK_PROBE"
18633 {
18634 #ifdef CHECK_STACK_LIMIT
18635   if (GET_CODE (operands[1]) == CONST_INT
18636       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18637     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18638                            operands[1]));
18639   else 
18640 #endif
18641     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18642                                                             operands[1])));
18643
18644   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18645   DONE;
18646 })
18647
18648 (define_expand "builtin_setjmp_receiver"
18649   [(label_ref (match_operand 0 "" ""))]
18650   "!TARGET_64BIT && flag_pic"
18651 {
18652   emit_insn (gen_set_got (pic_offset_table_rtx));
18653   DONE;
18654 })
18655 \f
18656 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18657
18658 (define_split
18659   [(set (match_operand 0 "register_operand" "")
18660         (match_operator 3 "promotable_binary_operator"
18661            [(match_operand 1 "register_operand" "")
18662             (match_operand 2 "aligned_operand" "")]))
18663    (clobber (reg:CC FLAGS_REG))]
18664   "! TARGET_PARTIAL_REG_STALL && reload_completed
18665    && ((GET_MODE (operands[0]) == HImode 
18666         && ((!optimize_size && !TARGET_FAST_PREFIX)
18667             || GET_CODE (operands[2]) != CONST_INT
18668             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18669        || (GET_MODE (operands[0]) == QImode 
18670            && (TARGET_PROMOTE_QImode || optimize_size)))"
18671   [(parallel [(set (match_dup 0)
18672                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18673               (clobber (reg:CC FLAGS_REG))])]
18674   "operands[0] = gen_lowpart (SImode, operands[0]);
18675    operands[1] = gen_lowpart (SImode, operands[1]);
18676    if (GET_CODE (operands[3]) != ASHIFT)
18677      operands[2] = gen_lowpart (SImode, operands[2]);
18678    PUT_MODE (operands[3], SImode);")
18679
18680 ; Promote the QImode tests, as i386 has encoding of the AND
18681 ; instruction with 32-bit sign-extended immediate and thus the
18682 ; instruction size is unchanged, except in the %eax case for
18683 ; which it is increased by one byte, hence the ! optimize_size.
18684 (define_split
18685   [(set (match_operand 0 "flags_reg_operand" "")
18686         (match_operator 2 "compare_operator"
18687           [(and (match_operand 3 "aligned_operand" "")
18688                 (match_operand 4 "const_int_operand" ""))
18689            (const_int 0)]))
18690    (set (match_operand 1 "register_operand" "")
18691         (and (match_dup 3) (match_dup 4)))]
18692   "! TARGET_PARTIAL_REG_STALL && reload_completed
18693    /* Ensure that the operand will remain sign-extended immediate.  */
18694    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18695    && ! optimize_size
18696    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18697        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18698   [(parallel [(set (match_dup 0)
18699                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18700                                     (const_int 0)]))
18701               (set (match_dup 1)
18702                    (and:SI (match_dup 3) (match_dup 4)))])]
18703 {
18704   operands[4]
18705     = gen_int_mode (INTVAL (operands[4])
18706                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18707   operands[1] = gen_lowpart (SImode, operands[1]);
18708   operands[3] = gen_lowpart (SImode, operands[3]);
18709 })
18710
18711 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18712 ; the TEST instruction with 32-bit sign-extended immediate and thus
18713 ; the instruction size would at least double, which is not what we
18714 ; want even with ! optimize_size.
18715 (define_split
18716   [(set (match_operand 0 "flags_reg_operand" "")
18717         (match_operator 1 "compare_operator"
18718           [(and (match_operand:HI 2 "aligned_operand" "")
18719                 (match_operand:HI 3 "const_int_operand" ""))
18720            (const_int 0)]))]
18721   "! TARGET_PARTIAL_REG_STALL && reload_completed
18722    /* Ensure that the operand will remain sign-extended immediate.  */
18723    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18724    && ! TARGET_FAST_PREFIX
18725    && ! optimize_size"
18726   [(set (match_dup 0)
18727         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18728                          (const_int 0)]))]
18729 {
18730   operands[3]
18731     = gen_int_mode (INTVAL (operands[3])
18732                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18733   operands[2] = gen_lowpart (SImode, operands[2]);
18734 })
18735
18736 (define_split
18737   [(set (match_operand 0 "register_operand" "")
18738         (neg (match_operand 1 "register_operand" "")))
18739    (clobber (reg:CC FLAGS_REG))]
18740   "! TARGET_PARTIAL_REG_STALL && reload_completed
18741    && (GET_MODE (operands[0]) == HImode
18742        || (GET_MODE (operands[0]) == QImode 
18743            && (TARGET_PROMOTE_QImode || optimize_size)))"
18744   [(parallel [(set (match_dup 0)
18745                    (neg:SI (match_dup 1)))
18746               (clobber (reg:CC FLAGS_REG))])]
18747   "operands[0] = gen_lowpart (SImode, operands[0]);
18748    operands[1] = gen_lowpart (SImode, operands[1]);")
18749
18750 (define_split
18751   [(set (match_operand 0 "register_operand" "")
18752         (not (match_operand 1 "register_operand" "")))]
18753   "! TARGET_PARTIAL_REG_STALL && reload_completed
18754    && (GET_MODE (operands[0]) == HImode
18755        || (GET_MODE (operands[0]) == QImode 
18756            && (TARGET_PROMOTE_QImode || optimize_size)))"
18757   [(set (match_dup 0)
18758         (not:SI (match_dup 1)))]
18759   "operands[0] = gen_lowpart (SImode, operands[0]);
18760    operands[1] = gen_lowpart (SImode, operands[1]);")
18761
18762 (define_split 
18763   [(set (match_operand 0 "register_operand" "")
18764         (if_then_else (match_operator 1 "comparison_operator" 
18765                                 [(reg FLAGS_REG) (const_int 0)])
18766                       (match_operand 2 "register_operand" "")
18767                       (match_operand 3 "register_operand" "")))]
18768   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18769    && (GET_MODE (operands[0]) == HImode
18770        || (GET_MODE (operands[0]) == QImode 
18771            && (TARGET_PROMOTE_QImode || optimize_size)))"
18772   [(set (match_dup 0)
18773         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18774   "operands[0] = gen_lowpart (SImode, operands[0]);
18775    operands[2] = gen_lowpart (SImode, operands[2]);
18776    operands[3] = gen_lowpart (SImode, operands[3]);")
18777                         
18778 \f
18779 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18780 ;; transform a complex memory operation into two memory to register operations.
18781
18782 ;; Don't push memory operands
18783 (define_peephole2
18784   [(set (match_operand:SI 0 "push_operand" "")
18785         (match_operand:SI 1 "memory_operand" ""))
18786    (match_scratch:SI 2 "r")]
18787   "! optimize_size && ! TARGET_PUSH_MEMORY"
18788   [(set (match_dup 2) (match_dup 1))
18789    (set (match_dup 0) (match_dup 2))]
18790   "")
18791
18792 (define_peephole2
18793   [(set (match_operand:DI 0 "push_operand" "")
18794         (match_operand:DI 1 "memory_operand" ""))
18795    (match_scratch:DI 2 "r")]
18796   "! optimize_size && ! TARGET_PUSH_MEMORY"
18797   [(set (match_dup 2) (match_dup 1))
18798    (set (match_dup 0) (match_dup 2))]
18799   "")
18800
18801 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18802 ;; SImode pushes.
18803 (define_peephole2
18804   [(set (match_operand:SF 0 "push_operand" "")
18805         (match_operand:SF 1 "memory_operand" ""))
18806    (match_scratch:SF 2 "r")]
18807   "! optimize_size && ! TARGET_PUSH_MEMORY"
18808   [(set (match_dup 2) (match_dup 1))
18809    (set (match_dup 0) (match_dup 2))]
18810   "")
18811
18812 (define_peephole2
18813   [(set (match_operand:HI 0 "push_operand" "")
18814         (match_operand:HI 1 "memory_operand" ""))
18815    (match_scratch:HI 2 "r")]
18816   "! optimize_size && ! TARGET_PUSH_MEMORY"
18817   [(set (match_dup 2) (match_dup 1))
18818    (set (match_dup 0) (match_dup 2))]
18819   "")
18820
18821 (define_peephole2
18822   [(set (match_operand:QI 0 "push_operand" "")
18823         (match_operand:QI 1 "memory_operand" ""))
18824    (match_scratch:QI 2 "q")]
18825   "! optimize_size && ! TARGET_PUSH_MEMORY"
18826   [(set (match_dup 2) (match_dup 1))
18827    (set (match_dup 0) (match_dup 2))]
18828   "")
18829
18830 ;; Don't move an immediate directly to memory when the instruction
18831 ;; gets too big.
18832 (define_peephole2
18833   [(match_scratch:SI 1 "r")
18834    (set (match_operand:SI 0 "memory_operand" "")
18835         (const_int 0))]
18836   "! optimize_size
18837    && ! TARGET_USE_MOV0
18838    && TARGET_SPLIT_LONG_MOVES
18839    && get_attr_length (insn) >= ix86_cost->large_insn
18840    && peep2_regno_dead_p (0, FLAGS_REG)"
18841   [(parallel [(set (match_dup 1) (const_int 0))
18842               (clobber (reg:CC FLAGS_REG))])
18843    (set (match_dup 0) (match_dup 1))]
18844   "")
18845
18846 (define_peephole2
18847   [(match_scratch:HI 1 "r")
18848    (set (match_operand:HI 0 "memory_operand" "")
18849         (const_int 0))]
18850   "! optimize_size
18851    && ! TARGET_USE_MOV0
18852    && TARGET_SPLIT_LONG_MOVES
18853    && get_attr_length (insn) >= ix86_cost->large_insn
18854    && peep2_regno_dead_p (0, FLAGS_REG)"
18855   [(parallel [(set (match_dup 2) (const_int 0))
18856               (clobber (reg:CC FLAGS_REG))])
18857    (set (match_dup 0) (match_dup 1))]
18858   "operands[2] = gen_lowpart (SImode, operands[1]);")
18859
18860 (define_peephole2
18861   [(match_scratch:QI 1 "q")
18862    (set (match_operand:QI 0 "memory_operand" "")
18863         (const_int 0))]
18864   "! optimize_size
18865    && ! TARGET_USE_MOV0
18866    && TARGET_SPLIT_LONG_MOVES
18867    && get_attr_length (insn) >= ix86_cost->large_insn
18868    && peep2_regno_dead_p (0, FLAGS_REG)"
18869   [(parallel [(set (match_dup 2) (const_int 0))
18870               (clobber (reg:CC FLAGS_REG))])
18871    (set (match_dup 0) (match_dup 1))]
18872   "operands[2] = gen_lowpart (SImode, operands[1]);")
18873
18874 (define_peephole2
18875   [(match_scratch:SI 2 "r")
18876    (set (match_operand:SI 0 "memory_operand" "")
18877         (match_operand:SI 1 "immediate_operand" ""))]
18878   "! optimize_size
18879    && get_attr_length (insn) >= ix86_cost->large_insn
18880    && TARGET_SPLIT_LONG_MOVES"
18881   [(set (match_dup 2) (match_dup 1))
18882    (set (match_dup 0) (match_dup 2))]
18883   "")
18884
18885 (define_peephole2
18886   [(match_scratch:HI 2 "r")
18887    (set (match_operand:HI 0 "memory_operand" "")
18888         (match_operand:HI 1 "immediate_operand" ""))]
18889   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18890   && TARGET_SPLIT_LONG_MOVES"
18891   [(set (match_dup 2) (match_dup 1))
18892    (set (match_dup 0) (match_dup 2))]
18893   "")
18894
18895 (define_peephole2
18896   [(match_scratch:QI 2 "q")
18897    (set (match_operand:QI 0 "memory_operand" "")
18898         (match_operand:QI 1 "immediate_operand" ""))]
18899   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18900   && TARGET_SPLIT_LONG_MOVES"
18901   [(set (match_dup 2) (match_dup 1))
18902    (set (match_dup 0) (match_dup 2))]
18903   "")
18904
18905 ;; Don't compare memory with zero, load and use a test instead.
18906 (define_peephole2
18907   [(set (match_operand 0 "flags_reg_operand" "")
18908         (match_operator 1 "compare_operator"
18909           [(match_operand:SI 2 "memory_operand" "")
18910            (const_int 0)]))
18911    (match_scratch:SI 3 "r")]
18912   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18913   [(set (match_dup 3) (match_dup 2))
18914    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18915   "")
18916
18917 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18918 ;; Don't split NOTs with a displacement operand, because resulting XOR
18919 ;; will not be pairable anyway.
18920 ;;
18921 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18922 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18923 ;; so this split helps here as well.
18924 ;;
18925 ;; Note: Can't do this as a regular split because we can't get proper
18926 ;; lifetime information then.
18927
18928 (define_peephole2
18929   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18930         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18931   "!optimize_size
18932    && peep2_regno_dead_p (0, FLAGS_REG)
18933    && ((TARGET_PENTIUM 
18934         && (GET_CODE (operands[0]) != MEM
18935             || !memory_displacement_operand (operands[0], SImode)))
18936        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18937   [(parallel [(set (match_dup 0)
18938                    (xor:SI (match_dup 1) (const_int -1)))
18939               (clobber (reg:CC FLAGS_REG))])]
18940   "")
18941
18942 (define_peephole2
18943   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18944         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18945   "!optimize_size
18946    && peep2_regno_dead_p (0, FLAGS_REG)
18947    && ((TARGET_PENTIUM 
18948         && (GET_CODE (operands[0]) != MEM
18949             || !memory_displacement_operand (operands[0], HImode)))
18950        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18951   [(parallel [(set (match_dup 0)
18952                    (xor:HI (match_dup 1) (const_int -1)))
18953               (clobber (reg:CC FLAGS_REG))])]
18954   "")
18955
18956 (define_peephole2
18957   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18958         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18959   "!optimize_size
18960    && peep2_regno_dead_p (0, FLAGS_REG)
18961    && ((TARGET_PENTIUM 
18962         && (GET_CODE (operands[0]) != MEM
18963             || !memory_displacement_operand (operands[0], QImode)))
18964        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18965   [(parallel [(set (match_dup 0)
18966                    (xor:QI (match_dup 1) (const_int -1)))
18967               (clobber (reg:CC FLAGS_REG))])]
18968   "")
18969
18970 ;; Non pairable "test imm, reg" instructions can be translated to
18971 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18972 ;; byte opcode instead of two, have a short form for byte operands),
18973 ;; so do it for other CPUs as well.  Given that the value was dead,
18974 ;; this should not create any new dependencies.  Pass on the sub-word
18975 ;; versions if we're concerned about partial register stalls.
18976
18977 (define_peephole2
18978   [(set (match_operand 0 "flags_reg_operand" "")
18979         (match_operator 1 "compare_operator"
18980           [(and:SI (match_operand:SI 2 "register_operand" "")
18981                    (match_operand:SI 3 "immediate_operand" ""))
18982            (const_int 0)]))]
18983   "ix86_match_ccmode (insn, CCNOmode)
18984    && (true_regnum (operands[2]) != 0
18985        || (GET_CODE (operands[3]) == CONST_INT
18986            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18987    && peep2_reg_dead_p (1, operands[2])"
18988   [(parallel
18989      [(set (match_dup 0)
18990            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18991                             (const_int 0)]))
18992       (set (match_dup 2)
18993            (and:SI (match_dup 2) (match_dup 3)))])]
18994   "")
18995
18996 ;; We don't need to handle HImode case, because it will be promoted to SImode
18997 ;; on ! TARGET_PARTIAL_REG_STALL
18998
18999 (define_peephole2
19000   [(set (match_operand 0 "flags_reg_operand" "")
19001         (match_operator 1 "compare_operator"
19002           [(and:QI (match_operand:QI 2 "register_operand" "")
19003                    (match_operand:QI 3 "immediate_operand" ""))
19004            (const_int 0)]))]
19005   "! TARGET_PARTIAL_REG_STALL
19006    && ix86_match_ccmode (insn, CCNOmode)
19007    && true_regnum (operands[2]) != 0
19008    && peep2_reg_dead_p (1, operands[2])"
19009   [(parallel
19010      [(set (match_dup 0)
19011            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19012                             (const_int 0)]))
19013       (set (match_dup 2)
19014            (and:QI (match_dup 2) (match_dup 3)))])]
19015   "")
19016
19017 (define_peephole2
19018   [(set (match_operand 0 "flags_reg_operand" "")
19019         (match_operator 1 "compare_operator"
19020           [(and:SI
19021              (zero_extract:SI
19022                (match_operand 2 "ext_register_operand" "")
19023                (const_int 8)
19024                (const_int 8))
19025              (match_operand 3 "const_int_operand" ""))
19026            (const_int 0)]))]
19027   "! TARGET_PARTIAL_REG_STALL
19028    && ix86_match_ccmode (insn, CCNOmode)
19029    && true_regnum (operands[2]) != 0
19030    && peep2_reg_dead_p (1, operands[2])"
19031   [(parallel [(set (match_dup 0)
19032                    (match_op_dup 1
19033                      [(and:SI
19034                         (zero_extract:SI
19035                           (match_dup 2)
19036                           (const_int 8)
19037                           (const_int 8))
19038                         (match_dup 3))
19039                       (const_int 0)]))
19040               (set (zero_extract:SI (match_dup 2)
19041                                     (const_int 8)
19042                                     (const_int 8))
19043                    (and:SI 
19044                      (zero_extract:SI
19045                        (match_dup 2)
19046                        (const_int 8)
19047                        (const_int 8))
19048                      (match_dup 3)))])]
19049   "")
19050
19051 ;; Don't do logical operations with memory inputs.
19052 (define_peephole2
19053   [(match_scratch:SI 2 "r")
19054    (parallel [(set (match_operand:SI 0 "register_operand" "")
19055                    (match_operator:SI 3 "arith_or_logical_operator"
19056                      [(match_dup 0)
19057                       (match_operand:SI 1 "memory_operand" "")]))
19058               (clobber (reg:CC FLAGS_REG))])]
19059   "! optimize_size && ! TARGET_READ_MODIFY"
19060   [(set (match_dup 2) (match_dup 1))
19061    (parallel [(set (match_dup 0)
19062                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19063               (clobber (reg:CC FLAGS_REG))])]
19064   "")
19065
19066 (define_peephole2
19067   [(match_scratch:SI 2 "r")
19068    (parallel [(set (match_operand:SI 0 "register_operand" "")
19069                    (match_operator:SI 3 "arith_or_logical_operator"
19070                      [(match_operand:SI 1 "memory_operand" "")
19071                       (match_dup 0)]))
19072               (clobber (reg:CC FLAGS_REG))])]
19073   "! optimize_size && ! TARGET_READ_MODIFY"
19074   [(set (match_dup 2) (match_dup 1))
19075    (parallel [(set (match_dup 0)
19076                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19077               (clobber (reg:CC FLAGS_REG))])]
19078   "")
19079
19080 ; Don't do logical operations with memory outputs
19081 ;
19082 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19083 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19084 ; the same decoder scheduling characteristics as the original.
19085
19086 (define_peephole2
19087   [(match_scratch:SI 2 "r")
19088    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19089                    (match_operator:SI 3 "arith_or_logical_operator"
19090                      [(match_dup 0)
19091                       (match_operand:SI 1 "nonmemory_operand" "")]))
19092               (clobber (reg:CC FLAGS_REG))])]
19093   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19094   [(set (match_dup 2) (match_dup 0))
19095    (parallel [(set (match_dup 2)
19096                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19097               (clobber (reg:CC FLAGS_REG))])
19098    (set (match_dup 0) (match_dup 2))]
19099   "")
19100
19101 (define_peephole2
19102   [(match_scratch:SI 2 "r")
19103    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19104                    (match_operator:SI 3 "arith_or_logical_operator"
19105                      [(match_operand:SI 1 "nonmemory_operand" "")
19106                       (match_dup 0)]))
19107               (clobber (reg:CC FLAGS_REG))])]
19108   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19109   [(set (match_dup 2) (match_dup 0))
19110    (parallel [(set (match_dup 2)
19111                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19112               (clobber (reg:CC FLAGS_REG))])
19113    (set (match_dup 0) (match_dup 2))]
19114   "")
19115
19116 ;; Attempt to always use XOR for zeroing registers.
19117 (define_peephole2
19118   [(set (match_operand 0 "register_operand" "")
19119         (const_int 0))]
19120   "(GET_MODE (operands[0]) == QImode
19121     || GET_MODE (operands[0]) == HImode
19122     || GET_MODE (operands[0]) == SImode
19123     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19124    && (! TARGET_USE_MOV0 || optimize_size)
19125    && peep2_regno_dead_p (0, FLAGS_REG)"
19126   [(parallel [(set (match_dup 0) (const_int 0))
19127               (clobber (reg:CC FLAGS_REG))])]
19128   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19129                               operands[0]);")
19130
19131 (define_peephole2
19132   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19133         (const_int 0))]
19134   "(GET_MODE (operands[0]) == QImode
19135     || GET_MODE (operands[0]) == HImode)
19136    && (! TARGET_USE_MOV0 || optimize_size)
19137    && peep2_regno_dead_p (0, FLAGS_REG)"
19138   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19139               (clobber (reg:CC FLAGS_REG))])])
19140
19141 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19142 (define_peephole2
19143   [(set (match_operand 0 "register_operand" "")
19144         (const_int -1))]
19145   "(GET_MODE (operands[0]) == HImode
19146     || GET_MODE (operands[0]) == SImode 
19147     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19148    && (optimize_size || TARGET_PENTIUM)
19149    && peep2_regno_dead_p (0, FLAGS_REG)"
19150   [(parallel [(set (match_dup 0) (const_int -1))
19151               (clobber (reg:CC FLAGS_REG))])]
19152   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19153                               operands[0]);")
19154
19155 ;; Attempt to convert simple leas to adds. These can be created by
19156 ;; move expanders.
19157 (define_peephole2
19158   [(set (match_operand:SI 0 "register_operand" "")
19159         (plus:SI (match_dup 0)
19160                  (match_operand:SI 1 "nonmemory_operand" "")))]
19161   "peep2_regno_dead_p (0, FLAGS_REG)"
19162   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19163               (clobber (reg:CC FLAGS_REG))])]
19164   "")
19165
19166 (define_peephole2
19167   [(set (match_operand:SI 0 "register_operand" "")
19168         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19169                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19170   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19171   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19172               (clobber (reg:CC FLAGS_REG))])]
19173   "operands[2] = gen_lowpart (SImode, operands[2]);")
19174
19175 (define_peephole2
19176   [(set (match_operand:DI 0 "register_operand" "")
19177         (plus:DI (match_dup 0)
19178                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19179   "peep2_regno_dead_p (0, FLAGS_REG)"
19180   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19181               (clobber (reg:CC FLAGS_REG))])]
19182   "")
19183
19184 (define_peephole2
19185   [(set (match_operand:SI 0 "register_operand" "")
19186         (mult:SI (match_dup 0)
19187                  (match_operand:SI 1 "const_int_operand" "")))]
19188   "exact_log2 (INTVAL (operands[1])) >= 0
19189    && peep2_regno_dead_p (0, FLAGS_REG)"
19190   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19191               (clobber (reg:CC FLAGS_REG))])]
19192   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19193
19194 (define_peephole2
19195   [(set (match_operand:DI 0 "register_operand" "")
19196         (mult:DI (match_dup 0)
19197                  (match_operand:DI 1 "const_int_operand" "")))]
19198   "exact_log2 (INTVAL (operands[1])) >= 0
19199    && peep2_regno_dead_p (0, FLAGS_REG)"
19200   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19201               (clobber (reg:CC FLAGS_REG))])]
19202   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19203
19204 (define_peephole2
19205   [(set (match_operand:SI 0 "register_operand" "")
19206         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19207                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19208   "exact_log2 (INTVAL (operands[2])) >= 0
19209    && REGNO (operands[0]) == REGNO (operands[1])
19210    && peep2_regno_dead_p (0, FLAGS_REG)"
19211   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19212               (clobber (reg:CC FLAGS_REG))])]
19213   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19214
19215 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19216 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19217 ;; many CPUs it is also faster, since special hardware to avoid esp
19218 ;; dependencies is present.
19219
19220 ;; While some of these conversions may be done using splitters, we use peepholes
19221 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19222
19223 ;; Convert prologue esp subtractions to push.
19224 ;; We need register to push.  In order to keep verify_flow_info happy we have
19225 ;; two choices
19226 ;; - use scratch and clobber it in order to avoid dependencies
19227 ;; - use already live register
19228 ;; We can't use the second way right now, since there is no reliable way how to
19229 ;; verify that given register is live.  First choice will also most likely in
19230 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19231 ;; call clobbered registers are dead.  We may want to use base pointer as an
19232 ;; alternative when no register is available later.
19233
19234 (define_peephole2
19235   [(match_scratch:SI 0 "r")
19236    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19237               (clobber (reg:CC FLAGS_REG))
19238               (clobber (mem:BLK (scratch)))])]
19239   "optimize_size || !TARGET_SUB_ESP_4"
19240   [(clobber (match_dup 0))
19241    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19242               (clobber (mem:BLK (scratch)))])])
19243
19244 (define_peephole2
19245   [(match_scratch:SI 0 "r")
19246    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19247               (clobber (reg:CC FLAGS_REG))
19248               (clobber (mem:BLK (scratch)))])]
19249   "optimize_size || !TARGET_SUB_ESP_8"
19250   [(clobber (match_dup 0))
19251    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19252    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19253               (clobber (mem:BLK (scratch)))])])
19254
19255 ;; Convert esp subtractions to push.
19256 (define_peephole2
19257   [(match_scratch:SI 0 "r")
19258    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19259               (clobber (reg:CC FLAGS_REG))])]
19260   "optimize_size || !TARGET_SUB_ESP_4"
19261   [(clobber (match_dup 0))
19262    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19263
19264 (define_peephole2
19265   [(match_scratch:SI 0 "r")
19266    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19267               (clobber (reg:CC FLAGS_REG))])]
19268   "optimize_size || !TARGET_SUB_ESP_8"
19269   [(clobber (match_dup 0))
19270    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19271    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19272
19273 ;; Convert epilogue deallocator to pop.
19274 (define_peephole2
19275   [(match_scratch:SI 0 "r")
19276    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19277               (clobber (reg:CC FLAGS_REG))
19278               (clobber (mem:BLK (scratch)))])]
19279   "optimize_size || !TARGET_ADD_ESP_4"
19280   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19281               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19282               (clobber (mem:BLK (scratch)))])]
19283   "")
19284
19285 ;; Two pops case is tricky, since pop causes dependency on destination register.
19286 ;; We use two registers if available.
19287 (define_peephole2
19288   [(match_scratch:SI 0 "r")
19289    (match_scratch:SI 1 "r")
19290    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19291               (clobber (reg:CC FLAGS_REG))
19292               (clobber (mem:BLK (scratch)))])]
19293   "optimize_size || !TARGET_ADD_ESP_8"
19294   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19295               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19296               (clobber (mem:BLK (scratch)))])
19297    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19298               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19299   "")
19300
19301 (define_peephole2
19302   [(match_scratch:SI 0 "r")
19303    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19304               (clobber (reg:CC FLAGS_REG))
19305               (clobber (mem:BLK (scratch)))])]
19306   "optimize_size"
19307   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19308               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19309               (clobber (mem:BLK (scratch)))])
19310    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19311               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19312   "")
19313
19314 ;; Convert esp additions to pop.
19315 (define_peephole2
19316   [(match_scratch:SI 0 "r")
19317    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19318               (clobber (reg:CC FLAGS_REG))])]
19319   ""
19320   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19321               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19322   "")
19323
19324 ;; Two pops case is tricky, since pop causes dependency on destination register.
19325 ;; We use two registers if available.
19326 (define_peephole2
19327   [(match_scratch:SI 0 "r")
19328    (match_scratch:SI 1 "r")
19329    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19330               (clobber (reg:CC FLAGS_REG))])]
19331   ""
19332   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19333               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19334    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19335               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19336   "")
19337
19338 (define_peephole2
19339   [(match_scratch:SI 0 "r")
19340    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19341               (clobber (reg:CC FLAGS_REG))])]
19342   "optimize_size"
19343   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19344               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19345    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19346               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19347   "")
19348 \f
19349 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19350 ;; required and register dies.  Similarly for 128 to plus -128.
19351 (define_peephole2
19352   [(set (match_operand 0 "flags_reg_operand" "")
19353         (match_operator 1 "compare_operator"
19354           [(match_operand 2 "register_operand" "")
19355            (match_operand 3 "const_int_operand" "")]))]
19356   "(INTVAL (operands[3]) == -1
19357     || INTVAL (operands[3]) == 1
19358     || INTVAL (operands[3]) == 128)
19359    && ix86_match_ccmode (insn, CCGCmode)
19360    && peep2_reg_dead_p (1, operands[2])"
19361   [(parallel [(set (match_dup 0)
19362                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19363               (clobber (match_dup 2))])]
19364   "")
19365 \f
19366 (define_peephole2
19367   [(match_scratch:DI 0 "r")
19368    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19369               (clobber (reg:CC FLAGS_REG))
19370               (clobber (mem:BLK (scratch)))])]
19371   "optimize_size || !TARGET_SUB_ESP_4"
19372   [(clobber (match_dup 0))
19373    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19374               (clobber (mem:BLK (scratch)))])])
19375
19376 (define_peephole2
19377   [(match_scratch:DI 0 "r")
19378    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19379               (clobber (reg:CC FLAGS_REG))
19380               (clobber (mem:BLK (scratch)))])]
19381   "optimize_size || !TARGET_SUB_ESP_8"
19382   [(clobber (match_dup 0))
19383    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19384    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19385               (clobber (mem:BLK (scratch)))])])
19386
19387 ;; Convert esp subtractions to push.
19388 (define_peephole2
19389   [(match_scratch:DI 0 "r")
19390    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19391               (clobber (reg:CC FLAGS_REG))])]
19392   "optimize_size || !TARGET_SUB_ESP_4"
19393   [(clobber (match_dup 0))
19394    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19395
19396 (define_peephole2
19397   [(match_scratch:DI 0 "r")
19398    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19399               (clobber (reg:CC FLAGS_REG))])]
19400   "optimize_size || !TARGET_SUB_ESP_8"
19401   [(clobber (match_dup 0))
19402    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19403    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19404
19405 ;; Convert epilogue deallocator to pop.
19406 (define_peephole2
19407   [(match_scratch:DI 0 "r")
19408    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19409               (clobber (reg:CC FLAGS_REG))
19410               (clobber (mem:BLK (scratch)))])]
19411   "optimize_size || !TARGET_ADD_ESP_4"
19412   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19413               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19414               (clobber (mem:BLK (scratch)))])]
19415   "")
19416
19417 ;; Two pops case is tricky, since pop causes dependency on destination register.
19418 ;; We use two registers if available.
19419 (define_peephole2
19420   [(match_scratch:DI 0 "r")
19421    (match_scratch:DI 1 "r")
19422    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19423               (clobber (reg:CC FLAGS_REG))
19424               (clobber (mem:BLK (scratch)))])]
19425   "optimize_size || !TARGET_ADD_ESP_8"
19426   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19427               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19428               (clobber (mem:BLK (scratch)))])
19429    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19430               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19431   "")
19432
19433 (define_peephole2
19434   [(match_scratch:DI 0 "r")
19435    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19436               (clobber (reg:CC FLAGS_REG))
19437               (clobber (mem:BLK (scratch)))])]
19438   "optimize_size"
19439   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19440               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19441               (clobber (mem:BLK (scratch)))])
19442    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19443               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19444   "")
19445
19446 ;; Convert esp additions to pop.
19447 (define_peephole2
19448   [(match_scratch:DI 0 "r")
19449    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19450               (clobber (reg:CC FLAGS_REG))])]
19451   ""
19452   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19453               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19454   "")
19455
19456 ;; Two pops case is tricky, since pop causes dependency on destination register.
19457 ;; We use two registers if available.
19458 (define_peephole2
19459   [(match_scratch:DI 0 "r")
19460    (match_scratch:DI 1 "r")
19461    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19462               (clobber (reg:CC FLAGS_REG))])]
19463   ""
19464   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19465               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19466    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19467               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19468   "")
19469
19470 (define_peephole2
19471   [(match_scratch:DI 0 "r")
19472    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19473               (clobber (reg:CC FLAGS_REG))])]
19474   "optimize_size"
19475   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19476               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19477    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19478               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19479   "")
19480 \f
19481 ;; Convert imul by three, five and nine into lea
19482 (define_peephole2
19483   [(parallel
19484     [(set (match_operand:SI 0 "register_operand" "")
19485           (mult:SI (match_operand:SI 1 "register_operand" "")
19486                    (match_operand:SI 2 "const_int_operand" "")))
19487      (clobber (reg:CC FLAGS_REG))])]
19488   "INTVAL (operands[2]) == 3
19489    || INTVAL (operands[2]) == 5
19490    || INTVAL (operands[2]) == 9"
19491   [(set (match_dup 0)
19492         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19493                  (match_dup 1)))]
19494   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19495
19496 (define_peephole2
19497   [(parallel
19498     [(set (match_operand:SI 0 "register_operand" "")
19499           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19500                    (match_operand:SI 2 "const_int_operand" "")))
19501      (clobber (reg:CC FLAGS_REG))])]
19502   "!optimize_size 
19503    && (INTVAL (operands[2]) == 3
19504        || INTVAL (operands[2]) == 5
19505        || INTVAL (operands[2]) == 9)"
19506   [(set (match_dup 0) (match_dup 1))
19507    (set (match_dup 0)
19508         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19509                  (match_dup 0)))]
19510   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19511
19512 (define_peephole2
19513   [(parallel
19514     [(set (match_operand:DI 0 "register_operand" "")
19515           (mult:DI (match_operand:DI 1 "register_operand" "")
19516                    (match_operand:DI 2 "const_int_operand" "")))
19517      (clobber (reg:CC FLAGS_REG))])]
19518   "TARGET_64BIT
19519    && (INTVAL (operands[2]) == 3
19520        || INTVAL (operands[2]) == 5
19521        || INTVAL (operands[2]) == 9)"
19522   [(set (match_dup 0)
19523         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19524                  (match_dup 1)))]
19525   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19526
19527 (define_peephole2
19528   [(parallel
19529     [(set (match_operand:DI 0 "register_operand" "")
19530           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19531                    (match_operand:DI 2 "const_int_operand" "")))
19532      (clobber (reg:CC FLAGS_REG))])]
19533   "TARGET_64BIT
19534    && !optimize_size 
19535    && (INTVAL (operands[2]) == 3
19536        || INTVAL (operands[2]) == 5
19537        || INTVAL (operands[2]) == 9)"
19538   [(set (match_dup 0) (match_dup 1))
19539    (set (match_dup 0)
19540         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19541                  (match_dup 0)))]
19542   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19543
19544 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19545 ;; imul $32bit_imm, reg, reg is direct decoded.
19546 (define_peephole2
19547   [(match_scratch:DI 3 "r")
19548    (parallel [(set (match_operand:DI 0 "register_operand" "")
19549                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19550                             (match_operand:DI 2 "immediate_operand" "")))
19551               (clobber (reg:CC FLAGS_REG))])]
19552   "TARGET_K8 && !optimize_size
19553    && (GET_CODE (operands[2]) != CONST_INT
19554        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19555   [(set (match_dup 3) (match_dup 1))
19556    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19557               (clobber (reg:CC FLAGS_REG))])]
19558 "")
19559
19560 (define_peephole2
19561   [(match_scratch:SI 3 "r")
19562    (parallel [(set (match_operand:SI 0 "register_operand" "")
19563                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19564                             (match_operand:SI 2 "immediate_operand" "")))
19565               (clobber (reg:CC FLAGS_REG))])]
19566   "TARGET_K8 && !optimize_size
19567    && (GET_CODE (operands[2]) != CONST_INT
19568        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19569   [(set (match_dup 3) (match_dup 1))
19570    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19571               (clobber (reg:CC FLAGS_REG))])]
19572 "")
19573
19574 (define_peephole2
19575   [(match_scratch:SI 3 "r")
19576    (parallel [(set (match_operand:DI 0 "register_operand" "")
19577                    (zero_extend:DI
19578                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19579                               (match_operand:SI 2 "immediate_operand" ""))))
19580               (clobber (reg:CC FLAGS_REG))])]
19581   "TARGET_K8 && !optimize_size
19582    && (GET_CODE (operands[2]) != CONST_INT
19583        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19584   [(set (match_dup 3) (match_dup 1))
19585    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19586               (clobber (reg:CC FLAGS_REG))])]
19587 "")
19588
19589 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19590 ;; Convert it into imul reg, reg
19591 ;; It would be better to force assembler to encode instruction using long
19592 ;; immediate, but there is apparently no way to do so.
19593 (define_peephole2
19594   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19595                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19596                             (match_operand:DI 2 "const_int_operand" "")))
19597               (clobber (reg:CC FLAGS_REG))])
19598    (match_scratch:DI 3 "r")]
19599   "TARGET_K8 && !optimize_size
19600    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19601   [(set (match_dup 3) (match_dup 2))
19602    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19603               (clobber (reg:CC FLAGS_REG))])]
19604 {
19605   if (!rtx_equal_p (operands[0], operands[1]))
19606     emit_move_insn (operands[0], operands[1]);
19607 })
19608
19609 (define_peephole2
19610   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19611                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19612                             (match_operand:SI 2 "const_int_operand" "")))
19613               (clobber (reg:CC FLAGS_REG))])
19614    (match_scratch:SI 3 "r")]
19615   "TARGET_K8 && !optimize_size
19616    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19617   [(set (match_dup 3) (match_dup 2))
19618    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19619               (clobber (reg:CC FLAGS_REG))])]
19620 {
19621   if (!rtx_equal_p (operands[0], operands[1]))
19622     emit_move_insn (operands[0], operands[1]);
19623 })
19624
19625 (define_peephole2
19626   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19627                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19628                             (match_operand:HI 2 "immediate_operand" "")))
19629               (clobber (reg:CC FLAGS_REG))])
19630    (match_scratch:HI 3 "r")]
19631   "TARGET_K8 && !optimize_size"
19632   [(set (match_dup 3) (match_dup 2))
19633    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19634               (clobber (reg:CC FLAGS_REG))])]
19635 {
19636   if (!rtx_equal_p (operands[0], operands[1]))
19637     emit_move_insn (operands[0], operands[1]);
19638 })
19639 \f
19640 ;; Call-value patterns last so that the wildcard operand does not
19641 ;; disrupt insn-recog's switch tables.
19642
19643 (define_insn "*call_value_pop_0"
19644   [(set (match_operand 0 "" "")
19645         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19646               (match_operand:SI 2 "" "")))
19647    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19648                             (match_operand:SI 3 "immediate_operand" "")))]
19649   "!TARGET_64BIT"
19650 {
19651   if (SIBLING_CALL_P (insn))
19652     return "jmp\t%P1";
19653   else
19654     return "call\t%P1";
19655 }
19656   [(set_attr "type" "callv")])
19657
19658 (define_insn "*call_value_pop_1"
19659   [(set (match_operand 0 "" "")
19660         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19661               (match_operand:SI 2 "" "")))
19662    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19663                             (match_operand:SI 3 "immediate_operand" "i")))]
19664   "!TARGET_64BIT"
19665 {
19666   if (constant_call_address_operand (operands[1], Pmode))
19667     {
19668       if (SIBLING_CALL_P (insn))
19669         return "jmp\t%P1";
19670       else
19671         return "call\t%P1";
19672     }
19673   if (SIBLING_CALL_P (insn))
19674     return "jmp\t%A1";
19675   else
19676     return "call\t%A1";
19677 }
19678   [(set_attr "type" "callv")])
19679
19680 (define_insn "*call_value_0"
19681   [(set (match_operand 0 "" "")
19682         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19683               (match_operand:SI 2 "" "")))]
19684   "!TARGET_64BIT"
19685 {
19686   if (SIBLING_CALL_P (insn))
19687     return "jmp\t%P1";
19688   else
19689     return "call\t%P1";
19690 }
19691   [(set_attr "type" "callv")])
19692
19693 (define_insn "*call_value_0_rex64"
19694   [(set (match_operand 0 "" "")
19695         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19696               (match_operand:DI 2 "const_int_operand" "")))]
19697   "TARGET_64BIT"
19698 {
19699   if (SIBLING_CALL_P (insn))
19700     return "jmp\t%P1";
19701   else
19702     return "call\t%P1";
19703 }
19704   [(set_attr "type" "callv")])
19705
19706 (define_insn "*call_value_1"
19707   [(set (match_operand 0 "" "")
19708         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19709               (match_operand:SI 2 "" "")))]
19710   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19711 {
19712   if (constant_call_address_operand (operands[1], Pmode))
19713     return "call\t%P1";
19714   return "call\t%A1";
19715 }
19716   [(set_attr "type" "callv")])
19717
19718 (define_insn "*sibcall_value_1"
19719   [(set (match_operand 0 "" "")
19720         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19721               (match_operand:SI 2 "" "")))]
19722   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19723 {
19724   if (constant_call_address_operand (operands[1], Pmode))
19725     return "jmp\t%P1";
19726   return "jmp\t%A1";
19727 }
19728   [(set_attr "type" "callv")])
19729
19730 (define_insn "*call_value_1_rex64"
19731   [(set (match_operand 0 "" "")
19732         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19733               (match_operand:DI 2 "" "")))]
19734   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19735 {
19736   if (constant_call_address_operand (operands[1], Pmode))
19737     return "call\t%P1";
19738   return "call\t%A1";
19739 }
19740   [(set_attr "type" "callv")])
19741
19742 (define_insn "*sibcall_value_1_rex64"
19743   [(set (match_operand 0 "" "")
19744         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19745               (match_operand:DI 2 "" "")))]
19746   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19747   "jmp\t%P1"
19748   [(set_attr "type" "callv")])
19749
19750 (define_insn "*sibcall_value_1_rex64_v"
19751   [(set (match_operand 0 "" "")
19752         (call (mem:QI (reg:DI 40))
19753               (match_operand:DI 1 "" "")))]
19754   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19755   "jmp\t*%%r11"
19756   [(set_attr "type" "callv")])
19757 \f
19758 (define_insn "trap"
19759   [(trap_if (const_int 1) (const_int 5))]
19760   ""
19761   "int\t$5")
19762
19763 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19764 ;;; for the sake of bounds checking.  By emitting bounds checks as
19765 ;;; conditional traps rather than as conditional jumps around
19766 ;;; unconditional traps we avoid introducing spurious basic-block
19767 ;;; boundaries and facilitate elimination of redundant checks.  In
19768 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19769 ;;; interrupt 5.
19770 ;;; 
19771 ;;; FIXME: Static branch prediction rules for ix86 are such that
19772 ;;; forward conditional branches predict as untaken.  As implemented
19773 ;;; below, pseudo conditional traps violate that rule.  We should use
19774 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19775 ;;; section loaded at the end of the text segment and branch forward
19776 ;;; there on bounds-failure, and then jump back immediately (in case
19777 ;;; the system chooses to ignore bounds violations, or to report
19778 ;;; violations and continue execution).
19779
19780 (define_expand "conditional_trap"
19781   [(trap_if (match_operator 0 "comparison_operator"
19782              [(match_dup 2) (const_int 0)])
19783             (match_operand 1 "const_int_operand" ""))]
19784   ""
19785 {
19786   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19787                               ix86_expand_compare (GET_CODE (operands[0]),
19788                                                    NULL, NULL),
19789                               operands[1]));
19790   DONE;
19791 })
19792
19793 (define_insn "*conditional_trap_1"
19794   [(trap_if (match_operator 0 "comparison_operator"
19795              [(reg FLAGS_REG) (const_int 0)])
19796             (match_operand 1 "const_int_operand" ""))]
19797   ""
19798 {
19799   operands[2] = gen_label_rtx ();
19800   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19801   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19802                              CODE_LABEL_NUMBER (operands[2]));
19803   RET;
19804 })
19805
19806         ;; Pentium III SIMD instructions.
19807
19808 ;; Moves for SSE/MMX regs.
19809
19810 (define_insn "*movv4sf_internal"
19811   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19812         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19813   "TARGET_SSE"
19814   "@
19815     xorps\t%0, %0
19816     movaps\t{%1, %0|%0, %1}
19817     movaps\t{%1, %0|%0, %1}"
19818   [(set_attr "type" "ssemov")
19819    (set_attr "mode" "V4SF")])
19820
19821 (define_split
19822   [(set (match_operand:V4SF 0 "register_operand" "")
19823         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19824   "TARGET_SSE && reload_completed"
19825   [(set (match_dup 0)
19826         (vec_merge:V4SF
19827          (vec_duplicate:V4SF (match_dup 1))
19828          (match_dup 2)
19829          (const_int 1)))]
19830 {
19831   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19832   operands[2] = CONST0_RTX (V4SFmode);
19833 })
19834
19835 (define_insn "*movv4si_internal"
19836   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
19837         (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
19838   "TARGET_SSE"
19839 {
19840   switch (which_alternative)
19841     {
19842     case 0:
19843       if (get_attr_mode (insn) == MODE_V4SF)
19844         return "xorps\t%0, %0";
19845       else
19846         return "pxor\t%0, %0";
19847     case 1:
19848     case 2:
19849       if (get_attr_mode (insn) == MODE_V4SF)
19850         return "movaps\t{%1, %0|%0, %1}";
19851       else
19852         return "movdqa\t{%1, %0|%0, %1}";
19853     default:
19854       abort ();
19855     }
19856 }
19857   [(set_attr "type" "ssemov")
19858    (set (attr "mode")
19859         (cond [(eq_attr "alternative" "0,1")
19860                  (if_then_else
19861                    (ne (symbol_ref "optimize_size")
19862                        (const_int 0))
19863                    (const_string "V4SF")
19864                    (const_string "TI"))
19865                (eq_attr "alternative" "2")
19866                  (if_then_else
19867                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19868                             (const_int 0))
19869                         (ne (symbol_ref "optimize_size")
19870                             (const_int 0)))
19871                    (const_string "V4SF")
19872                    (const_string "TI"))]
19873                (const_string "TI")))])
19874
19875 (define_insn "*movv2di_internal"
19876   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
19877         (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
19878   "TARGET_SSE"
19879 {
19880   switch (which_alternative)
19881     {
19882     case 0:
19883       if (get_attr_mode (insn) == MODE_V4SF)
19884         return "xorps\t%0, %0";
19885       else
19886         return "pxor\t%0, %0";
19887     case 1:
19888     case 2:
19889       if (get_attr_mode (insn) == MODE_V4SF)
19890         return "movaps\t{%1, %0|%0, %1}";
19891       else
19892         return "movdqa\t{%1, %0|%0, %1}";
19893     default:
19894       abort ();
19895     }
19896 }
19897   [(set_attr "type" "ssemov")
19898    (set (attr "mode")
19899         (cond [(eq_attr "alternative" "0,1")
19900                  (if_then_else
19901                    (ne (symbol_ref "optimize_size")
19902                        (const_int 0))
19903                    (const_string "V4SF")
19904                    (const_string "TI"))
19905                (eq_attr "alternative" "2")
19906                  (if_then_else
19907                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19908                             (const_int 0))
19909                         (ne (symbol_ref "optimize_size")
19910                             (const_int 0)))
19911                    (const_string "V4SF")
19912                    (const_string "TI"))]
19913                (const_string "TI")))])
19914
19915 (define_split
19916   [(set (match_operand:V2DF 0 "register_operand" "")
19917         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19918   "TARGET_SSE2 && reload_completed"
19919   [(set (match_dup 0)
19920         (vec_merge:V2DF
19921          (vec_duplicate:V2DF (match_dup 1))
19922          (match_dup 2)
19923          (const_int 1)))]
19924 {
19925   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19926   operands[2] = CONST0_RTX (V2DFmode);
19927 })
19928
19929 (define_insn "*movv8qi_internal"
19930   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19931         (match_operand:V8QI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19932   "TARGET_MMX
19933    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19934   "@
19935     pxor\t%0, %0
19936     movq\t{%1, %0|%0, %1}
19937     movq\t{%1, %0|%0, %1}
19938     movdq2q\t{%1, %0|%0, %1}
19939     movq2dq\t{%1, %0|%0, %1}
19940     movq\t{%1, %0|%0, %1}
19941     movq\t{%1, %0|%0, %1}"
19942   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19943    (set_attr "mode" "DI")])
19944
19945 (define_insn "*movv4hi_internal"
19946   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19947         (match_operand:V4HI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19948   "TARGET_MMX
19949    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19950   "@
19951     pxor\t%0, %0
19952     movq\t{%1, %0|%0, %1}
19953     movq\t{%1, %0|%0, %1}
19954     movdq2q\t{%1, %0|%0, %1}
19955     movq2dq\t{%1, %0|%0, %1}
19956     movq\t{%1, %0|%0, %1}
19957     movq\t{%1, %0|%0, %1}"
19958   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19959    (set_attr "mode" "DI")])
19960
19961 (define_insn "*movv2si_internal"
19962   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19963         (match_operand:V2SI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19964   "TARGET_MMX
19965    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19966   "@
19967     pxor\t%0, %0
19968     movq\t{%1, %0|%0, %1}
19969     movq\t{%1, %0|%0, %1}
19970     movdq2q\t{%1, %0|%0, %1}
19971     movq2dq\t{%1, %0|%0, %1}
19972     movq\t{%1, %0|%0, %1}
19973     movq\t{%1, %0|%0, %1}"
19974   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19975    (set_attr "mode" "DI")])
19976
19977 (define_insn "*movv2sf_internal"
19978   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*x,?m")
19979         (match_operand:V2SF 1 "vector_move_operand" "C,ym,y,*Y,y,*xm,*x"))]
19980   "TARGET_MMX
19981    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19982   "@
19983     pxor\t%0, %0
19984     movq\t{%1, %0|%0, %1}
19985     movq\t{%1, %0|%0, %1}
19986     movdq2q\t{%1, %0|%0, %1}
19987     movq2dq\t{%1, %0|%0, %1}
19988     movlps\t{%1, %0|%0, %1}
19989     movlps\t{%1, %0|%0, %1}"
19990   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19991    (set_attr "mode" "DI,DI,DI,DI,DI,V2SF,V2SF")])
19992
19993 (define_expand "movti"
19994   [(set (match_operand:TI 0 "nonimmediate_operand" "")
19995         (match_operand:TI 1 "nonimmediate_operand" ""))]
19996   "TARGET_SSE || TARGET_64BIT"
19997 {
19998   if (TARGET_64BIT)
19999     ix86_expand_move (TImode, operands);
20000   else
20001     ix86_expand_vector_move (TImode, operands);
20002   DONE;
20003 })
20004
20005 (define_expand "movtf"
20006   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20007         (match_operand:TF 1 "nonimmediate_operand" ""))]
20008   "TARGET_64BIT"
20009 {
20010   ix86_expand_move (TFmode, operands);
20011   DONE;
20012 })
20013
20014 (define_insn "*movv2df_internal"
20015   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
20016         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
20017   "TARGET_SSE
20018    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20019 {
20020   switch (which_alternative)
20021     {
20022     case 0:
20023       if (get_attr_mode (insn) == MODE_V4SF)
20024         return "xorps\t%0, %0";
20025       else
20026         return "xorpd\t%0, %0";
20027     case 1:
20028     case 2:
20029       if (get_attr_mode (insn) == MODE_V4SF)
20030         return "movaps\t{%1, %0|%0, %1}";
20031       else
20032         return "movapd\t{%1, %0|%0, %1}";
20033     default:
20034       abort ();
20035     }
20036 }
20037   [(set_attr "type" "ssemov")
20038    (set (attr "mode")
20039         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
20040                  (const_string "V4SF")
20041                (eq_attr "alternative" "0,1")
20042                  (if_then_else
20043                    (ne (symbol_ref "optimize_size")
20044                        (const_int 0))
20045                    (const_string "V4SF")
20046                    (const_string "V2DF"))
20047                (eq_attr "alternative" "2")
20048                  (if_then_else
20049                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20050                             (const_int 0))
20051                         (ne (symbol_ref "optimize_size")
20052                             (const_int 0)))
20053                    (const_string "V4SF")
20054                    (const_string "V2DF"))]
20055                (const_string "V2DF")))])
20056
20057 (define_insn "*movv8hi_internal"
20058   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
20059         (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
20060   "TARGET_SSE
20061    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20062 {
20063   switch (which_alternative)
20064     {
20065     case 0:
20066       if (get_attr_mode (insn) == MODE_V4SF)
20067         return "xorps\t%0, %0";
20068       else
20069         return "pxor\t%0, %0";
20070     case 1:
20071     case 2:
20072       if (get_attr_mode (insn) == MODE_V4SF)
20073         return "movaps\t{%1, %0|%0, %1}";
20074       else
20075         return "movdqa\t{%1, %0|%0, %1}";
20076     default:
20077       abort ();
20078     }
20079 }
20080   [(set_attr "type" "ssemov")
20081    (set (attr "mode")
20082         (cond [(eq_attr "alternative" "0,1")
20083                  (if_then_else
20084                    (ne (symbol_ref "optimize_size")
20085                        (const_int 0))
20086                    (const_string "V4SF")
20087                    (const_string "TI"))
20088                (eq_attr "alternative" "2")
20089                  (if_then_else
20090                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20091                             (const_int 0))
20092                         (ne (symbol_ref "optimize_size")
20093                             (const_int 0)))
20094                    (const_string "V4SF")
20095                    (const_string "TI"))]
20096                (const_string "TI")))])
20097
20098 (define_insn "*movv16qi_internal"
20099   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
20100         (match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
20101   "TARGET_SSE
20102    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20103 {
20104   switch (which_alternative)
20105     {
20106     case 0:
20107       if (get_attr_mode (insn) == MODE_V4SF)
20108         return "xorps\t%0, %0";
20109       else
20110         return "pxor\t%0, %0";
20111     case 1:
20112     case 2:
20113       if (get_attr_mode (insn) == MODE_V4SF)
20114         return "movaps\t{%1, %0|%0, %1}";
20115       else
20116         return "movdqa\t{%1, %0|%0, %1}";
20117     default:
20118       abort ();
20119     }
20120 }
20121   [(set_attr "type" "ssemov")
20122    (set (attr "mode")
20123         (cond [(eq_attr "alternative" "0,1")
20124                  (if_then_else
20125                    (ne (symbol_ref "optimize_size")
20126                        (const_int 0))
20127                    (const_string "V4SF")
20128                    (const_string "TI"))
20129                (eq_attr "alternative" "2")
20130                  (if_then_else
20131                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20132                             (const_int 0))
20133                         (ne (symbol_ref "optimize_size")
20134                             (const_int 0)))
20135                    (const_string "V4SF")
20136                    (const_string "TI"))]
20137                (const_string "TI")))])
20138
20139 (define_expand "movv2df"
20140   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
20141         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
20142   "TARGET_SSE"
20143 {
20144   ix86_expand_vector_move (V2DFmode, operands);
20145   DONE;
20146 })
20147
20148 (define_expand "movv8hi"
20149   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
20150         (match_operand:V8HI 1 "nonimmediate_operand" ""))]
20151   "TARGET_SSE"
20152 {
20153   ix86_expand_vector_move (V8HImode, operands);
20154   DONE;
20155 })
20156
20157 (define_expand "movv16qi"
20158   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
20159         (match_operand:V16QI 1 "nonimmediate_operand" ""))]
20160   "TARGET_SSE"
20161 {
20162   ix86_expand_vector_move (V16QImode, operands);
20163   DONE;
20164 })
20165
20166 (define_expand "movv4sf"
20167   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20168         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
20169   "TARGET_SSE"
20170 {
20171   ix86_expand_vector_move (V4SFmode, operands);
20172   DONE;
20173 })
20174
20175 (define_expand "movv4si"
20176   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
20177         (match_operand:V4SI 1 "nonimmediate_operand" ""))]
20178   "TARGET_SSE"
20179 {
20180   ix86_expand_vector_move (V4SImode, operands);
20181   DONE;
20182 })
20183
20184 (define_expand "movv2di"
20185   [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
20186         (match_operand:V2DI 1 "nonimmediate_operand" ""))]
20187   "TARGET_SSE"
20188 {
20189   ix86_expand_vector_move (V2DImode, operands);
20190   DONE;
20191 })
20192
20193 (define_expand "movv2si"
20194   [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
20195         (match_operand:V2SI 1 "nonimmediate_operand" ""))]
20196   "TARGET_MMX"
20197 {
20198   ix86_expand_vector_move (V2SImode, operands);
20199   DONE;
20200 })
20201
20202 (define_expand "movv4hi"
20203   [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
20204         (match_operand:V4HI 1 "nonimmediate_operand" ""))]
20205   "TARGET_MMX"
20206 {
20207   ix86_expand_vector_move (V4HImode, operands);
20208   DONE;
20209 })
20210
20211 (define_expand "movv8qi"
20212   [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
20213         (match_operand:V8QI 1 "nonimmediate_operand" ""))]
20214   "TARGET_MMX"
20215 {
20216   ix86_expand_vector_move (V8QImode, operands);
20217   DONE;
20218 })
20219
20220 (define_expand "movv2sf"
20221   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
20222         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
20223   "TARGET_MMX"
20224 {
20225   ix86_expand_vector_move (V2SFmode, operands);
20226   DONE;
20227 })
20228
20229 (define_insn "*pushti"
20230   [(set (match_operand:TI 0 "push_operand" "=<")
20231         (match_operand:TI 1 "register_operand" "x"))]
20232   "TARGET_SSE"
20233   "#")
20234
20235 (define_insn "*pushv2df"
20236   [(set (match_operand:V2DF 0 "push_operand" "=<")
20237         (match_operand:V2DF 1 "register_operand" "x"))]
20238   "TARGET_SSE"
20239   "#")
20240
20241 (define_insn "*pushv2di"
20242   [(set (match_operand:V2DI 0 "push_operand" "=<")
20243         (match_operand:V2DI 1 "register_operand" "x"))]
20244   "TARGET_SSE"
20245   "#")
20246
20247 (define_insn "*pushv8hi"
20248   [(set (match_operand:V8HI 0 "push_operand" "=<")
20249         (match_operand:V8HI 1 "register_operand" "x"))]
20250   "TARGET_SSE"
20251   "#")
20252
20253 (define_insn "*pushv16qi"
20254   [(set (match_operand:V16QI 0 "push_operand" "=<")
20255         (match_operand:V16QI 1 "register_operand" "x"))]
20256   "TARGET_SSE"
20257   "#")
20258
20259 (define_insn "*pushv4sf"
20260   [(set (match_operand:V4SF 0 "push_operand" "=<")
20261         (match_operand:V4SF 1 "register_operand" "x"))]
20262   "TARGET_SSE"
20263   "#")
20264
20265 (define_insn "*pushv4si"
20266   [(set (match_operand:V4SI 0 "push_operand" "=<")
20267         (match_operand:V4SI 1 "register_operand" "x"))]
20268   "TARGET_SSE"
20269   "#")
20270
20271 (define_insn "*pushv2si"
20272   [(set (match_operand:V2SI 0 "push_operand" "=<")
20273         (match_operand:V2SI 1 "register_operand" "y"))]
20274   "TARGET_MMX"
20275   "#")
20276
20277 (define_insn "*pushv4hi"
20278   [(set (match_operand:V4HI 0 "push_operand" "=<")
20279         (match_operand:V4HI 1 "register_operand" "y"))]
20280   "TARGET_MMX"
20281   "#")
20282
20283 (define_insn "*pushv8qi"
20284   [(set (match_operand:V8QI 0 "push_operand" "=<")
20285         (match_operand:V8QI 1 "register_operand" "y"))]
20286   "TARGET_MMX"
20287   "#")
20288
20289 (define_insn "*pushv2sf"
20290   [(set (match_operand:V2SF 0 "push_operand" "=<")
20291         (match_operand:V2SF 1 "register_operand" "y"))]
20292   "TARGET_MMX"
20293   "#")
20294
20295 (define_split
20296   [(set (match_operand 0 "push_operand" "")
20297         (match_operand 1 "register_operand" ""))]
20298   "!TARGET_64BIT && reload_completed
20299    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20300   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20301    (set (match_dup 2) (match_dup 1))]
20302   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20303                                  stack_pointer_rtx);
20304    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20305
20306 (define_split
20307   [(set (match_operand 0 "push_operand" "")
20308         (match_operand 1 "register_operand" ""))]
20309   "TARGET_64BIT && reload_completed
20310    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20311   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20312    (set (match_dup 2) (match_dup 1))]
20313   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20314                                  stack_pointer_rtx);
20315    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20316
20317
20318 (define_insn "*movti_internal"
20319   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
20320         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
20321   "TARGET_SSE && !TARGET_64BIT
20322    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20323 {
20324   switch (which_alternative)
20325     {
20326     case 0:
20327       if (get_attr_mode (insn) == MODE_V4SF)
20328         return "xorps\t%0, %0";
20329       else
20330         return "pxor\t%0, %0";
20331     case 1:
20332     case 2:
20333       if (get_attr_mode (insn) == MODE_V4SF)
20334         return "movaps\t{%1, %0|%0, %1}";
20335       else
20336         return "movdqa\t{%1, %0|%0, %1}";
20337     default:
20338       abort ();
20339     }
20340 }
20341   [(set_attr "type" "ssemov,ssemov,ssemov")
20342    (set (attr "mode")
20343         (cond [(eq_attr "alternative" "0,1")
20344                  (if_then_else
20345                    (ne (symbol_ref "optimize_size")
20346                        (const_int 0))
20347                    (const_string "V4SF")
20348                    (const_string "TI"))
20349                (eq_attr "alternative" "2")
20350                  (if_then_else
20351                    (ne (symbol_ref "optimize_size")
20352                        (const_int 0))
20353                    (const_string "V4SF")
20354                    (const_string "TI"))]
20355                (const_string "TI")))])
20356
20357 (define_insn "*movti_rex64"
20358   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
20359         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
20360   "TARGET_64BIT
20361    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20362 {
20363   switch (which_alternative)
20364     {
20365     case 0:
20366     case 1:
20367       return "#";
20368     case 2:
20369       if (get_attr_mode (insn) == MODE_V4SF)
20370         return "xorps\t%0, %0";
20371       else
20372         return "pxor\t%0, %0";
20373     case 3:
20374     case 4:
20375       if (get_attr_mode (insn) == MODE_V4SF)
20376         return "movaps\t{%1, %0|%0, %1}";
20377       else
20378         return "movdqa\t{%1, %0|%0, %1}";
20379     default:
20380       abort ();
20381     }
20382 }
20383   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20384    (set (attr "mode")
20385         (cond [(eq_attr "alternative" "2,3")
20386                  (if_then_else
20387                    (ne (symbol_ref "optimize_size")
20388                        (const_int 0))
20389                    (const_string "V4SF")
20390                    (const_string "TI"))
20391                (eq_attr "alternative" "4")
20392                  (if_then_else
20393                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20394                             (const_int 0))
20395                         (ne (symbol_ref "optimize_size")
20396                             (const_int 0)))
20397                    (const_string "V4SF")
20398                    (const_string "TI"))]
20399                (const_string "DI")))])
20400
20401 (define_insn "*movtf_rex64"
20402   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20403         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20404   "TARGET_64BIT
20405    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20406 {
20407   switch (which_alternative)
20408     {
20409     case 0:
20410     case 1:
20411       return "#";
20412     case 2:
20413       if (get_attr_mode (insn) == MODE_V4SF)
20414         return "xorps\t%0, %0";
20415       else
20416         return "pxor\t%0, %0";
20417     case 3:
20418     case 4:
20419       if (get_attr_mode (insn) == MODE_V4SF)
20420         return "movaps\t{%1, %0|%0, %1}";
20421       else
20422         return "movdqa\t{%1, %0|%0, %1}";
20423     default:
20424       abort ();
20425     }
20426 }
20427   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20428    (set (attr "mode")
20429         (cond [(eq_attr "alternative" "2,3")
20430                  (if_then_else
20431                    (ne (symbol_ref "optimize_size")
20432                        (const_int 0))
20433                    (const_string "V4SF")
20434                    (const_string "TI"))
20435                (eq_attr "alternative" "4")
20436                  (if_then_else
20437                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20438                             (const_int 0))
20439                         (ne (symbol_ref "optimize_size")
20440                             (const_int 0)))
20441                    (const_string "V4SF")
20442                    (const_string "TI"))]
20443                (const_string "DI")))])
20444
20445 (define_split
20446   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20447         (match_operand:TI 1 "general_operand" ""))]
20448   "reload_completed && !SSE_REG_P (operands[0])
20449    && !SSE_REG_P (operands[1])"
20450   [(const_int 0)]
20451   "ix86_split_long_move (operands); DONE;")
20452
20453 (define_split
20454   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20455         (match_operand:TF 1 "general_operand" ""))]
20456   "reload_completed && !SSE_REG_P (operands[0])
20457    && !SSE_REG_P (operands[1])"
20458   [(const_int 0)]
20459   "ix86_split_long_move (operands); DONE;")
20460
20461 ;; These two patterns are useful for specifying exactly whether to use
20462 ;; movaps or movups
20463 (define_expand "sse_movaps"
20464   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20465         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20466                      UNSPEC_MOVA))]
20467   "TARGET_SSE"
20468 {
20469   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20470     {
20471       rtx tmp = gen_reg_rtx (V4SFmode);
20472       emit_insn (gen_sse_movaps (tmp, operands[1]));
20473       emit_move_insn (operands[0], tmp);
20474       DONE;
20475     }
20476 })
20477
20478 (define_insn "*sse_movaps_1"
20479   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20480         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20481                      UNSPEC_MOVA))]
20482   "TARGET_SSE
20483    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20484   "movaps\t{%1, %0|%0, %1}"
20485   [(set_attr "type" "ssemov,ssemov")
20486    (set_attr "mode" "V4SF")])
20487
20488 (define_expand "sse_movups"
20489   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20490         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20491                      UNSPEC_MOVU))]
20492   "TARGET_SSE"
20493 {
20494   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20495     {
20496       rtx tmp = gen_reg_rtx (V4SFmode);
20497       emit_insn (gen_sse_movups (tmp, operands[1]));
20498       emit_move_insn (operands[0], tmp);
20499       DONE;
20500     }
20501 })
20502
20503 (define_insn "*sse_movups_1"
20504   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20505         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20506                      UNSPEC_MOVU))]
20507   "TARGET_SSE
20508    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20509   "movups\t{%1, %0|%0, %1}"
20510   [(set_attr "type" "ssecvt,ssecvt")
20511    (set_attr "mode" "V4SF")])
20512
20513 ;; SSE Strange Moves.
20514
20515 (define_insn "sse_movmskps"
20516   [(set (match_operand:SI 0 "register_operand" "=r")
20517         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20518                    UNSPEC_MOVMSK))]
20519   "TARGET_SSE"
20520   "movmskps\t{%1, %0|%0, %1}"
20521   [(set_attr "type" "ssecvt")
20522    (set_attr "mode" "V4SF")])
20523
20524 (define_insn "mmx_pmovmskb"
20525   [(set (match_operand:SI 0 "register_operand" "=r")
20526         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20527                    UNSPEC_MOVMSK))]
20528   "TARGET_SSE || TARGET_3DNOW_A"
20529   "pmovmskb\t{%1, %0|%0, %1}"
20530   [(set_attr "type" "ssecvt")
20531    (set_attr "mode" "V4SF")])
20532
20533
20534 (define_insn "mmx_maskmovq"
20535   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20536         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20537                       (match_operand:V8QI 2 "register_operand" "y")]
20538                      UNSPEC_MASKMOV))]
20539   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20540   ;; @@@ check ordering of operands in intel/nonintel syntax
20541   "maskmovq\t{%2, %1|%1, %2}"
20542   [(set_attr "type" "mmxcvt")
20543    (set_attr "mode" "DI")])
20544
20545 (define_insn "mmx_maskmovq_rex"
20546   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20547         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20548                       (match_operand:V8QI 2 "register_operand" "y")]
20549                      UNSPEC_MASKMOV))]
20550   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20551   ;; @@@ check ordering of operands in intel/nonintel syntax
20552   "maskmovq\t{%2, %1|%1, %2}"
20553   [(set_attr "type" "mmxcvt")
20554    (set_attr "mode" "DI")])
20555
20556 (define_insn "sse_movntv4sf"
20557   [(set (match_operand:V4SF 0 "memory_operand" "=m")
20558         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20559                      UNSPEC_MOVNT))]
20560   "TARGET_SSE"
20561   "movntps\t{%1, %0|%0, %1}"
20562   [(set_attr "type" "ssemov")
20563    (set_attr "mode" "V4SF")])
20564
20565 (define_insn "sse_movntdi"
20566   [(set (match_operand:DI 0 "memory_operand" "=m")
20567         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20568                    UNSPEC_MOVNT))]
20569   "TARGET_SSE || TARGET_3DNOW_A"
20570   "movntq\t{%1, %0|%0, %1}"
20571   [(set_attr "type" "mmxmov")
20572    (set_attr "mode" "DI")])
20573
20574 (define_insn "sse_movhlps"
20575   [(set (match_operand:V4SF 0 "register_operand" "=x")
20576         (vec_merge:V4SF
20577          (match_operand:V4SF 1 "register_operand" "0")
20578          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20579                           (parallel [(const_int 2)
20580                                      (const_int 3)
20581                                      (const_int 0)
20582                                      (const_int 1)]))
20583          (const_int 3)))]
20584   "TARGET_SSE"
20585   "movhlps\t{%2, %0|%0, %2}"
20586   [(set_attr "type" "ssecvt")
20587    (set_attr "mode" "V4SF")])
20588
20589 (define_insn "sse_movlhps"
20590   [(set (match_operand:V4SF 0 "register_operand" "=x")
20591         (vec_merge:V4SF
20592          (match_operand:V4SF 1 "register_operand" "0")
20593          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20594                           (parallel [(const_int 2)
20595                                      (const_int 3)
20596                                      (const_int 0)
20597                                      (const_int 1)]))
20598          (const_int 12)))]
20599   "TARGET_SSE"
20600   "movlhps\t{%2, %0|%0, %2}"
20601   [(set_attr "type" "ssecvt")
20602    (set_attr "mode" "V4SF")])
20603
20604 (define_insn "sse_movhps"
20605   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20606         (vec_merge:V4SF
20607          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20608          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20609          (const_int 12)))]
20610   "TARGET_SSE
20611    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20612   "movhps\t{%2, %0|%0, %2}"
20613   [(set_attr "type" "ssecvt")
20614    (set_attr "mode" "V4SF")])
20615
20616 (define_insn "sse_movlps"
20617   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20618         (vec_merge:V4SF
20619          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20620          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20621          (const_int 3)))]
20622   "TARGET_SSE
20623    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20624   "movlps\t{%2, %0|%0, %2}"
20625   [(set_attr "type" "ssecvt")
20626    (set_attr "mode" "V4SF")])
20627
20628 (define_expand "sse_loadss"
20629   [(match_operand:V4SF 0 "register_operand" "")
20630    (match_operand:SF 1 "memory_operand" "")]
20631   "TARGET_SSE"
20632 {
20633   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20634                                CONST0_RTX (V4SFmode)));
20635   DONE;
20636 })
20637
20638 (define_insn "sse_loadss_1"
20639   [(set (match_operand:V4SF 0 "register_operand" "=x")
20640         (vec_merge:V4SF
20641          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20642          (match_operand:V4SF 2 "const0_operand" "X")
20643          (const_int 1)))]
20644   "TARGET_SSE"
20645   "movss\t{%1, %0|%0, %1}"
20646   [(set_attr "type" "ssemov")
20647    (set_attr "mode" "SF")])
20648
20649 (define_insn "sse_movss"
20650   [(set (match_operand:V4SF 0 "register_operand" "=x")
20651         (vec_merge:V4SF
20652          (match_operand:V4SF 1 "register_operand" "0")
20653          (match_operand:V4SF 2 "register_operand" "x")
20654          (const_int 14)))]
20655   "TARGET_SSE"
20656   "movss\t{%2, %0|%0, %2}"
20657   [(set_attr "type" "ssemov")
20658    (set_attr "mode" "SF")])
20659
20660 (define_insn "sse_storess"
20661   [(set (match_operand:SF 0 "memory_operand" "=m")
20662         (vec_select:SF
20663          (match_operand:V4SF 1 "register_operand" "x")
20664          (parallel [(const_int 0)])))]
20665   "TARGET_SSE"
20666   "movss\t{%1, %0|%0, %1}"
20667   [(set_attr "type" "ssemov")
20668    (set_attr "mode" "SF")])
20669
20670 (define_insn "sse_shufps"
20671   [(set (match_operand:V4SF 0 "register_operand" "=x")
20672         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20673                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20674                       (match_operand:SI 3 "immediate_operand" "i")]
20675                      UNSPEC_SHUFFLE))]
20676   "TARGET_SSE"
20677   ;; @@@ check operand order for intel/nonintel syntax
20678   "shufps\t{%3, %2, %0|%0, %2, %3}"
20679   [(set_attr "type" "ssecvt")
20680    (set_attr "mode" "V4SF")])
20681
20682
20683 ;; SSE arithmetic
20684
20685 (define_insn "addv4sf3"
20686   [(set (match_operand:V4SF 0 "register_operand" "=x")
20687         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20688                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20689   "TARGET_SSE"
20690   "addps\t{%2, %0|%0, %2}"
20691   [(set_attr "type" "sseadd")
20692    (set_attr "mode" "V4SF")])
20693
20694 (define_insn "vmaddv4sf3"
20695   [(set (match_operand:V4SF 0 "register_operand" "=x")
20696         (vec_merge:V4SF
20697          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20698                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20699          (match_dup 1)
20700          (const_int 1)))]
20701   "TARGET_SSE"
20702   "addss\t{%2, %0|%0, %2}"
20703   [(set_attr "type" "sseadd")
20704    (set_attr "mode" "SF")])
20705
20706 (define_insn "subv4sf3"
20707   [(set (match_operand:V4SF 0 "register_operand" "=x")
20708         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20709                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20710   "TARGET_SSE"
20711   "subps\t{%2, %0|%0, %2}"
20712   [(set_attr "type" "sseadd")
20713    (set_attr "mode" "V4SF")])
20714
20715 (define_insn "vmsubv4sf3"
20716   [(set (match_operand:V4SF 0 "register_operand" "=x")
20717         (vec_merge:V4SF
20718          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20719                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20720          (match_dup 1)
20721          (const_int 1)))]
20722   "TARGET_SSE"
20723   "subss\t{%2, %0|%0, %2}"
20724   [(set_attr "type" "sseadd")
20725    (set_attr "mode" "SF")])
20726
20727 ;; ??? Should probably be done by generic code instead.
20728 (define_expand "negv4sf2"
20729   [(set (match_operand:V4SF 0 "register_operand" "")
20730         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20731                   (match_dup 2)))]
20732   "TARGET_SSE"
20733 {
20734   rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20735   rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20736   operands[2] = force_reg (V4SFmode, vm0);
20737 })
20738
20739 (define_insn "mulv4sf3"
20740   [(set (match_operand:V4SF 0 "register_operand" "=x")
20741         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20742                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20743   "TARGET_SSE"
20744   "mulps\t{%2, %0|%0, %2}"
20745   [(set_attr "type" "ssemul")
20746    (set_attr "mode" "V4SF")])
20747
20748 (define_insn "vmmulv4sf3"
20749   [(set (match_operand:V4SF 0 "register_operand" "=x")
20750         (vec_merge:V4SF
20751          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20752                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20753          (match_dup 1)
20754          (const_int 1)))]
20755   "TARGET_SSE"
20756   "mulss\t{%2, %0|%0, %2}"
20757   [(set_attr "type" "ssemul")
20758    (set_attr "mode" "SF")])
20759
20760 (define_insn "divv4sf3"
20761   [(set (match_operand:V4SF 0 "register_operand" "=x")
20762         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20763                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20764   "TARGET_SSE"
20765   "divps\t{%2, %0|%0, %2}"
20766   [(set_attr "type" "ssediv")
20767    (set_attr "mode" "V4SF")])
20768
20769 (define_insn "vmdivv4sf3"
20770   [(set (match_operand:V4SF 0 "register_operand" "=x")
20771         (vec_merge:V4SF
20772          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20773                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20774          (match_dup 1)
20775          (const_int 1)))]
20776   "TARGET_SSE"
20777   "divss\t{%2, %0|%0, %2}"
20778   [(set_attr "type" "ssediv")
20779    (set_attr "mode" "SF")])
20780
20781
20782 ;; SSE square root/reciprocal
20783
20784 (define_insn "rcpv4sf2"
20785   [(set (match_operand:V4SF 0 "register_operand" "=x")
20786         (unspec:V4SF
20787          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20788   "TARGET_SSE"
20789   "rcpps\t{%1, %0|%0, %1}"
20790   [(set_attr "type" "sse")
20791    (set_attr "mode" "V4SF")])
20792
20793 (define_insn "vmrcpv4sf2"
20794   [(set (match_operand:V4SF 0 "register_operand" "=x")
20795         (vec_merge:V4SF
20796          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20797                       UNSPEC_RCP)
20798          (match_operand:V4SF 2 "register_operand" "0")
20799          (const_int 1)))]
20800   "TARGET_SSE"
20801   "rcpss\t{%1, %0|%0, %1}"
20802   [(set_attr "type" "sse")
20803    (set_attr "mode" "SF")])
20804
20805 (define_insn "rsqrtv4sf2"
20806   [(set (match_operand:V4SF 0 "register_operand" "=x")
20807         (unspec:V4SF
20808          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20809   "TARGET_SSE"
20810   "rsqrtps\t{%1, %0|%0, %1}"
20811   [(set_attr "type" "sse")
20812    (set_attr "mode" "V4SF")])
20813
20814 (define_insn "vmrsqrtv4sf2"
20815   [(set (match_operand:V4SF 0 "register_operand" "=x")
20816         (vec_merge:V4SF
20817          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20818                       UNSPEC_RSQRT)
20819          (match_operand:V4SF 2 "register_operand" "0")
20820          (const_int 1)))]
20821   "TARGET_SSE"
20822   "rsqrtss\t{%1, %0|%0, %1}"
20823   [(set_attr "type" "sse")
20824    (set_attr "mode" "SF")])
20825
20826 (define_insn "sqrtv4sf2"
20827   [(set (match_operand:V4SF 0 "register_operand" "=x")
20828         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20829   "TARGET_SSE"
20830   "sqrtps\t{%1, %0|%0, %1}"
20831   [(set_attr "type" "sse")
20832    (set_attr "mode" "V4SF")])
20833
20834 (define_insn "vmsqrtv4sf2"
20835   [(set (match_operand:V4SF 0 "register_operand" "=x")
20836         (vec_merge:V4SF
20837          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20838          (match_operand:V4SF 2 "register_operand" "0")
20839          (const_int 1)))]
20840   "TARGET_SSE"
20841   "sqrtss\t{%1, %0|%0, %1}"
20842   [(set_attr "type" "sse")
20843    (set_attr "mode" "SF")])
20844
20845 ;; SSE logical operations.
20846
20847 ;; SSE defines logical operations on floating point values.  This brings
20848 ;; interesting challenge to RTL representation where logicals are only valid
20849 ;; on integral types.  We deal with this by representing the floating point
20850 ;; logical as logical on arguments casted to TImode as this is what hardware
20851 ;; really does.  Unfortunately hardware requires the type information to be
20852 ;; present and thus we must avoid subregs from being simplified and eliminated
20853 ;; in later compilation phases.
20854 ;;
20855 ;; We have following variants from each instruction:
20856 ;; sse_andsf3 - the operation taking V4SF vector operands
20857 ;;              and doing TImode cast on them
20858 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20859 ;;                      TImode, since backend insist on eliminating casts
20860 ;;                      on memory operands
20861 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20862 ;;                   We cannot accept memory operand here as instruction reads
20863 ;;                   whole scalar.  This is generated only post reload by GCC
20864 ;;                   scalar float operations that expands to logicals (fabs)
20865 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20866 ;;                   memory operand.  Eventually combine can be able
20867 ;;                   to synthesize these using splitter.
20868 ;; sse2_anddf3, *sse2_anddf3_memory
20869 ;;              
20870 ;; 
20871 ;; These are not called andti3 etc. because we really really don't want
20872 ;; the compiler to widen DImode ands to TImode ands and then try to move
20873 ;; into DImode subregs of SSE registers, and them together, and move out
20874 ;; of DImode subregs again!
20875 ;; SSE1 single precision floating point logical operation
20876 (define_expand "sse_andv4sf3"
20877   [(set (match_operand:V4SF 0 "register_operand" "")
20878         (and:V4SF (match_operand:V4SF 1 "register_operand" "")
20879                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20880   "TARGET_SSE"
20881   "")
20882
20883 (define_insn "*sse_andv4sf3"
20884   [(set (match_operand:V4SF 0 "register_operand" "=x")
20885         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20886                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20887   "TARGET_SSE
20888    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20889   "andps\t{%2, %0|%0, %2}"
20890   [(set_attr "type" "sselog")
20891    (set_attr "mode" "V4SF")])
20892
20893 (define_expand "sse_nandv4sf3"
20894   [(set (match_operand:V4SF 0 "register_operand" "")
20895         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
20896                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20897   "TARGET_SSE"
20898   "")
20899
20900 (define_insn "*sse_nandv4sf3"
20901   [(set (match_operand:V4SF 0 "register_operand" "=x")
20902         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
20903                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20904   "TARGET_SSE"
20905   "andnps\t{%2, %0|%0, %2}"
20906   [(set_attr "type" "sselog")
20907    (set_attr "mode" "V4SF")])
20908
20909 (define_expand "sse_iorv4sf3"
20910   [(set (match_operand:V4SF 0 "register_operand" "")
20911         (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
20912                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20913   "TARGET_SSE"
20914   "")
20915
20916 (define_insn "*sse_iorv4sf3"
20917   [(set (match_operand:V4SF 0 "register_operand" "=x")
20918         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20919                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20920   "TARGET_SSE
20921    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20922   "orps\t{%2, %0|%0, %2}"
20923   [(set_attr "type" "sselog")
20924    (set_attr "mode" "V4SF")])
20925
20926 (define_expand "sse_xorv4sf3"
20927   [(set (match_operand:V4SF 0 "register_operand" "")
20928         (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
20929                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20930   "TARGET_SSE"
20931   "")
20932
20933 (define_insn "*sse_xorv4sf3"
20934   [(set (match_operand:V4SF 0 "register_operand" "=x")
20935         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20936                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20937   "TARGET_SSE
20938    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20939   "xorps\t{%2, %0|%0, %2}"
20940   [(set_attr "type" "sselog")
20941    (set_attr "mode" "V4SF")])
20942
20943 ;; SSE2 double precision floating point logical operation
20944
20945 (define_expand "sse2_andv2df3"
20946   [(set (match_operand:V2DF 0 "register_operand" "")
20947         (and:V2DF (match_operand:V2DF 1 "register_operand" "")
20948                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20949   "TARGET_SSE2"
20950   "")
20951
20952 (define_insn "*sse2_andv2df3"
20953   [(set (match_operand:V2DF 0 "register_operand" "=x")
20954         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20955                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20956   "TARGET_SSE2
20957    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20958   "andpd\t{%2, %0|%0, %2}"
20959   [(set_attr "type" "sselog")
20960    (set_attr "mode" "V2DF")])
20961
20962 (define_expand "sse2_nandv2df3"
20963   [(set (match_operand:V2DF 0 "register_operand" "")
20964         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
20965                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20966   "TARGET_SSE2"
20967   "")
20968
20969 (define_insn "*sse2_nandv2df3"
20970   [(set (match_operand:V2DF 0 "register_operand" "=x")
20971         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
20972                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20973   "TARGET_SSE2"
20974   "andnpd\t{%2, %0|%0, %2}"
20975   [(set_attr "type" "sselog")
20976    (set_attr "mode" "V2DF")])
20977
20978 (define_expand "sse2_iorv2df3"
20979   [(set (match_operand:V2DF 0 "register_operand" "")
20980         (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
20981                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20982   "TARGET_SSE2"
20983   "")
20984
20985 (define_insn "*sse2_iorv2df3"
20986   [(set (match_operand:V2DF 0 "register_operand" "=x")
20987         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20988                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20989   "TARGET_SSE2
20990    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20991   "orpd\t{%2, %0|%0, %2}"
20992   [(set_attr "type" "sselog")
20993    (set_attr "mode" "V2DF")])
20994
20995 (define_expand "sse2_xorv2df3"
20996   [(set (match_operand:V2DF 0 "register_operand" "")
20997         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
20998                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20999   "TARGET_SSE2"
21000   "")
21001
21002 (define_insn "*sse2_xorv2df3"
21003   [(set (match_operand:V2DF 0 "register_operand" "=x")
21004         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21005                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21006   "TARGET_SSE2
21007    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21008   "xorpd\t{%2, %0|%0, %2}"
21009   [(set_attr "type" "sselog")
21010    (set_attr "mode" "V2DF")])
21011
21012 ;; SSE2 integral logicals.  These patterns must always come after floating
21013 ;; point ones since we don't want compiler to use integer opcodes on floating
21014 ;; point SSE values to avoid matching of subregs in the match_operand.
21015 (define_insn "*sse2_andti3"
21016   [(set (match_operand:TI 0 "register_operand" "=x")
21017         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21018                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21019   "TARGET_SSE2
21020    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21021   "pand\t{%2, %0|%0, %2}"
21022   [(set_attr "type" "sselog")
21023    (set_attr "mode" "TI")])
21024
21025 (define_insn "sse2_andv2di3"
21026   [(set (match_operand:V2DI 0 "register_operand" "=x")
21027         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21028                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21029   "TARGET_SSE2
21030    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21031   "pand\t{%2, %0|%0, %2}"
21032   [(set_attr "type" "sselog")
21033    (set_attr "mode" "TI")])
21034
21035 (define_insn "*sse2_nandti3"
21036   [(set (match_operand:TI 0 "register_operand" "=x")
21037         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
21038                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21039   "TARGET_SSE2"
21040   "pandn\t{%2, %0|%0, %2}"
21041   [(set_attr "type" "sselog")
21042    (set_attr "mode" "TI")])
21043
21044 (define_insn "sse2_nandv2di3"
21045   [(set (match_operand:V2DI 0 "register_operand" "=x")
21046         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
21047                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21048   "TARGET_SSE2
21049    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21050   "pandn\t{%2, %0|%0, %2}"
21051   [(set_attr "type" "sselog")
21052    (set_attr "mode" "TI")])
21053
21054 (define_insn "*sse2_iorti3"
21055   [(set (match_operand:TI 0 "register_operand" "=x")
21056         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21057                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21058   "TARGET_SSE2
21059    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21060   "por\t{%2, %0|%0, %2}"
21061   [(set_attr "type" "sselog")
21062    (set_attr "mode" "TI")])
21063
21064 (define_insn "sse2_iorv2di3"
21065   [(set (match_operand:V2DI 0 "register_operand" "=x")
21066         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21067                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21068   "TARGET_SSE2
21069    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21070   "por\t{%2, %0|%0, %2}"
21071   [(set_attr "type" "sselog")
21072    (set_attr "mode" "TI")])
21073
21074 (define_insn "*sse2_xorti3"
21075   [(set (match_operand:TI 0 "register_operand" "=x")
21076         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21077                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21078   "TARGET_SSE2
21079    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21080   "pxor\t{%2, %0|%0, %2}"
21081   [(set_attr "type" "sselog")
21082    (set_attr "mode" "TI")])
21083
21084 (define_insn "sse2_xorv2di3"
21085   [(set (match_operand:V2DI 0 "register_operand" "=x")
21086         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21087                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21088   "TARGET_SSE2
21089    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21090   "pxor\t{%2, %0|%0, %2}"
21091   [(set_attr "type" "sselog")
21092    (set_attr "mode" "TI")])
21093
21094 ;; Use xor, but don't show input operands so they aren't live before
21095 ;; this insn.
21096 (define_insn "sse_clrv4sf"
21097   [(set (match_operand:V4SF 0 "register_operand" "=x")
21098         (match_operand:V4SF 1 "const0_operand" "X"))]
21099   "TARGET_SSE"
21100 {
21101   if (get_attr_mode (insn) == MODE_TI)
21102     return "pxor\t{%0, %0|%0, %0}";
21103   else
21104     return "xorps\t{%0, %0|%0, %0}";
21105 }
21106   [(set_attr "type" "sselog")
21107    (set_attr "memory" "none")
21108    (set (attr "mode")
21109         (if_then_else
21110            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
21111                          (const_int 0))
21112                      (ne (symbol_ref "TARGET_SSE2")
21113                          (const_int 0)))
21114                 (eq (symbol_ref "optimize_size")
21115                     (const_int 0)))
21116          (const_string "TI")
21117          (const_string "V4SF")))])
21118
21119 ;; Use xor, but don't show input operands so they aren't live before
21120 ;; this insn.
21121 (define_insn "sse_clrv2df"
21122   [(set (match_operand:V2DF 0 "register_operand" "=x")
21123         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
21124   "TARGET_SSE2"
21125   "xorpd\t{%0, %0|%0, %0}"
21126   [(set_attr "type" "sselog")
21127    (set_attr "memory" "none")
21128    (set_attr "mode" "V4SF")])
21129
21130 ;; SSE mask-generating compares
21131
21132 (define_insn "maskcmpv4sf3"
21133   [(set (match_operand:V4SI 0 "register_operand" "=x")
21134         (match_operator:V4SI 3 "sse_comparison_operator"
21135                 [(match_operand:V4SF 1 "register_operand" "0")
21136                  (match_operand:V4SF 2 "register_operand" "x")]))]
21137   "TARGET_SSE"
21138   "cmp%D3ps\t{%2, %0|%0, %2}"
21139   [(set_attr "type" "ssecmp")
21140    (set_attr "mode" "V4SF")])
21141
21142 (define_insn "maskncmpv4sf3"
21143   [(set (match_operand:V4SI 0 "register_operand" "=x")
21144         (not:V4SI
21145          (match_operator:V4SI 3 "sse_comparison_operator"
21146                 [(match_operand:V4SF 1 "register_operand" "0")
21147                  (match_operand:V4SF 2 "register_operand" "x")])))]
21148   "TARGET_SSE"
21149 {
21150   if (GET_CODE (operands[3]) == UNORDERED)
21151     return "cmpordps\t{%2, %0|%0, %2}";
21152   else
21153     return "cmpn%D3ps\t{%2, %0|%0, %2}";
21154 }
21155   [(set_attr "type" "ssecmp")
21156    (set_attr "mode" "V4SF")])
21157
21158 (define_insn "vmmaskcmpv4sf3"
21159   [(set (match_operand:V4SI 0 "register_operand" "=x")
21160         (vec_merge:V4SI
21161          (match_operator:V4SI 3 "sse_comparison_operator"
21162                 [(match_operand:V4SF 1 "register_operand" "0")
21163                  (match_operand:V4SF 2 "register_operand" "x")])
21164          (subreg:V4SI (match_dup 1) 0)
21165          (const_int 1)))]
21166   "TARGET_SSE"
21167   "cmp%D3ss\t{%2, %0|%0, %2}"
21168   [(set_attr "type" "ssecmp")
21169    (set_attr "mode" "SF")])
21170
21171 (define_insn "vmmaskncmpv4sf3"
21172   [(set (match_operand:V4SI 0 "register_operand" "=x")
21173         (vec_merge:V4SI
21174          (not:V4SI
21175           (match_operator:V4SI 3 "sse_comparison_operator"
21176                 [(match_operand:V4SF 1 "register_operand" "0")
21177                  (match_operand:V4SF 2 "register_operand" "x")]))
21178          (subreg:V4SI (match_dup 1) 0)
21179          (const_int 1)))]
21180   "TARGET_SSE"
21181 {
21182   if (GET_CODE (operands[3]) == UNORDERED)
21183     return "cmpordss\t{%2, %0|%0, %2}";
21184   else
21185     return "cmpn%D3ss\t{%2, %0|%0, %2}";
21186 }
21187   [(set_attr "type" "ssecmp")
21188    (set_attr "mode" "SF")])
21189
21190 (define_insn "sse_comi"
21191   [(set (reg:CCFP FLAGS_REG)
21192         (compare:CCFP (vec_select:SF
21193                        (match_operand:V4SF 0 "register_operand" "x")
21194                        (parallel [(const_int 0)]))
21195                       (vec_select:SF
21196                        (match_operand:V4SF 1 "register_operand" "x")
21197                        (parallel [(const_int 0)]))))]
21198   "TARGET_SSE"
21199   "comiss\t{%1, %0|%0, %1}"
21200   [(set_attr "type" "ssecomi")
21201    (set_attr "mode" "SF")])
21202
21203 (define_insn "sse_ucomi"
21204   [(set (reg:CCFPU FLAGS_REG)
21205         (compare:CCFPU (vec_select:SF
21206                         (match_operand:V4SF 0 "register_operand" "x")
21207                         (parallel [(const_int 0)]))
21208                        (vec_select:SF
21209                         (match_operand:V4SF 1 "register_operand" "x")
21210                         (parallel [(const_int 0)]))))]
21211   "TARGET_SSE"
21212   "ucomiss\t{%1, %0|%0, %1}"
21213   [(set_attr "type" "ssecomi")
21214    (set_attr "mode" "SF")])
21215
21216
21217 ;; SSE unpack
21218
21219 (define_insn "sse_unpckhps"
21220   [(set (match_operand:V4SF 0 "register_operand" "=x")
21221         (vec_merge:V4SF
21222          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21223                           (parallel [(const_int 2)
21224                                      (const_int 0)
21225                                      (const_int 3)
21226                                      (const_int 1)]))
21227          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21228                           (parallel [(const_int 0)
21229                                      (const_int 2)
21230                                      (const_int 1)
21231                                      (const_int 3)]))
21232          (const_int 5)))]
21233   "TARGET_SSE"
21234   "unpckhps\t{%2, %0|%0, %2}"
21235   [(set_attr "type" "ssecvt")
21236    (set_attr "mode" "V4SF")])
21237
21238 (define_insn "sse_unpcklps"
21239   [(set (match_operand:V4SF 0 "register_operand" "=x")
21240         (vec_merge:V4SF
21241          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21242                           (parallel [(const_int 0)
21243                                      (const_int 2)
21244                                      (const_int 1)
21245                                      (const_int 3)]))
21246          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21247                           (parallel [(const_int 2)
21248                                      (const_int 0)
21249                                      (const_int 3)
21250                                      (const_int 1)]))
21251          (const_int 5)))]
21252   "TARGET_SSE"
21253   "unpcklps\t{%2, %0|%0, %2}"
21254   [(set_attr "type" "ssecvt")
21255    (set_attr "mode" "V4SF")])
21256
21257
21258 ;; SSE min/max
21259
21260 (define_insn "smaxv4sf3"
21261   [(set (match_operand:V4SF 0 "register_operand" "=x")
21262         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21263                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21264   "TARGET_SSE"
21265   "maxps\t{%2, %0|%0, %2}"
21266   [(set_attr "type" "sse")
21267    (set_attr "mode" "V4SF")])
21268
21269 (define_insn "vmsmaxv4sf3"
21270   [(set (match_operand:V4SF 0 "register_operand" "=x")
21271         (vec_merge:V4SF
21272          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21273                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21274          (match_dup 1)
21275          (const_int 1)))]
21276   "TARGET_SSE"
21277   "maxss\t{%2, %0|%0, %2}"
21278   [(set_attr "type" "sse")
21279    (set_attr "mode" "SF")])
21280
21281 (define_insn "sminv4sf3"
21282   [(set (match_operand:V4SF 0 "register_operand" "=x")
21283         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21284                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21285   "TARGET_SSE"
21286   "minps\t{%2, %0|%0, %2}"
21287   [(set_attr "type" "sse")
21288    (set_attr "mode" "V4SF")])
21289
21290 (define_insn "vmsminv4sf3"
21291   [(set (match_operand:V4SF 0 "register_operand" "=x")
21292         (vec_merge:V4SF
21293          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21294                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21295          (match_dup 1)
21296          (const_int 1)))]
21297   "TARGET_SSE"
21298   "minss\t{%2, %0|%0, %2}"
21299   [(set_attr "type" "sse")
21300    (set_attr "mode" "SF")])
21301
21302 ;; SSE <-> integer/MMX conversions
21303
21304 (define_insn "cvtpi2ps"
21305   [(set (match_operand:V4SF 0 "register_operand" "=x")
21306         (vec_merge:V4SF
21307          (match_operand:V4SF 1 "register_operand" "0")
21308          (vec_duplicate:V4SF
21309           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
21310          (const_int 12)))]
21311   "TARGET_SSE"
21312   "cvtpi2ps\t{%2, %0|%0, %2}"
21313   [(set_attr "type" "ssecvt")
21314    (set_attr "mode" "V4SF")])
21315
21316 (define_insn "cvtps2pi"
21317   [(set (match_operand:V2SI 0 "register_operand" "=y")
21318         (vec_select:V2SI
21319          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21320          (parallel [(const_int 0) (const_int 1)])))]
21321   "TARGET_SSE"
21322   "cvtps2pi\t{%1, %0|%0, %1}"
21323   [(set_attr "type" "ssecvt")
21324    (set_attr "mode" "V4SF")])
21325
21326 (define_insn "cvttps2pi"
21327   [(set (match_operand:V2SI 0 "register_operand" "=y")
21328         (vec_select:V2SI
21329          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21330                       UNSPEC_FIX)
21331          (parallel [(const_int 0) (const_int 1)])))]
21332   "TARGET_SSE"
21333   "cvttps2pi\t{%1, %0|%0, %1}"
21334   [(set_attr "type" "ssecvt")
21335    (set_attr "mode" "SF")])
21336
21337 (define_insn "cvtsi2ss"
21338   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21339         (vec_merge:V4SF
21340          (match_operand:V4SF 1 "register_operand" "0,0")
21341          (vec_duplicate:V4SF
21342           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21343          (const_int 14)))]
21344   "TARGET_SSE"
21345   "cvtsi2ss\t{%2, %0|%0, %2}"
21346   [(set_attr "type" "sseicvt")
21347    (set_attr "athlon_decode" "vector,double")
21348    (set_attr "mode" "SF")])
21349
21350 (define_insn "cvtsi2ssq"
21351   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21352         (vec_merge:V4SF
21353          (match_operand:V4SF 1 "register_operand" "0,0")
21354          (vec_duplicate:V4SF
21355           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21356          (const_int 14)))]
21357   "TARGET_SSE && TARGET_64BIT"
21358   "cvtsi2ssq\t{%2, %0|%0, %2}"
21359   [(set_attr "type" "sseicvt")
21360    (set_attr "athlon_decode" "vector,double")
21361    (set_attr "mode" "SF")])
21362
21363 (define_insn "cvtss2si"
21364   [(set (match_operand:SI 0 "register_operand" "=r,r")
21365         (vec_select:SI
21366          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21367          (parallel [(const_int 0)])))]
21368   "TARGET_SSE"
21369   "cvtss2si\t{%1, %0|%0, %1}"
21370   [(set_attr "type" "sseicvt")
21371    (set_attr "athlon_decode" "double,vector")
21372    (set_attr "mode" "SI")])
21373
21374 (define_insn "cvtss2siq"
21375   [(set (match_operand:DI 0 "register_operand" "=r,r")
21376         (vec_select:DI
21377          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21378          (parallel [(const_int 0)])))]
21379   "TARGET_SSE"
21380   "cvtss2siq\t{%1, %0|%0, %1}"
21381   [(set_attr "type" "sseicvt")
21382    (set_attr "athlon_decode" "double,vector")
21383    (set_attr "mode" "DI")])
21384
21385 (define_insn "cvttss2si"
21386   [(set (match_operand:SI 0 "register_operand" "=r,r")
21387         (vec_select:SI
21388          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21389                       UNSPEC_FIX)
21390          (parallel [(const_int 0)])))]
21391   "TARGET_SSE"
21392   "cvttss2si\t{%1, %0|%0, %1}"
21393   [(set_attr "type" "sseicvt")
21394    (set_attr "mode" "SF")
21395    (set_attr "athlon_decode" "double,vector")])
21396
21397 (define_insn "cvttss2siq"
21398   [(set (match_operand:DI 0 "register_operand" "=r,r")
21399         (vec_select:DI
21400          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21401                       UNSPEC_FIX)
21402          (parallel [(const_int 0)])))]
21403   "TARGET_SSE && TARGET_64BIT"
21404   "cvttss2siq\t{%1, %0|%0, %1}"
21405   [(set_attr "type" "sseicvt")
21406    (set_attr "mode" "SF")
21407    (set_attr "athlon_decode" "double,vector")])
21408
21409
21410 ;; MMX insns
21411
21412 ;; MMX arithmetic
21413
21414 (define_insn "addv8qi3"
21415   [(set (match_operand:V8QI 0 "register_operand" "=y")
21416         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21417                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21418   "TARGET_MMX"
21419   "paddb\t{%2, %0|%0, %2}"
21420   [(set_attr "type" "mmxadd")
21421    (set_attr "mode" "DI")])
21422
21423 (define_insn "addv4hi3"
21424   [(set (match_operand:V4HI 0 "register_operand" "=y")
21425         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21426                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21427   "TARGET_MMX"
21428   "paddw\t{%2, %0|%0, %2}"
21429   [(set_attr "type" "mmxadd")
21430    (set_attr "mode" "DI")])
21431
21432 (define_insn "addv2si3"
21433   [(set (match_operand:V2SI 0 "register_operand" "=y")
21434         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21435                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21436   "TARGET_MMX"
21437   "paddd\t{%2, %0|%0, %2}"
21438   [(set_attr "type" "mmxadd")
21439    (set_attr "mode" "DI")])
21440
21441 (define_insn "mmx_adddi3"
21442   [(set (match_operand:DI 0 "register_operand" "=y")
21443         (unspec:DI
21444          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21445                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21446          UNSPEC_NOP))]
21447   "TARGET_MMX"
21448   "paddq\t{%2, %0|%0, %2}"
21449   [(set_attr "type" "mmxadd")
21450    (set_attr "mode" "DI")])
21451
21452 (define_insn "ssaddv8qi3"
21453   [(set (match_operand:V8QI 0 "register_operand" "=y")
21454         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21455                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21456   "TARGET_MMX"
21457   "paddsb\t{%2, %0|%0, %2}"
21458   [(set_attr "type" "mmxadd")
21459    (set_attr "mode" "DI")])
21460
21461 (define_insn "ssaddv4hi3"
21462   [(set (match_operand:V4HI 0 "register_operand" "=y")
21463         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21464                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21465   "TARGET_MMX"
21466   "paddsw\t{%2, %0|%0, %2}"
21467   [(set_attr "type" "mmxadd")
21468    (set_attr "mode" "DI")])
21469
21470 (define_insn "usaddv8qi3"
21471   [(set (match_operand:V8QI 0 "register_operand" "=y")
21472         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21473                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21474   "TARGET_MMX"
21475   "paddusb\t{%2, %0|%0, %2}"
21476   [(set_attr "type" "mmxadd")
21477    (set_attr "mode" "DI")])
21478
21479 (define_insn "usaddv4hi3"
21480   [(set (match_operand:V4HI 0 "register_operand" "=y")
21481         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21482                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21483   "TARGET_MMX"
21484   "paddusw\t{%2, %0|%0, %2}"
21485   [(set_attr "type" "mmxadd")
21486    (set_attr "mode" "DI")])
21487
21488 (define_insn "subv8qi3"
21489   [(set (match_operand:V8QI 0 "register_operand" "=y")
21490         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21491                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21492   "TARGET_MMX"
21493   "psubb\t{%2, %0|%0, %2}"
21494   [(set_attr "type" "mmxadd")
21495    (set_attr "mode" "DI")])
21496
21497 (define_insn "subv4hi3"
21498   [(set (match_operand:V4HI 0 "register_operand" "=y")
21499         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21500                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21501   "TARGET_MMX"
21502   "psubw\t{%2, %0|%0, %2}"
21503   [(set_attr "type" "mmxadd")
21504    (set_attr "mode" "DI")])
21505
21506 (define_insn "subv2si3"
21507   [(set (match_operand:V2SI 0 "register_operand" "=y")
21508         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21509                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21510   "TARGET_MMX"
21511   "psubd\t{%2, %0|%0, %2}"
21512   [(set_attr "type" "mmxadd")
21513    (set_attr "mode" "DI")])
21514
21515 (define_insn "mmx_subdi3"
21516   [(set (match_operand:DI 0 "register_operand" "=y")
21517         (unspec:DI
21518          [(minus:DI (match_operand:DI 1 "register_operand" "0")
21519                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21520          UNSPEC_NOP))]
21521   "TARGET_MMX"
21522   "psubq\t{%2, %0|%0, %2}"
21523   [(set_attr "type" "mmxadd")
21524    (set_attr "mode" "DI")])
21525
21526 (define_insn "sssubv8qi3"
21527   [(set (match_operand:V8QI 0 "register_operand" "=y")
21528         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21529                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21530   "TARGET_MMX"
21531   "psubsb\t{%2, %0|%0, %2}"
21532   [(set_attr "type" "mmxadd")
21533    (set_attr "mode" "DI")])
21534
21535 (define_insn "sssubv4hi3"
21536   [(set (match_operand:V4HI 0 "register_operand" "=y")
21537         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21538                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21539   "TARGET_MMX"
21540   "psubsw\t{%2, %0|%0, %2}"
21541   [(set_attr "type" "mmxadd")
21542    (set_attr "mode" "DI")])
21543
21544 (define_insn "ussubv8qi3"
21545   [(set (match_operand:V8QI 0 "register_operand" "=y")
21546         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21547                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21548   "TARGET_MMX"
21549   "psubusb\t{%2, %0|%0, %2}"
21550   [(set_attr "type" "mmxadd")
21551    (set_attr "mode" "DI")])
21552
21553 (define_insn "ussubv4hi3"
21554   [(set (match_operand:V4HI 0 "register_operand" "=y")
21555         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21556                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21557   "TARGET_MMX"
21558   "psubusw\t{%2, %0|%0, %2}"
21559   [(set_attr "type" "mmxadd")
21560    (set_attr "mode" "DI")])
21561
21562 (define_insn "mulv4hi3"
21563   [(set (match_operand:V4HI 0 "register_operand" "=y")
21564         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21565                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21566   "TARGET_MMX"
21567   "pmullw\t{%2, %0|%0, %2}"
21568   [(set_attr "type" "mmxmul")
21569    (set_attr "mode" "DI")])
21570
21571 (define_insn "smulv4hi3_highpart"
21572   [(set (match_operand:V4HI 0 "register_operand" "=y")
21573         (truncate:V4HI
21574          (lshiftrt:V4SI
21575           (mult:V4SI (sign_extend:V4SI
21576                       (match_operand:V4HI 1 "register_operand" "0"))
21577                      (sign_extend:V4SI
21578                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21579           (const_int 16))))]
21580   "TARGET_MMX"
21581   "pmulhw\t{%2, %0|%0, %2}"
21582   [(set_attr "type" "mmxmul")
21583    (set_attr "mode" "DI")])
21584
21585 (define_insn "umulv4hi3_highpart"
21586   [(set (match_operand:V4HI 0 "register_operand" "=y")
21587         (truncate:V4HI
21588          (lshiftrt:V4SI
21589           (mult:V4SI (zero_extend:V4SI
21590                       (match_operand:V4HI 1 "register_operand" "0"))
21591                      (zero_extend:V4SI
21592                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21593           (const_int 16))))]
21594   "TARGET_SSE || TARGET_3DNOW_A"
21595   "pmulhuw\t{%2, %0|%0, %2}"
21596   [(set_attr "type" "mmxmul")
21597    (set_attr "mode" "DI")])
21598
21599 (define_insn "mmx_pmaddwd"
21600   [(set (match_operand:V2SI 0 "register_operand" "=y")
21601         (plus:V2SI
21602          (mult:V2SI
21603           (sign_extend:V2SI
21604            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21605                             (parallel [(const_int 0) (const_int 2)])))
21606           (sign_extend:V2SI
21607            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21608                             (parallel [(const_int 0) (const_int 2)]))))
21609          (mult:V2SI
21610           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21611                                              (parallel [(const_int 1)
21612                                                         (const_int 3)])))
21613           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21614                                              (parallel [(const_int 1)
21615                                                         (const_int 3)]))))))]
21616   "TARGET_MMX"
21617   "pmaddwd\t{%2, %0|%0, %2}"
21618   [(set_attr "type" "mmxmul")
21619    (set_attr "mode" "DI")])
21620
21621
21622 ;; MMX logical operations
21623 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21624 ;; normal code that also wants to use the FPU from getting broken.
21625 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21626 (define_insn "mmx_iordi3"
21627   [(set (match_operand:DI 0 "register_operand" "=y")
21628         (unspec:DI
21629          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21630                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21631          UNSPEC_NOP))]
21632   "TARGET_MMX"
21633   "por\t{%2, %0|%0, %2}"
21634   [(set_attr "type" "mmxadd")
21635    (set_attr "mode" "DI")])
21636
21637 (define_insn "mmx_xordi3"
21638   [(set (match_operand:DI 0 "register_operand" "=y")
21639         (unspec:DI
21640          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21641                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21642          UNSPEC_NOP))]
21643   "TARGET_MMX"
21644   "pxor\t{%2, %0|%0, %2}"
21645   [(set_attr "type" "mmxadd")
21646    (set_attr "mode" "DI")
21647    (set_attr "memory" "none")])
21648
21649 ;; Same as pxor, but don't show input operands so that we don't think
21650 ;; they are live.
21651 (define_insn "mmx_clrdi"
21652   [(set (match_operand:DI 0 "register_operand" "=y")
21653         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21654   "TARGET_MMX"
21655   "pxor\t{%0, %0|%0, %0}"
21656   [(set_attr "type" "mmxadd")
21657    (set_attr "mode" "DI")
21658    (set_attr "memory" "none")])
21659
21660 (define_insn "mmx_anddi3"
21661   [(set (match_operand:DI 0 "register_operand" "=y")
21662         (unspec:DI
21663          [(and:DI (match_operand:DI 1 "register_operand" "%0")
21664                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21665          UNSPEC_NOP))]
21666   "TARGET_MMX"
21667   "pand\t{%2, %0|%0, %2}"
21668   [(set_attr "type" "mmxadd")
21669    (set_attr "mode" "DI")])
21670
21671 (define_insn "mmx_nanddi3"
21672   [(set (match_operand:DI 0 "register_operand" "=y")
21673         (unspec:DI
21674          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21675                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21676          UNSPEC_NOP))]
21677   "TARGET_MMX"
21678   "pandn\t{%2, %0|%0, %2}"
21679   [(set_attr "type" "mmxadd")
21680    (set_attr "mode" "DI")])
21681
21682
21683 ;; MMX unsigned averages/sum of absolute differences
21684
21685 (define_insn "mmx_uavgv8qi3"
21686   [(set (match_operand:V8QI 0 "register_operand" "=y")
21687         (ashiftrt:V8QI
21688          (plus:V8QI (plus:V8QI
21689                      (match_operand:V8QI 1 "register_operand" "0")
21690                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21691                     (const_vector:V8QI [(const_int 1)
21692                                         (const_int 1)
21693                                         (const_int 1)
21694                                         (const_int 1)
21695                                         (const_int 1)
21696                                         (const_int 1)
21697                                         (const_int 1)
21698                                         (const_int 1)]))
21699          (const_int 1)))]
21700   "TARGET_SSE || TARGET_3DNOW_A"
21701   "pavgb\t{%2, %0|%0, %2}"
21702   [(set_attr "type" "mmxshft")
21703    (set_attr "mode" "DI")])
21704
21705 (define_insn "mmx_uavgv4hi3"
21706   [(set (match_operand:V4HI 0 "register_operand" "=y")
21707         (ashiftrt:V4HI
21708          (plus:V4HI (plus:V4HI
21709                      (match_operand:V4HI 1 "register_operand" "0")
21710                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21711                     (const_vector:V4HI [(const_int 1)
21712                                         (const_int 1)
21713                                         (const_int 1)
21714                                         (const_int 1)]))
21715          (const_int 1)))]
21716   "TARGET_SSE || TARGET_3DNOW_A"
21717   "pavgw\t{%2, %0|%0, %2}"
21718   [(set_attr "type" "mmxshft")
21719    (set_attr "mode" "DI")])
21720
21721 (define_insn "mmx_psadbw"
21722   [(set (match_operand:DI 0 "register_operand" "=y")
21723         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21724                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21725                    UNSPEC_PSADBW))]
21726   "TARGET_SSE || TARGET_3DNOW_A"
21727   "psadbw\t{%2, %0|%0, %2}"
21728   [(set_attr "type" "mmxshft")
21729    (set_attr "mode" "DI")])
21730
21731
21732 ;; MMX insert/extract/shuffle
21733
21734 (define_insn "mmx_pinsrw"
21735   [(set (match_operand:V4HI 0 "register_operand" "=y")
21736         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21737                         (vec_duplicate:V4HI
21738                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21739                         (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21740   "TARGET_SSE || TARGET_3DNOW_A"
21741   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21742   [(set_attr "type" "mmxcvt")
21743    (set_attr "mode" "DI")])
21744
21745 (define_insn "mmx_pextrw"
21746   [(set (match_operand:SI 0 "register_operand" "=r")
21747         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21748                                        (parallel
21749                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21750   "TARGET_SSE || TARGET_3DNOW_A"
21751   "pextrw\t{%2, %1, %0|%0, %1, %2}"
21752   [(set_attr "type" "mmxcvt")
21753    (set_attr "mode" "DI")])
21754
21755 (define_insn "mmx_pshufw"
21756   [(set (match_operand:V4HI 0 "register_operand" "=y")
21757         (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21758                       (match_operand:SI 2 "immediate_operand" "i")]
21759                      UNSPEC_SHUFFLE))]
21760   "TARGET_SSE || TARGET_3DNOW_A"
21761   "pshufw\t{%2, %1, %0|%0, %1, %2}"
21762   [(set_attr "type" "mmxcvt")
21763    (set_attr "mode" "DI")])
21764
21765
21766 ;; MMX mask-generating comparisons
21767
21768 (define_insn "eqv8qi3"
21769   [(set (match_operand:V8QI 0 "register_operand" "=y")
21770         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21771                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21772   "TARGET_MMX"
21773   "pcmpeqb\t{%2, %0|%0, %2}"
21774   [(set_attr "type" "mmxcmp")
21775    (set_attr "mode" "DI")])
21776
21777 (define_insn "eqv4hi3"
21778   [(set (match_operand:V4HI 0 "register_operand" "=y")
21779         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21780                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21781   "TARGET_MMX"
21782   "pcmpeqw\t{%2, %0|%0, %2}"
21783   [(set_attr "type" "mmxcmp")
21784    (set_attr "mode" "DI")])
21785
21786 (define_insn "eqv2si3"
21787   [(set (match_operand:V2SI 0 "register_operand" "=y")
21788         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21789                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21790   "TARGET_MMX"
21791   "pcmpeqd\t{%2, %0|%0, %2}"
21792   [(set_attr "type" "mmxcmp")
21793    (set_attr "mode" "DI")])
21794
21795 (define_insn "gtv8qi3"
21796   [(set (match_operand:V8QI 0 "register_operand" "=y")
21797         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21798                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21799   "TARGET_MMX"
21800   "pcmpgtb\t{%2, %0|%0, %2}"
21801   [(set_attr "type" "mmxcmp")
21802    (set_attr "mode" "DI")])
21803
21804 (define_insn "gtv4hi3"
21805   [(set (match_operand:V4HI 0 "register_operand" "=y")
21806         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21807                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21808   "TARGET_MMX"
21809   "pcmpgtw\t{%2, %0|%0, %2}"
21810   [(set_attr "type" "mmxcmp")
21811    (set_attr "mode" "DI")])
21812
21813 (define_insn "gtv2si3"
21814   [(set (match_operand:V2SI 0 "register_operand" "=y")
21815         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21816                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21817   "TARGET_MMX"
21818   "pcmpgtd\t{%2, %0|%0, %2}"
21819   [(set_attr "type" "mmxcmp")
21820    (set_attr "mode" "DI")])
21821
21822
21823 ;; MMX max/min insns
21824
21825 (define_insn "umaxv8qi3"
21826   [(set (match_operand:V8QI 0 "register_operand" "=y")
21827         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21828                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21829   "TARGET_SSE || TARGET_3DNOW_A"
21830   "pmaxub\t{%2, %0|%0, %2}"
21831   [(set_attr "type" "mmxadd")
21832    (set_attr "mode" "DI")])
21833
21834 (define_insn "smaxv4hi3"
21835   [(set (match_operand:V4HI 0 "register_operand" "=y")
21836         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21837                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21838   "TARGET_SSE || TARGET_3DNOW_A"
21839   "pmaxsw\t{%2, %0|%0, %2}"
21840   [(set_attr "type" "mmxadd")
21841    (set_attr "mode" "DI")])
21842
21843 (define_insn "uminv8qi3"
21844   [(set (match_operand:V8QI 0 "register_operand" "=y")
21845         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21846                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21847   "TARGET_SSE || TARGET_3DNOW_A"
21848   "pminub\t{%2, %0|%0, %2}"
21849   [(set_attr "type" "mmxadd")
21850    (set_attr "mode" "DI")])
21851
21852 (define_insn "sminv4hi3"
21853   [(set (match_operand:V4HI 0 "register_operand" "=y")
21854         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21855                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21856   "TARGET_SSE || TARGET_3DNOW_A"
21857   "pminsw\t{%2, %0|%0, %2}"
21858   [(set_attr "type" "mmxadd")
21859    (set_attr "mode" "DI")])
21860
21861
21862 ;; MMX shifts
21863
21864 (define_insn "ashrv4hi3"
21865   [(set (match_operand:V4HI 0 "register_operand" "=y")
21866         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21867                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21868   "TARGET_MMX"
21869   "psraw\t{%2, %0|%0, %2}"
21870   [(set_attr "type" "mmxshft")
21871    (set_attr "mode" "DI")])
21872
21873 (define_insn "ashrv2si3"
21874   [(set (match_operand:V2SI 0 "register_operand" "=y")
21875         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21876                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21877   "TARGET_MMX"
21878   "psrad\t{%2, %0|%0, %2}"
21879   [(set_attr "type" "mmxshft")
21880    (set_attr "mode" "DI")])
21881
21882 (define_insn "lshrv4hi3"
21883   [(set (match_operand:V4HI 0 "register_operand" "=y")
21884         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21885                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21886   "TARGET_MMX"
21887   "psrlw\t{%2, %0|%0, %2}"
21888   [(set_attr "type" "mmxshft")
21889    (set_attr "mode" "DI")])
21890
21891 (define_insn "lshrv2si3"
21892   [(set (match_operand:V2SI 0 "register_operand" "=y")
21893         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21894                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21895   "TARGET_MMX"
21896   "psrld\t{%2, %0|%0, %2}"
21897   [(set_attr "type" "mmxshft")
21898    (set_attr "mode" "DI")])
21899
21900 ;; See logical MMX insns.
21901 (define_insn "mmx_lshrdi3"
21902   [(set (match_operand:DI 0 "register_operand" "=y")
21903         (unspec:DI
21904           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21905                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
21906           UNSPEC_NOP))]
21907   "TARGET_MMX"
21908   "psrlq\t{%2, %0|%0, %2}"
21909   [(set_attr "type" "mmxshft")
21910    (set_attr "mode" "DI")])
21911
21912 (define_insn "ashlv4hi3"
21913   [(set (match_operand:V4HI 0 "register_operand" "=y")
21914         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21915                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21916   "TARGET_MMX"
21917   "psllw\t{%2, %0|%0, %2}"
21918   [(set_attr "type" "mmxshft")
21919    (set_attr "mode" "DI")])
21920
21921 (define_insn "ashlv2si3"
21922   [(set (match_operand:V2SI 0 "register_operand" "=y")
21923         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21924                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21925   "TARGET_MMX"
21926   "pslld\t{%2, %0|%0, %2}"
21927   [(set_attr "type" "mmxshft")
21928    (set_attr "mode" "DI")])
21929
21930 ;; See logical MMX insns.
21931 (define_insn "mmx_ashldi3"
21932   [(set (match_operand:DI 0 "register_operand" "=y")
21933         (unspec:DI
21934          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21935                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
21936          UNSPEC_NOP))]
21937   "TARGET_MMX"
21938   "psllq\t{%2, %0|%0, %2}"
21939   [(set_attr "type" "mmxshft")
21940    (set_attr "mode" "DI")])
21941
21942
21943 ;; MMX pack/unpack insns.
21944
21945 (define_insn "mmx_packsswb"
21946   [(set (match_operand:V8QI 0 "register_operand" "=y")
21947         (vec_concat:V8QI
21948          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21949          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21950   "TARGET_MMX"
21951   "packsswb\t{%2, %0|%0, %2}"
21952   [(set_attr "type" "mmxshft")
21953    (set_attr "mode" "DI")])
21954
21955 (define_insn "mmx_packssdw"
21956   [(set (match_operand:V4HI 0 "register_operand" "=y")
21957         (vec_concat:V4HI
21958          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21959          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21960   "TARGET_MMX"
21961   "packssdw\t{%2, %0|%0, %2}"
21962   [(set_attr "type" "mmxshft")
21963    (set_attr "mode" "DI")])
21964
21965 (define_insn "mmx_packuswb"
21966   [(set (match_operand:V8QI 0 "register_operand" "=y")
21967         (vec_concat:V8QI
21968          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21969          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21970   "TARGET_MMX"
21971   "packuswb\t{%2, %0|%0, %2}"
21972   [(set_attr "type" "mmxshft")
21973    (set_attr "mode" "DI")])
21974
21975 (define_insn "mmx_punpckhbw"
21976   [(set (match_operand:V8QI 0 "register_operand" "=y")
21977         (vec_merge:V8QI
21978          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21979                           (parallel [(const_int 4)
21980                                      (const_int 0)
21981                                      (const_int 5)
21982                                      (const_int 1)
21983                                      (const_int 6)
21984                                      (const_int 2)
21985                                      (const_int 7)
21986                                      (const_int 3)]))
21987          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21988                           (parallel [(const_int 0)
21989                                      (const_int 4)
21990                                      (const_int 1)
21991                                      (const_int 5)
21992                                      (const_int 2)
21993                                      (const_int 6)
21994                                      (const_int 3)
21995                                      (const_int 7)]))
21996          (const_int 85)))]
21997   "TARGET_MMX"
21998   "punpckhbw\t{%2, %0|%0, %2}"
21999   [(set_attr "type" "mmxcvt")
22000    (set_attr "mode" "DI")])
22001
22002 (define_insn "mmx_punpckhwd"
22003   [(set (match_operand:V4HI 0 "register_operand" "=y")
22004         (vec_merge:V4HI
22005          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
22006                           (parallel [(const_int 0)
22007                                      (const_int 2)
22008                                      (const_int 1)
22009                                      (const_int 3)]))
22010          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
22011                           (parallel [(const_int 2)
22012                                      (const_int 0)
22013                                      (const_int 3)
22014                                      (const_int 1)]))
22015          (const_int 5)))]
22016   "TARGET_MMX"
22017   "punpckhwd\t{%2, %0|%0, %2}"
22018   [(set_attr "type" "mmxcvt")
22019    (set_attr "mode" "DI")])
22020
22021 (define_insn "mmx_punpckhdq"
22022   [(set (match_operand:V2SI 0 "register_operand" "=y")
22023         (vec_merge:V2SI
22024          (match_operand:V2SI 1 "register_operand" "0")
22025          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
22026                           (parallel [(const_int 1)
22027                                      (const_int 0)]))
22028          (const_int 1)))]
22029   "TARGET_MMX"
22030   "punpckhdq\t{%2, %0|%0, %2}"
22031   [(set_attr "type" "mmxcvt")
22032    (set_attr "mode" "DI")])
22033
22034 (define_insn "mmx_punpcklbw"
22035   [(set (match_operand:V8QI 0 "register_operand" "=y")
22036         (vec_merge:V8QI
22037          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
22038                           (parallel [(const_int 0)
22039                                      (const_int 4)
22040                                      (const_int 1)
22041                                      (const_int 5)
22042                                      (const_int 2)
22043                                      (const_int 6)
22044                                      (const_int 3)
22045                                      (const_int 7)]))
22046          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
22047                           (parallel [(const_int 4)
22048                                      (const_int 0)
22049                                      (const_int 5)
22050                                      (const_int 1)
22051                                      (const_int 6)
22052                                      (const_int 2)
22053                                      (const_int 7)
22054                                      (const_int 3)]))
22055          (const_int 85)))]
22056   "TARGET_MMX"
22057   "punpcklbw\t{%2, %0|%0, %2}"
22058   [(set_attr "type" "mmxcvt")
22059    (set_attr "mode" "DI")])
22060
22061 (define_insn "mmx_punpcklwd"
22062   [(set (match_operand:V4HI 0 "register_operand" "=y")
22063         (vec_merge:V4HI
22064          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
22065                           (parallel [(const_int 2)
22066                                      (const_int 0)
22067                                      (const_int 3)
22068                                      (const_int 1)]))
22069          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
22070                           (parallel [(const_int 0)
22071                                      (const_int 2)
22072                                      (const_int 1)
22073                                      (const_int 3)]))
22074          (const_int 5)))]
22075   "TARGET_MMX"
22076   "punpcklwd\t{%2, %0|%0, %2}"
22077   [(set_attr "type" "mmxcvt")
22078    (set_attr "mode" "DI")])
22079
22080 (define_insn "mmx_punpckldq"
22081   [(set (match_operand:V2SI 0 "register_operand" "=y")
22082         (vec_merge:V2SI
22083          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
22084                            (parallel [(const_int 1)
22085                                       (const_int 0)]))
22086          (match_operand:V2SI 2 "register_operand" "y")
22087          (const_int 1)))]
22088   "TARGET_MMX"
22089   "punpckldq\t{%2, %0|%0, %2}"
22090   [(set_attr "type" "mmxcvt")
22091    (set_attr "mode" "DI")])
22092
22093
22094 ;; Miscellaneous stuff
22095
22096 (define_insn "emms"
22097   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
22098    (clobber (reg:XF 8))
22099    (clobber (reg:XF 9))
22100    (clobber (reg:XF 10))
22101    (clobber (reg:XF 11))
22102    (clobber (reg:XF 12))
22103    (clobber (reg:XF 13))
22104    (clobber (reg:XF 14))
22105    (clobber (reg:XF 15))
22106    (clobber (reg:DI 29))
22107    (clobber (reg:DI 30))
22108    (clobber (reg:DI 31))
22109    (clobber (reg:DI 32))
22110    (clobber (reg:DI 33))
22111    (clobber (reg:DI 34))
22112    (clobber (reg:DI 35))
22113    (clobber (reg:DI 36))]
22114   "TARGET_MMX"
22115   "emms"
22116   [(set_attr "type" "mmx")
22117    (set_attr "memory" "unknown")])
22118
22119 (define_insn "ldmxcsr"
22120   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
22121                     UNSPECV_LDMXCSR)]
22122   "TARGET_SSE"
22123   "ldmxcsr\t%0"
22124   [(set_attr "type" "sse")
22125    (set_attr "memory" "load")])
22126
22127 (define_insn "stmxcsr"
22128   [(set (match_operand:SI 0 "memory_operand" "=m")
22129         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
22130   "TARGET_SSE"
22131   "stmxcsr\t%0"
22132   [(set_attr "type" "sse")
22133    (set_attr "memory" "store")])
22134
22135 (define_expand "sfence"
22136   [(set (match_dup 0)
22137         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22138   "TARGET_SSE || TARGET_3DNOW_A"
22139 {
22140   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22141   MEM_VOLATILE_P (operands[0]) = 1;
22142 })
22143
22144 (define_insn "*sfence_insn"
22145   [(set (match_operand:BLK 0 "" "")
22146         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22147   "TARGET_SSE || TARGET_3DNOW_A"
22148   "sfence"
22149   [(set_attr "type" "sse")
22150    (set_attr "memory" "unknown")])
22151
22152 (define_expand "sse_prologue_save"
22153   [(parallel [(set (match_operand:BLK 0 "" "")
22154                    (unspec:BLK [(reg:DI 21)
22155                                 (reg:DI 22)
22156                                 (reg:DI 23)
22157                                 (reg:DI 24)
22158                                 (reg:DI 25)
22159                                 (reg:DI 26)
22160                                 (reg:DI 27)
22161                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22162               (use (match_operand:DI 1 "register_operand" ""))
22163               (use (match_operand:DI 2 "immediate_operand" ""))
22164               (use (label_ref:DI (match_operand 3 "" "")))])]
22165   "TARGET_64BIT"
22166   "")
22167
22168 (define_insn "*sse_prologue_save_insn"
22169   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22170                           (match_operand:DI 4 "const_int_operand" "n")))
22171         (unspec:BLK [(reg:DI 21)
22172                      (reg:DI 22)
22173                      (reg:DI 23)
22174                      (reg:DI 24)
22175                      (reg:DI 25)
22176                      (reg:DI 26)
22177                      (reg:DI 27)
22178                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22179    (use (match_operand:DI 1 "register_operand" "r"))
22180    (use (match_operand:DI 2 "const_int_operand" "i"))
22181    (use (label_ref:DI (match_operand 3 "" "X")))]
22182   "TARGET_64BIT
22183    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
22184    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22185   "*
22186 {
22187   int i;
22188   operands[0] = gen_rtx_MEM (Pmode,
22189                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22190   output_asm_insn (\"jmp\\t%A1\", operands);
22191   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22192     {
22193       operands[4] = adjust_address (operands[0], DImode, i*16);
22194       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22195       PUT_MODE (operands[4], TImode);
22196       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22197         output_asm_insn (\"rex\", operands);
22198       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
22199     }
22200   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
22201                              CODE_LABEL_NUMBER (operands[3]));
22202   RET;
22203 }
22204   "
22205   [(set_attr "type" "other")
22206    (set_attr "length_immediate" "0")
22207    (set_attr "length_address" "0")
22208    (set_attr "length" "135")
22209    (set_attr "memory" "store")
22210    (set_attr "modrm" "0")
22211    (set_attr "mode" "DI")])
22212
22213 ;; 3Dnow! instructions
22214
22215 (define_insn "addv2sf3"
22216   [(set (match_operand:V2SF 0 "register_operand" "=y")
22217         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22218                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22219   "TARGET_3DNOW"
22220   "pfadd\\t{%2, %0|%0, %2}"
22221   [(set_attr "type" "mmxadd")
22222    (set_attr "mode" "V2SF")])
22223
22224 (define_insn "subv2sf3"
22225   [(set (match_operand:V2SF 0 "register_operand" "=y")
22226         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22227                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22228   "TARGET_3DNOW"
22229   "pfsub\\t{%2, %0|%0, %2}"
22230   [(set_attr "type" "mmxadd")
22231    (set_attr "mode" "V2SF")])
22232
22233 (define_insn "subrv2sf3"
22234   [(set (match_operand:V2SF 0 "register_operand" "=y")
22235         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
22236                     (match_operand:V2SF 1 "register_operand" "0")))]
22237   "TARGET_3DNOW"
22238   "pfsubr\\t{%2, %0|%0, %2}"
22239   [(set_attr "type" "mmxadd")
22240    (set_attr "mode" "V2SF")])
22241
22242 (define_insn "gtv2sf3"
22243   [(set (match_operand:V2SI 0 "register_operand" "=y")
22244         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
22245                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22246   "TARGET_3DNOW"
22247   "pfcmpgt\\t{%2, %0|%0, %2}"
22248   [(set_attr "type" "mmxcmp")
22249    (set_attr "mode" "V2SF")])
22250
22251 (define_insn "gev2sf3"
22252   [(set (match_operand:V2SI 0 "register_operand" "=y")
22253         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
22254                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22255   "TARGET_3DNOW"
22256   "pfcmpge\\t{%2, %0|%0, %2}"
22257   [(set_attr "type" "mmxcmp")
22258    (set_attr "mode" "V2SF")])
22259
22260 (define_insn "eqv2sf3"
22261   [(set (match_operand:V2SI 0 "register_operand" "=y")
22262         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
22263                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22264   "TARGET_3DNOW"
22265   "pfcmpeq\\t{%2, %0|%0, %2}"
22266   [(set_attr "type" "mmxcmp")
22267    (set_attr "mode" "V2SF")])
22268
22269 (define_insn "pfmaxv2sf3"
22270   [(set (match_operand:V2SF 0 "register_operand" "=y")
22271         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
22272                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22273   "TARGET_3DNOW"
22274   "pfmax\\t{%2, %0|%0, %2}"
22275   [(set_attr "type" "mmxadd")
22276    (set_attr "mode" "V2SF")])
22277
22278 (define_insn "pfminv2sf3"
22279   [(set (match_operand:V2SF 0 "register_operand" "=y")
22280         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
22281                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22282   "TARGET_3DNOW"
22283   "pfmin\\t{%2, %0|%0, %2}"
22284   [(set_attr "type" "mmxadd")
22285    (set_attr "mode" "V2SF")])
22286
22287 (define_insn "mulv2sf3"
22288   [(set (match_operand:V2SF 0 "register_operand" "=y")
22289         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
22290                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22291   "TARGET_3DNOW"
22292   "pfmul\\t{%2, %0|%0, %2}"
22293   [(set_attr "type" "mmxmul")
22294    (set_attr "mode" "V2SF")])
22295
22296 (define_insn "femms"
22297   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
22298    (clobber (reg:XF 8))
22299    (clobber (reg:XF 9))
22300    (clobber (reg:XF 10))
22301    (clobber (reg:XF 11))
22302    (clobber (reg:XF 12))
22303    (clobber (reg:XF 13))
22304    (clobber (reg:XF 14))
22305    (clobber (reg:XF 15))
22306    (clobber (reg:DI 29))
22307    (clobber (reg:DI 30))
22308    (clobber (reg:DI 31))
22309    (clobber (reg:DI 32))
22310    (clobber (reg:DI 33))
22311    (clobber (reg:DI 34))
22312    (clobber (reg:DI 35))
22313    (clobber (reg:DI 36))]
22314   "TARGET_3DNOW"
22315   "femms"
22316   [(set_attr "type" "mmx")
22317    (set_attr "memory" "none")]) 
22318
22319 (define_insn "pf2id"
22320   [(set (match_operand:V2SI 0 "register_operand" "=y")
22321         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
22322   "TARGET_3DNOW"
22323   "pf2id\\t{%1, %0|%0, %1}"
22324   [(set_attr "type" "mmxcvt")
22325    (set_attr "mode" "V2SF")])
22326
22327 (define_insn "pf2iw"
22328   [(set (match_operand:V2SI 0 "register_operand" "=y")
22329         (sign_extend:V2SI
22330            (ss_truncate:V2HI
22331               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22332   "TARGET_3DNOW_A"
22333   "pf2iw\\t{%1, %0|%0, %1}"
22334   [(set_attr "type" "mmxcvt")
22335    (set_attr "mode" "V2SF")])
22336
22337 (define_insn "pfacc"
22338   [(set (match_operand:V2SF 0 "register_operand" "=y")
22339         (vec_concat:V2SF
22340            (plus:SF
22341               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22342                              (parallel [(const_int  0)]))
22343               (vec_select:SF (match_dup 1)
22344                              (parallel [(const_int 1)])))
22345            (plus:SF
22346               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22347                              (parallel [(const_int  0)]))
22348               (vec_select:SF (match_dup 2)
22349                              (parallel [(const_int 1)])))))]
22350   "TARGET_3DNOW"
22351   "pfacc\\t{%2, %0|%0, %2}"
22352   [(set_attr "type" "mmxadd")
22353    (set_attr "mode" "V2SF")])
22354
22355 (define_insn "pfnacc"
22356   [(set (match_operand:V2SF 0 "register_operand" "=y")
22357         (vec_concat:V2SF
22358            (minus:SF
22359               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22360                              (parallel [(const_int 0)]))
22361               (vec_select:SF (match_dup 1)
22362                              (parallel [(const_int 1)])))
22363            (minus:SF
22364               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22365                              (parallel [(const_int  0)]))
22366               (vec_select:SF (match_dup 2)
22367                              (parallel [(const_int 1)])))))]
22368   "TARGET_3DNOW_A"
22369   "pfnacc\\t{%2, %0|%0, %2}"
22370   [(set_attr "type" "mmxadd")
22371    (set_attr "mode" "V2SF")])
22372
22373 (define_insn "pfpnacc"
22374   [(set (match_operand:V2SF 0 "register_operand" "=y")
22375         (vec_concat:V2SF
22376            (minus:SF
22377               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22378                              (parallel [(const_int 0)]))
22379               (vec_select:SF (match_dup 1)
22380                              (parallel [(const_int 1)])))
22381            (plus:SF
22382               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22383                              (parallel [(const_int 0)]))
22384               (vec_select:SF (match_dup 2)
22385                              (parallel [(const_int 1)])))))]
22386   "TARGET_3DNOW_A"
22387   "pfpnacc\\t{%2, %0|%0, %2}"
22388   [(set_attr "type" "mmxadd")
22389    (set_attr "mode" "V2SF")])
22390
22391 (define_insn "pi2fw"
22392   [(set (match_operand:V2SF 0 "register_operand" "=y")
22393         (float:V2SF
22394            (vec_concat:V2SI
22395               (sign_extend:SI
22396                  (truncate:HI
22397                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22398                                    (parallel [(const_int 0)]))))
22399               (sign_extend:SI
22400                  (truncate:HI
22401                     (vec_select:SI (match_dup 1)
22402                                    (parallel [(const_int  1)])))))))]
22403   "TARGET_3DNOW_A"
22404   "pi2fw\\t{%1, %0|%0, %1}"
22405   [(set_attr "type" "mmxcvt")
22406    (set_attr "mode" "V2SF")])
22407
22408 (define_insn "floatv2si2"
22409   [(set (match_operand:V2SF 0 "register_operand" "=y")
22410         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22411   "TARGET_3DNOW"
22412   "pi2fd\\t{%1, %0|%0, %1}"
22413   [(set_attr "type" "mmxcvt")
22414    (set_attr "mode" "V2SF")])
22415
22416 ;; This insn is identical to pavgb in operation, but the opcode is
22417 ;; different.  To avoid accidentally matching pavgb, use an unspec.
22418
22419 (define_insn "pavgusb"
22420  [(set (match_operand:V8QI 0 "register_operand" "=y")
22421        (unspec:V8QI
22422           [(match_operand:V8QI 1 "register_operand" "0")
22423            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22424           UNSPEC_PAVGUSB))]
22425   "TARGET_3DNOW"
22426   "pavgusb\\t{%2, %0|%0, %2}"
22427   [(set_attr "type" "mmxshft")
22428    (set_attr "mode" "TI")])
22429
22430 ;; 3DNow reciprocal and sqrt
22431  
22432 (define_insn "pfrcpv2sf2"
22433   [(set (match_operand:V2SF 0 "register_operand" "=y")
22434         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22435         UNSPEC_PFRCP))]
22436   "TARGET_3DNOW"
22437   "pfrcp\\t{%1, %0|%0, %1}"
22438   [(set_attr "type" "mmx")
22439    (set_attr "mode" "TI")])
22440
22441 (define_insn "pfrcpit1v2sf3"
22442   [(set (match_operand:V2SF 0 "register_operand" "=y")
22443         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22444                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22445                      UNSPEC_PFRCPIT1))]
22446   "TARGET_3DNOW"
22447   "pfrcpit1\\t{%2, %0|%0, %2}"
22448   [(set_attr "type" "mmx")
22449    (set_attr "mode" "TI")])
22450
22451 (define_insn "pfrcpit2v2sf3"
22452   [(set (match_operand:V2SF 0 "register_operand" "=y")
22453         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22454                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22455                      UNSPEC_PFRCPIT2))]
22456   "TARGET_3DNOW"
22457   "pfrcpit2\\t{%2, %0|%0, %2}"
22458   [(set_attr "type" "mmx")
22459    (set_attr "mode" "TI")])
22460
22461 (define_insn "pfrsqrtv2sf2"
22462   [(set (match_operand:V2SF 0 "register_operand" "=y")
22463         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22464                      UNSPEC_PFRSQRT))]
22465   "TARGET_3DNOW"
22466   "pfrsqrt\\t{%1, %0|%0, %1}"
22467   [(set_attr "type" "mmx")
22468    (set_attr "mode" "TI")])
22469                 
22470 (define_insn "pfrsqit1v2sf3"
22471   [(set (match_operand:V2SF 0 "register_operand" "=y")
22472         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22473                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22474                      UNSPEC_PFRSQIT1))]
22475   "TARGET_3DNOW"
22476   "pfrsqit1\\t{%2, %0|%0, %2}"
22477   [(set_attr "type" "mmx")
22478    (set_attr "mode" "TI")])
22479
22480 (define_insn "pmulhrwv4hi3"
22481   [(set (match_operand:V4HI 0 "register_operand" "=y")
22482         (truncate:V4HI
22483            (lshiftrt:V4SI
22484               (plus:V4SI
22485                  (mult:V4SI
22486                     (sign_extend:V4SI
22487                        (match_operand:V4HI 1 "register_operand" "0"))
22488                     (sign_extend:V4SI
22489                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22490                  (const_vector:V4SI [(const_int 32768)
22491                                      (const_int 32768)
22492                                      (const_int 32768)
22493                                      (const_int 32768)]))
22494               (const_int 16))))]
22495   "TARGET_3DNOW"
22496   "pmulhrw\\t{%2, %0|%0, %2}"
22497   [(set_attr "type" "mmxmul")
22498    (set_attr "mode" "TI")])
22499
22500 (define_insn "pswapdv2si2"
22501   [(set (match_operand:V2SI 0 "register_operand" "=y")
22502         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22503                          (parallel [(const_int 1) (const_int 0)])))]
22504   "TARGET_3DNOW_A"
22505   "pswapd\\t{%1, %0|%0, %1}"
22506   [(set_attr "type" "mmxcvt")
22507    (set_attr "mode" "TI")])
22508
22509 (define_insn "pswapdv2sf2"
22510   [(set (match_operand:V2SF 0 "register_operand" "=y")
22511         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22512                          (parallel [(const_int 1) (const_int 0)])))]
22513   "TARGET_3DNOW_A"
22514   "pswapd\\t{%1, %0|%0, %1}"
22515   [(set_attr "type" "mmxcvt")
22516    (set_attr "mode" "TI")])
22517
22518 (define_expand "prefetch"
22519   [(prefetch (match_operand 0 "address_operand" "")
22520              (match_operand:SI 1 "const_int_operand" "")
22521              (match_operand:SI 2 "const_int_operand" ""))]
22522   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22523 {
22524   int rw = INTVAL (operands[1]);
22525   int locality = INTVAL (operands[2]);
22526
22527   if (rw != 0 && rw != 1)
22528     abort ();
22529   if (locality < 0 || locality > 3)
22530     abort ();
22531   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22532     abort ();
22533
22534   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22535      suported by SSE counterpart or the SSE prefetch is not available
22536      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22537      of locality.  */
22538   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22539     operands[2] = GEN_INT (3);
22540   else
22541     operands[1] = const0_rtx;
22542 })
22543
22544 (define_insn "*prefetch_sse"
22545   [(prefetch (match_operand:SI 0 "address_operand" "p")
22546              (const_int 0)
22547              (match_operand:SI 1 "const_int_operand" ""))]
22548   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22549 {
22550   static const char * const patterns[4] = {
22551    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22552   };
22553
22554   int locality = INTVAL (operands[1]);
22555   if (locality < 0 || locality > 3)
22556     abort ();
22557
22558   return patterns[locality];  
22559 }
22560   [(set_attr "type" "sse")
22561    (set_attr "memory" "none")])
22562
22563 (define_insn "*prefetch_sse_rex"
22564   [(prefetch (match_operand:DI 0 "address_operand" "p")
22565              (const_int 0)
22566              (match_operand:SI 1 "const_int_operand" ""))]
22567   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22568 {
22569   static const char * const patterns[4] = {
22570    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22571   };
22572
22573   int locality = INTVAL (operands[1]);
22574   if (locality < 0 || locality > 3)
22575     abort ();
22576
22577   return patterns[locality];  
22578 }
22579   [(set_attr "type" "sse")
22580    (set_attr "memory" "none")])
22581
22582 (define_insn "*prefetch_3dnow"
22583   [(prefetch (match_operand:SI 0 "address_operand" "p")
22584              (match_operand:SI 1 "const_int_operand" "n")
22585              (const_int 3))]
22586   "TARGET_3DNOW && !TARGET_64BIT"
22587 {
22588   if (INTVAL (operands[1]) == 0)
22589     return "prefetch\t%a0";
22590   else
22591     return "prefetchw\t%a0";
22592 }
22593   [(set_attr "type" "mmx")
22594    (set_attr "memory" "none")])
22595
22596 (define_insn "*prefetch_3dnow_rex"
22597   [(prefetch (match_operand:DI 0 "address_operand" "p")
22598              (match_operand:SI 1 "const_int_operand" "n")
22599              (const_int 3))]
22600   "TARGET_3DNOW && TARGET_64BIT"
22601 {
22602   if (INTVAL (operands[1]) == 0)
22603     return "prefetch\t%a0";
22604   else
22605     return "prefetchw\t%a0";
22606 }
22607   [(set_attr "type" "mmx")
22608    (set_attr "memory" "none")])
22609
22610 ;; SSE2 support
22611
22612 (define_insn "addv2df3"
22613   [(set (match_operand:V2DF 0 "register_operand" "=x")
22614         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22615                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22616   "TARGET_SSE2"
22617   "addpd\t{%2, %0|%0, %2}"
22618   [(set_attr "type" "sseadd")
22619    (set_attr "mode" "V2DF")])
22620
22621 (define_insn "vmaddv2df3"
22622   [(set (match_operand:V2DF 0 "register_operand" "=x")
22623         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22624                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22625                         (match_dup 1)
22626                         (const_int 1)))]
22627   "TARGET_SSE2"
22628   "addsd\t{%2, %0|%0, %2}"
22629   [(set_attr "type" "sseadd")
22630    (set_attr "mode" "DF")])
22631
22632 (define_insn "subv2df3"
22633   [(set (match_operand:V2DF 0 "register_operand" "=x")
22634         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22635                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22636   "TARGET_SSE2"
22637   "subpd\t{%2, %0|%0, %2}"
22638   [(set_attr "type" "sseadd")
22639    (set_attr "mode" "V2DF")])
22640
22641 (define_insn "vmsubv2df3"
22642   [(set (match_operand:V2DF 0 "register_operand" "=x")
22643         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22644                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22645                         (match_dup 1)
22646                         (const_int 1)))]
22647   "TARGET_SSE2"
22648   "subsd\t{%2, %0|%0, %2}"
22649   [(set_attr "type" "sseadd")
22650    (set_attr "mode" "DF")])
22651
22652 (define_insn "mulv2df3"
22653   [(set (match_operand:V2DF 0 "register_operand" "=x")
22654         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22655                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22656   "TARGET_SSE2"
22657   "mulpd\t{%2, %0|%0, %2}"
22658   [(set_attr "type" "ssemul")
22659    (set_attr "mode" "V2DF")])
22660
22661 (define_insn "vmmulv2df3"
22662   [(set (match_operand:V2DF 0 "register_operand" "=x")
22663         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22664                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22665                         (match_dup 1)
22666                         (const_int 1)))]
22667   "TARGET_SSE2"
22668   "mulsd\t{%2, %0|%0, %2}"
22669   [(set_attr "type" "ssemul")
22670    (set_attr "mode" "DF")])
22671
22672 (define_insn "divv2df3"
22673   [(set (match_operand:V2DF 0 "register_operand" "=x")
22674         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22675                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22676   "TARGET_SSE2"
22677   "divpd\t{%2, %0|%0, %2}"
22678   [(set_attr "type" "ssediv")
22679    (set_attr "mode" "V2DF")])
22680
22681 (define_insn "vmdivv2df3"
22682   [(set (match_operand:V2DF 0 "register_operand" "=x")
22683         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22684                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22685                         (match_dup 1)
22686                         (const_int 1)))]
22687   "TARGET_SSE2"
22688   "divsd\t{%2, %0|%0, %2}"
22689   [(set_attr "type" "ssediv")
22690    (set_attr "mode" "DF")])
22691
22692 ;; SSE min/max
22693
22694 (define_insn "smaxv2df3"
22695   [(set (match_operand:V2DF 0 "register_operand" "=x")
22696         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22697                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22698   "TARGET_SSE2"
22699   "maxpd\t{%2, %0|%0, %2}"
22700   [(set_attr "type" "sseadd")
22701    (set_attr "mode" "V2DF")])
22702
22703 (define_insn "vmsmaxv2df3"
22704   [(set (match_operand:V2DF 0 "register_operand" "=x")
22705         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22706                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22707                         (match_dup 1)
22708                         (const_int 1)))]
22709   "TARGET_SSE2"
22710   "maxsd\t{%2, %0|%0, %2}"
22711   [(set_attr "type" "sseadd")
22712    (set_attr "mode" "DF")])
22713
22714 (define_insn "sminv2df3"
22715   [(set (match_operand:V2DF 0 "register_operand" "=x")
22716         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22717                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22718   "TARGET_SSE2"
22719   "minpd\t{%2, %0|%0, %2}"
22720   [(set_attr "type" "sseadd")
22721    (set_attr "mode" "V2DF")])
22722
22723 (define_insn "vmsminv2df3"
22724   [(set (match_operand:V2DF 0 "register_operand" "=x")
22725         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22726                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22727                         (match_dup 1)
22728                         (const_int 1)))]
22729   "TARGET_SSE2"
22730   "minsd\t{%2, %0|%0, %2}"
22731   [(set_attr "type" "sseadd")
22732    (set_attr "mode" "DF")])
22733 ;; SSE2 square root.  There doesn't appear to be an extension for the
22734 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22735
22736 (define_insn "sqrtv2df2"
22737   [(set (match_operand:V2DF 0 "register_operand" "=x")
22738         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22739   "TARGET_SSE2"
22740   "sqrtpd\t{%1, %0|%0, %1}"
22741   [(set_attr "type" "sse")
22742    (set_attr "mode" "V2DF")])
22743
22744 (define_insn "vmsqrtv2df2"
22745   [(set (match_operand:V2DF 0 "register_operand" "=x")
22746         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22747                         (match_operand:V2DF 2 "register_operand" "0")
22748                         (const_int 1)))]
22749   "TARGET_SSE2"
22750   "sqrtsd\t{%1, %0|%0, %1}"
22751   [(set_attr "type" "sse")
22752    (set_attr "mode" "SF")])
22753
22754 ;; SSE mask-generating compares
22755
22756 (define_insn "maskcmpv2df3"
22757   [(set (match_operand:V2DI 0 "register_operand" "=x")
22758         (match_operator:V2DI 3 "sse_comparison_operator"
22759                              [(match_operand:V2DF 1 "register_operand" "0")
22760                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22761   "TARGET_SSE2"
22762   "cmp%D3pd\t{%2, %0|%0, %2}"
22763   [(set_attr "type" "ssecmp")
22764    (set_attr "mode" "V2DF")])
22765
22766 (define_insn "maskncmpv2df3"
22767   [(set (match_operand:V2DI 0 "register_operand" "=x")
22768         (not:V2DI
22769          (match_operator:V2DI 3 "sse_comparison_operator"
22770                               [(match_operand:V2DF 1 "register_operand" "0")
22771                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22772   "TARGET_SSE2"
22773 {
22774   if (GET_CODE (operands[3]) == UNORDERED)
22775     return "cmpordps\t{%2, %0|%0, %2}";
22776   else
22777     return "cmpn%D3pd\t{%2, %0|%0, %2}";
22778 }
22779   [(set_attr "type" "ssecmp")
22780    (set_attr "mode" "V2DF")])
22781
22782 (define_insn "vmmaskcmpv2df3"
22783   [(set (match_operand:V2DI 0 "register_operand" "=x")
22784         (vec_merge:V2DI
22785          (match_operator:V2DI 3 "sse_comparison_operator"
22786                               [(match_operand:V2DF 1 "register_operand" "0")
22787                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22788          (subreg:V2DI (match_dup 1) 0)
22789          (const_int 1)))]
22790   "TARGET_SSE2"
22791   "cmp%D3sd\t{%2, %0|%0, %2}"
22792   [(set_attr "type" "ssecmp")
22793    (set_attr "mode" "DF")])
22794
22795 (define_insn "vmmaskncmpv2df3"
22796   [(set (match_operand:V2DI 0 "register_operand" "=x")
22797         (vec_merge:V2DI
22798          (not:V2DI
22799           (match_operator:V2DI 3 "sse_comparison_operator"
22800                                [(match_operand:V2DF 1 "register_operand" "0")
22801                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22802          (subreg:V2DI (match_dup 1) 0)
22803          (const_int 1)))]
22804   "TARGET_SSE2"
22805 {
22806   if (GET_CODE (operands[3]) == UNORDERED)
22807     return "cmpordsd\t{%2, %0|%0, %2}";
22808   else
22809     return "cmpn%D3sd\t{%2, %0|%0, %2}";
22810 }
22811   [(set_attr "type" "ssecmp")
22812    (set_attr "mode" "DF")])
22813
22814 (define_insn "sse2_comi"
22815   [(set (reg:CCFP FLAGS_REG)
22816         (compare:CCFP (vec_select:DF
22817                        (match_operand:V2DF 0 "register_operand" "x")
22818                        (parallel [(const_int 0)]))
22819                       (vec_select:DF
22820                        (match_operand:V2DF 1 "register_operand" "x")
22821                        (parallel [(const_int 0)]))))]
22822   "TARGET_SSE2"
22823   "comisd\t{%1, %0|%0, %1}"
22824   [(set_attr "type" "ssecomi")
22825    (set_attr "mode" "DF")])
22826
22827 (define_insn "sse2_ucomi"
22828   [(set (reg:CCFPU FLAGS_REG)
22829         (compare:CCFPU (vec_select:DF
22830                          (match_operand:V2DF 0 "register_operand" "x")
22831                          (parallel [(const_int 0)]))
22832                         (vec_select:DF
22833                          (match_operand:V2DF 1 "register_operand" "x")
22834                          (parallel [(const_int 0)]))))]
22835   "TARGET_SSE2"
22836   "ucomisd\t{%1, %0|%0, %1}"
22837   [(set_attr "type" "ssecomi")
22838    (set_attr "mode" "DF")])
22839
22840 ;; SSE Strange Moves.
22841
22842 (define_insn "sse2_movmskpd"
22843   [(set (match_operand:SI 0 "register_operand" "=r")
22844         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22845                    UNSPEC_MOVMSK))]
22846   "TARGET_SSE2"
22847   "movmskpd\t{%1, %0|%0, %1}"
22848   [(set_attr "type" "ssecvt")
22849    (set_attr "mode" "V2DF")])
22850
22851 (define_insn "sse2_pmovmskb"
22852   [(set (match_operand:SI 0 "register_operand" "=r")
22853         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22854                    UNSPEC_MOVMSK))]
22855   "TARGET_SSE2"
22856   "pmovmskb\t{%1, %0|%0, %1}"
22857   [(set_attr "type" "ssecvt")
22858    (set_attr "mode" "V2DF")])
22859
22860 (define_insn "sse2_maskmovdqu"
22861   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22862         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22863                        (match_operand:V16QI 2 "register_operand" "x")]
22864                       UNSPEC_MASKMOV))]
22865   "TARGET_SSE2"
22866   ;; @@@ check ordering of operands in intel/nonintel syntax
22867   "maskmovdqu\t{%2, %1|%1, %2}"
22868   [(set_attr "type" "ssecvt")
22869    (set_attr "mode" "TI")])
22870
22871 (define_insn "sse2_maskmovdqu_rex64"
22872   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22873         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22874                        (match_operand:V16QI 2 "register_operand" "x")]
22875                       UNSPEC_MASKMOV))]
22876   "TARGET_SSE2"
22877   ;; @@@ check ordering of operands in intel/nonintel syntax
22878   "maskmovdqu\t{%2, %1|%1, %2}"
22879   [(set_attr "type" "ssecvt")
22880    (set_attr "mode" "TI")])
22881
22882 (define_insn "sse2_movntv2df"
22883   [(set (match_operand:V2DF 0 "memory_operand" "=m")
22884         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22885                      UNSPEC_MOVNT))]
22886   "TARGET_SSE2"
22887   "movntpd\t{%1, %0|%0, %1}"
22888   [(set_attr "type" "ssecvt")
22889    (set_attr "mode" "V2DF")])
22890
22891 (define_insn "sse2_movntv2di"
22892   [(set (match_operand:V2DI 0 "memory_operand" "=m")
22893         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22894                      UNSPEC_MOVNT))]
22895   "TARGET_SSE2"
22896   "movntdq\t{%1, %0|%0, %1}"
22897   [(set_attr "type" "ssecvt")
22898    (set_attr "mode" "TI")])
22899
22900 (define_insn "sse2_movntsi"
22901   [(set (match_operand:SI 0 "memory_operand" "=m")
22902         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22903                    UNSPEC_MOVNT))]
22904   "TARGET_SSE2"
22905   "movnti\t{%1, %0|%0, %1}"
22906   [(set_attr "type" "ssecvt")
22907    (set_attr "mode" "V2DF")])
22908
22909 ;; SSE <-> integer/MMX conversions
22910
22911 ;; Conversions between SI and SF
22912
22913 (define_insn "cvtdq2ps"
22914   [(set (match_operand:V4SF 0 "register_operand" "=x")
22915         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22916   "TARGET_SSE2"
22917   "cvtdq2ps\t{%1, %0|%0, %1}"
22918   [(set_attr "type" "ssecvt")
22919    (set_attr "mode" "V2DF")])
22920
22921 (define_insn "cvtps2dq"
22922   [(set (match_operand:V4SI 0 "register_operand" "=x")
22923         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22924   "TARGET_SSE2"
22925   "cvtps2dq\t{%1, %0|%0, %1}"
22926   [(set_attr "type" "ssecvt")
22927    (set_attr "mode" "TI")])
22928
22929 (define_insn "cvttps2dq"
22930   [(set (match_operand:V4SI 0 "register_operand" "=x")
22931         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22932                      UNSPEC_FIX))]
22933   "TARGET_SSE2"
22934   "cvttps2dq\t{%1, %0|%0, %1}"
22935   [(set_attr "type" "ssecvt")
22936    (set_attr "mode" "TI")])
22937
22938 ;; Conversions between SI and DF
22939
22940 (define_insn "cvtdq2pd"
22941   [(set (match_operand:V2DF 0 "register_operand" "=x")
22942         (float:V2DF (vec_select:V2SI
22943                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22944                      (parallel
22945                       [(const_int 0)
22946                        (const_int 1)]))))]
22947   "TARGET_SSE2"
22948   "cvtdq2pd\t{%1, %0|%0, %1}"
22949   [(set_attr "type" "ssecvt")
22950    (set_attr "mode" "V2DF")])
22951
22952 (define_insn "cvtpd2dq"
22953   [(set (match_operand:V4SI 0 "register_operand" "=x")
22954         (vec_concat:V4SI
22955          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22956          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22957   "TARGET_SSE2"
22958   "cvtpd2dq\t{%1, %0|%0, %1}"
22959   [(set_attr "type" "ssecvt")
22960    (set_attr "mode" "TI")])
22961
22962 (define_insn "cvttpd2dq"
22963   [(set (match_operand:V4SI 0 "register_operand" "=x")
22964         (vec_concat:V4SI
22965          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22966                       UNSPEC_FIX)
22967          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22968   "TARGET_SSE2"
22969   "cvttpd2dq\t{%1, %0|%0, %1}"
22970   [(set_attr "type" "ssecvt")
22971    (set_attr "mode" "TI")])
22972
22973 (define_insn "cvtpd2pi"
22974   [(set (match_operand:V2SI 0 "register_operand" "=y")
22975         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22976   "TARGET_SSE2"
22977   "cvtpd2pi\t{%1, %0|%0, %1}"
22978   [(set_attr "type" "ssecvt")
22979    (set_attr "mode" "TI")])
22980
22981 (define_insn "cvttpd2pi"
22982   [(set (match_operand:V2SI 0 "register_operand" "=y")
22983         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22984                      UNSPEC_FIX))]
22985   "TARGET_SSE2"
22986   "cvttpd2pi\t{%1, %0|%0, %1}"
22987   [(set_attr "type" "ssecvt")
22988    (set_attr "mode" "TI")])
22989
22990 (define_insn "cvtpi2pd"
22991   [(set (match_operand:V2DF 0 "register_operand" "=x")
22992         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22993   "TARGET_SSE2"
22994   "cvtpi2pd\t{%1, %0|%0, %1}"
22995   [(set_attr "type" "ssecvt")
22996    (set_attr "mode" "TI")])
22997
22998 ;; Conversions between SI and DF
22999
23000 (define_insn "cvtsd2si"
23001   [(set (match_operand:SI 0 "register_operand" "=r,r")
23002         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
23003                                (parallel [(const_int 0)]))))]
23004   "TARGET_SSE2"
23005   "cvtsd2si\t{%1, %0|%0, %1}"
23006   [(set_attr "type" "sseicvt")
23007    (set_attr "athlon_decode" "double,vector")
23008    (set_attr "mode" "SI")])
23009
23010 (define_insn "cvtsd2siq"
23011   [(set (match_operand:DI 0 "register_operand" "=r,r")
23012         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
23013                                (parallel [(const_int 0)]))))]
23014   "TARGET_SSE2 && TARGET_64BIT"
23015   "cvtsd2siq\t{%1, %0|%0, %1}"
23016   [(set_attr "type" "sseicvt")
23017    (set_attr "athlon_decode" "double,vector")
23018    (set_attr "mode" "DI")])
23019
23020 (define_insn "cvttsd2si"
23021   [(set (match_operand:SI 0 "register_operand" "=r,r")
23022         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
23023                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
23024   "TARGET_SSE2"
23025   "cvttsd2si\t{%1, %0|%0, %1}"
23026   [(set_attr "type" "sseicvt")
23027    (set_attr "mode" "SI")
23028    (set_attr "athlon_decode" "double,vector")])
23029
23030 (define_insn "cvttsd2siq"
23031   [(set (match_operand:DI 0 "register_operand" "=r,r")
23032         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
23033                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
23034   "TARGET_SSE2 && TARGET_64BIT"
23035   "cvttsd2siq\t{%1, %0|%0, %1}"
23036   [(set_attr "type" "sseicvt")
23037    (set_attr "mode" "DI")
23038    (set_attr "athlon_decode" "double,vector")])
23039
23040 (define_insn "cvtsi2sd"
23041   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
23042         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
23043                         (vec_duplicate:V2DF
23044                           (float:DF
23045                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
23046                         (const_int 2)))]
23047   "TARGET_SSE2"
23048   "cvtsi2sd\t{%2, %0|%0, %2}"
23049   [(set_attr "type" "sseicvt")
23050    (set_attr "mode" "DF")
23051    (set_attr "athlon_decode" "double,direct")])
23052
23053 (define_insn "cvtsi2sdq"
23054   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
23055         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
23056                         (vec_duplicate:V2DF
23057                           (float:DF
23058                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
23059                         (const_int 2)))]
23060   "TARGET_SSE2 && TARGET_64BIT"
23061   "cvtsi2sdq\t{%2, %0|%0, %2}"
23062   [(set_attr "type" "sseicvt")
23063    (set_attr "mode" "DF")
23064    (set_attr "athlon_decode" "double,direct")])
23065
23066 ;; Conversions between SF and DF
23067
23068 (define_insn "cvtsd2ss"
23069   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
23070         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
23071                         (vec_duplicate:V4SF
23072                           (float_truncate:V2SF
23073                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
23074                         (const_int 14)))]
23075   "TARGET_SSE2"
23076   "cvtsd2ss\t{%2, %0|%0, %2}"
23077   [(set_attr "type" "ssecvt")
23078    (set_attr "athlon_decode" "vector,double")
23079    (set_attr "mode" "SF")])
23080
23081 (define_insn "cvtss2sd"
23082   [(set (match_operand:V2DF 0 "register_operand" "=x")
23083         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
23084                         (float_extend:V2DF
23085                           (vec_select:V2SF
23086                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
23087                             (parallel [(const_int 0)
23088                                        (const_int 1)])))
23089                         (const_int 2)))]
23090   "TARGET_SSE2"
23091   "cvtss2sd\t{%2, %0|%0, %2}"
23092   [(set_attr "type" "ssecvt")
23093    (set_attr "mode" "DF")])
23094
23095 (define_insn "cvtpd2ps"
23096   [(set (match_operand:V4SF 0 "register_operand" "=x")
23097         (subreg:V4SF
23098           (vec_concat:V4SI
23099             (subreg:V2SI (float_truncate:V2SF
23100                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
23101             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
23102   "TARGET_SSE2"
23103   "cvtpd2ps\t{%1, %0|%0, %1}"
23104   [(set_attr "type" "ssecvt")
23105    (set_attr "mode" "V4SF")])
23106
23107 (define_insn "cvtps2pd"
23108   [(set (match_operand:V2DF 0 "register_operand" "=x")
23109         (float_extend:V2DF
23110           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
23111                            (parallel [(const_int 0)
23112                                       (const_int 1)]))))]
23113   "TARGET_SSE2"
23114   "cvtps2pd\t{%1, %0|%0, %1}"
23115   [(set_attr "type" "ssecvt")
23116    (set_attr "mode" "V2DF")])
23117
23118 ;; SSE2 variants of MMX insns
23119
23120 ;; MMX arithmetic
23121
23122 (define_insn "addv16qi3"
23123   [(set (match_operand:V16QI 0 "register_operand" "=x")
23124         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23125                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23126   "TARGET_SSE2"
23127   "paddb\t{%2, %0|%0, %2}"
23128   [(set_attr "type" "sseiadd")
23129    (set_attr "mode" "TI")])
23130
23131 (define_insn "addv8hi3"
23132   [(set (match_operand:V8HI 0 "register_operand" "=x")
23133         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23134                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23135   "TARGET_SSE2"
23136   "paddw\t{%2, %0|%0, %2}"
23137   [(set_attr "type" "sseiadd")
23138    (set_attr "mode" "TI")])
23139
23140 (define_insn "addv4si3"
23141   [(set (match_operand:V4SI 0 "register_operand" "=x")
23142         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
23143                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23144   "TARGET_SSE2"
23145   "paddd\t{%2, %0|%0, %2}"
23146   [(set_attr "type" "sseiadd")
23147    (set_attr "mode" "TI")])
23148
23149 (define_insn "addv2di3"
23150   [(set (match_operand:V2DI 0 "register_operand" "=x")
23151         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
23152                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23153   "TARGET_SSE2"
23154   "paddq\t{%2, %0|%0, %2}"
23155   [(set_attr "type" "sseiadd")
23156    (set_attr "mode" "TI")])
23157
23158 (define_insn "ssaddv16qi3"
23159   [(set (match_operand:V16QI 0 "register_operand" "=x")
23160         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23161                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23162   "TARGET_SSE2"
23163   "paddsb\t{%2, %0|%0, %2}"
23164   [(set_attr "type" "sseiadd")
23165    (set_attr "mode" "TI")])
23166
23167 (define_insn "ssaddv8hi3"
23168   [(set (match_operand:V8HI 0 "register_operand" "=x")
23169         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23170                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23171   "TARGET_SSE2"
23172   "paddsw\t{%2, %0|%0, %2}"
23173   [(set_attr "type" "sseiadd")
23174    (set_attr "mode" "TI")])
23175
23176 (define_insn "usaddv16qi3"
23177   [(set (match_operand:V16QI 0 "register_operand" "=x")
23178         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23179                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23180   "TARGET_SSE2"
23181   "paddusb\t{%2, %0|%0, %2}"
23182   [(set_attr "type" "sseiadd")
23183    (set_attr "mode" "TI")])
23184
23185 (define_insn "usaddv8hi3"
23186   [(set (match_operand:V8HI 0 "register_operand" "=x")
23187         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23188                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23189   "TARGET_SSE2"
23190   "paddusw\t{%2, %0|%0, %2}"
23191   [(set_attr "type" "sseiadd")
23192    (set_attr "mode" "TI")])
23193
23194 (define_insn "subv16qi3"
23195   [(set (match_operand:V16QI 0 "register_operand" "=x")
23196         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23197                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23198   "TARGET_SSE2"
23199   "psubb\t{%2, %0|%0, %2}"
23200   [(set_attr "type" "sseiadd")
23201    (set_attr "mode" "TI")])
23202
23203 (define_insn "subv8hi3"
23204   [(set (match_operand:V8HI 0 "register_operand" "=x")
23205         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23206                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23207   "TARGET_SSE2"
23208   "psubw\t{%2, %0|%0, %2}"
23209   [(set_attr "type" "sseiadd")
23210    (set_attr "mode" "TI")])
23211
23212 (define_insn "subv4si3"
23213   [(set (match_operand:V4SI 0 "register_operand" "=x")
23214         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
23215                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23216   "TARGET_SSE2"
23217   "psubd\t{%2, %0|%0, %2}"
23218   [(set_attr "type" "sseiadd")
23219    (set_attr "mode" "TI")])
23220
23221 (define_insn "subv2di3"
23222   [(set (match_operand:V2DI 0 "register_operand" "=x")
23223         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
23224                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23225   "TARGET_SSE2"
23226   "psubq\t{%2, %0|%0, %2}"
23227   [(set_attr "type" "sseiadd")
23228    (set_attr "mode" "TI")])
23229
23230 (define_insn "sssubv16qi3"
23231   [(set (match_operand:V16QI 0 "register_operand" "=x")
23232         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23233                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23234   "TARGET_SSE2"
23235   "psubsb\t{%2, %0|%0, %2}"
23236   [(set_attr "type" "sseiadd")
23237    (set_attr "mode" "TI")])
23238
23239 (define_insn "sssubv8hi3"
23240   [(set (match_operand:V8HI 0 "register_operand" "=x")
23241         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23242                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23243   "TARGET_SSE2"
23244   "psubsw\t{%2, %0|%0, %2}"
23245   [(set_attr "type" "sseiadd")
23246    (set_attr "mode" "TI")])
23247
23248 (define_insn "ussubv16qi3"
23249   [(set (match_operand:V16QI 0 "register_operand" "=x")
23250         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23251                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23252   "TARGET_SSE2"
23253   "psubusb\t{%2, %0|%0, %2}"
23254   [(set_attr "type" "sseiadd")
23255    (set_attr "mode" "TI")])
23256
23257 (define_insn "ussubv8hi3"
23258   [(set (match_operand:V8HI 0 "register_operand" "=x")
23259         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23260                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23261   "TARGET_SSE2"
23262   "psubusw\t{%2, %0|%0, %2}"
23263   [(set_attr "type" "sseiadd")
23264    (set_attr "mode" "TI")])
23265
23266 (define_insn "mulv8hi3"
23267   [(set (match_operand:V8HI 0 "register_operand" "=x")
23268         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
23269                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23270   "TARGET_SSE2"
23271   "pmullw\t{%2, %0|%0, %2}"
23272   [(set_attr "type" "sseimul")
23273    (set_attr "mode" "TI")])
23274
23275 (define_insn "smulv8hi3_highpart"
23276   [(set (match_operand:V8HI 0 "register_operand" "=x")
23277         (truncate:V8HI
23278          (lshiftrt:V8SI
23279           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23280                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23281           (const_int 16))))]
23282   "TARGET_SSE2"
23283   "pmulhw\t{%2, %0|%0, %2}"
23284   [(set_attr "type" "sseimul")
23285    (set_attr "mode" "TI")])
23286
23287 (define_insn "umulv8hi3_highpart"
23288   [(set (match_operand:V8HI 0 "register_operand" "=x")
23289         (truncate:V8HI
23290          (lshiftrt:V8SI
23291           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23292                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23293           (const_int 16))))]
23294   "TARGET_SSE2"
23295   "pmulhuw\t{%2, %0|%0, %2}"
23296   [(set_attr "type" "sseimul")
23297    (set_attr "mode" "TI")])
23298
23299 (define_insn "sse2_umulsidi3"
23300   [(set (match_operand:DI 0 "register_operand" "=y")
23301         (mult:DI (zero_extend:DI (vec_select:SI
23302                                   (match_operand:V2SI 1 "register_operand" "0")
23303                                   (parallel [(const_int 0)])))
23304                  (zero_extend:DI (vec_select:SI
23305                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
23306                                   (parallel [(const_int 0)])))))]
23307   "TARGET_SSE2"
23308   "pmuludq\t{%2, %0|%0, %2}"
23309   [(set_attr "type" "mmxmul")
23310    (set_attr "mode" "DI")])
23311
23312 (define_insn "sse2_umulv2siv2di3"
23313   [(set (match_operand:V2DI 0 "register_operand" "=x")
23314         (mult:V2DI (zero_extend:V2DI
23315                      (vec_select:V2SI
23316                        (match_operand:V4SI 1 "register_operand" "0")
23317                        (parallel [(const_int 0) (const_int 2)])))
23318                    (zero_extend:V2DI
23319                      (vec_select:V2SI
23320                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
23321                        (parallel [(const_int 0) (const_int 2)])))))]
23322   "TARGET_SSE2"
23323   "pmuludq\t{%2, %0|%0, %2}"
23324   [(set_attr "type" "sseimul")
23325    (set_attr "mode" "TI")])
23326
23327 (define_insn "sse2_pmaddwd"
23328   [(set (match_operand:V4SI 0 "register_operand" "=x")
23329         (plus:V4SI
23330          (mult:V4SI
23331           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23332                                              (parallel [(const_int 0)
23333                                                         (const_int 2)
23334                                                         (const_int 4)
23335                                                         (const_int 6)])))
23336           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23337                                              (parallel [(const_int 0)
23338                                                         (const_int 2)
23339                                                         (const_int 4)
23340                                                         (const_int 6)]))))
23341          (mult:V4SI
23342           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23343                                              (parallel [(const_int 1)
23344                                                         (const_int 3)
23345                                                         (const_int 5)
23346                                                         (const_int 7)])))
23347           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23348                                              (parallel [(const_int 1)
23349                                                         (const_int 3)
23350                                                         (const_int 5)
23351                                                         (const_int 7)]))))))]
23352   "TARGET_SSE2"
23353   "pmaddwd\t{%2, %0|%0, %2}"
23354   [(set_attr "type" "sseiadd")
23355    (set_attr "mode" "TI")])
23356
23357 ;; Same as pxor, but don't show input operands so that we don't think
23358 ;; they are live.
23359 (define_insn "sse2_clrti"
23360   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23361   "TARGET_SSE2"
23362 {
23363   if (get_attr_mode (insn) == MODE_TI)
23364     return "pxor\t%0, %0";
23365   else
23366     return "xorps\t%0, %0";
23367 }
23368   [(set_attr "type" "ssemov")
23369    (set_attr "memory" "none")
23370    (set (attr "mode")
23371               (if_then_else
23372                 (ne (symbol_ref "optimize_size")
23373                     (const_int 0))
23374                 (const_string "V4SF")
23375                 (const_string "TI")))])
23376
23377 ;; MMX unsigned averages/sum of absolute differences
23378
23379 (define_insn "sse2_uavgv16qi3"
23380   [(set (match_operand:V16QI 0 "register_operand" "=x")
23381         (ashiftrt:V16QI
23382          (plus:V16QI (plus:V16QI
23383                      (match_operand:V16QI 1 "register_operand" "0")
23384                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23385                      (const_vector:V16QI [(const_int 1) (const_int 1)
23386                                           (const_int 1) (const_int 1)
23387                                           (const_int 1) (const_int 1)
23388                                           (const_int 1) (const_int 1)
23389                                           (const_int 1) (const_int 1)
23390                                           (const_int 1) (const_int 1)
23391                                           (const_int 1) (const_int 1)
23392                                           (const_int 1) (const_int 1)]))
23393          (const_int 1)))]
23394   "TARGET_SSE2"
23395   "pavgb\t{%2, %0|%0, %2}"
23396   [(set_attr "type" "sseiadd")
23397    (set_attr "mode" "TI")])
23398
23399 (define_insn "sse2_uavgv8hi3"
23400   [(set (match_operand:V8HI 0 "register_operand" "=x")
23401         (ashiftrt:V8HI
23402          (plus:V8HI (plus:V8HI
23403                      (match_operand:V8HI 1 "register_operand" "0")
23404                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23405                     (const_vector:V8HI [(const_int 1) (const_int 1)
23406                                         (const_int 1) (const_int 1)
23407                                         (const_int 1) (const_int 1)
23408                                         (const_int 1) (const_int 1)]))
23409          (const_int 1)))]
23410   "TARGET_SSE2"
23411   "pavgw\t{%2, %0|%0, %2}"
23412   [(set_attr "type" "sseiadd")
23413    (set_attr "mode" "TI")])
23414
23415 ;; @@@ this isn't the right representation.
23416 (define_insn "sse2_psadbw"
23417   [(set (match_operand:V2DI 0 "register_operand" "=x")
23418         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23419                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23420                      UNSPEC_PSADBW))]
23421   "TARGET_SSE2"
23422   "psadbw\t{%2, %0|%0, %2}"
23423   [(set_attr "type" "sseiadd")
23424    (set_attr "mode" "TI")])
23425
23426
23427 ;; MMX insert/extract/shuffle
23428
23429 (define_insn "sse2_pinsrw"
23430   [(set (match_operand:V8HI 0 "register_operand" "=x")
23431         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
23432                         (vec_duplicate:V8HI
23433                          (truncate:HI
23434                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
23435                         (match_operand:SI 3 "const_0_to_255_operand" "N")))]
23436   "TARGET_SSE2"
23437   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
23438   [(set_attr "type" "ssecvt")
23439    (set_attr "mode" "TI")])
23440
23441 (define_insn "sse2_pextrw"
23442   [(set (match_operand:SI 0 "register_operand" "=r")
23443         (zero_extend:SI
23444           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23445                          (parallel
23446                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23447   "TARGET_SSE2"
23448   "pextrw\t{%2, %1, %0|%0, %1, %2}"
23449   [(set_attr "type" "ssecvt")
23450    (set_attr "mode" "TI")])
23451
23452 (define_insn "sse2_pshufd"
23453   [(set (match_operand:V4SI 0 "register_operand" "=x")
23454         (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23455                       (match_operand:SI 2 "immediate_operand" "i")]
23456                      UNSPEC_SHUFFLE))]
23457   "TARGET_SSE2"
23458   "pshufd\t{%2, %1, %0|%0, %1, %2}"
23459   [(set_attr "type" "ssecvt")
23460    (set_attr "mode" "TI")])
23461
23462 (define_insn "sse2_pshuflw"
23463   [(set (match_operand:V8HI 0 "register_operand" "=x")
23464         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23465                       (match_operand:SI 2 "immediate_operand" "i")]
23466                      UNSPEC_PSHUFLW))]
23467   "TARGET_SSE2"
23468   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23469   [(set_attr "type" "ssecvt")
23470    (set_attr "mode" "TI")])
23471
23472 (define_insn "sse2_pshufhw"
23473   [(set (match_operand:V8HI 0 "register_operand" "=x")
23474         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23475                       (match_operand:SI 2 "immediate_operand" "i")]
23476                      UNSPEC_PSHUFHW))]
23477   "TARGET_SSE2"
23478   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23479   [(set_attr "type" "ssecvt")
23480    (set_attr "mode" "TI")])
23481
23482 ;; MMX mask-generating comparisons
23483
23484 (define_insn "eqv16qi3"
23485   [(set (match_operand:V16QI 0 "register_operand" "=x")
23486         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23487                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23488   "TARGET_SSE2"
23489   "pcmpeqb\t{%2, %0|%0, %2}"
23490   [(set_attr "type" "ssecmp")
23491    (set_attr "mode" "TI")])
23492
23493 (define_insn "eqv8hi3"
23494   [(set (match_operand:V8HI 0 "register_operand" "=x")
23495         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23496                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23497   "TARGET_SSE2"
23498   "pcmpeqw\t{%2, %0|%0, %2}"
23499   [(set_attr "type" "ssecmp")
23500    (set_attr "mode" "TI")])
23501
23502 (define_insn "eqv4si3"
23503   [(set (match_operand:V4SI 0 "register_operand" "=x")
23504         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23505                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23506   "TARGET_SSE2"
23507   "pcmpeqd\t{%2, %0|%0, %2}"
23508   [(set_attr "type" "ssecmp")
23509    (set_attr "mode" "TI")])
23510
23511 (define_insn "gtv16qi3"
23512   [(set (match_operand:V16QI 0 "register_operand" "=x")
23513         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23514                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23515   "TARGET_SSE2"
23516   "pcmpgtb\t{%2, %0|%0, %2}"
23517   [(set_attr "type" "ssecmp")
23518    (set_attr "mode" "TI")])
23519
23520 (define_insn "gtv8hi3"
23521   [(set (match_operand:V8HI 0 "register_operand" "=x")
23522         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23523                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23524   "TARGET_SSE2"
23525   "pcmpgtw\t{%2, %0|%0, %2}"
23526   [(set_attr "type" "ssecmp")
23527    (set_attr "mode" "TI")])
23528
23529 (define_insn "gtv4si3"
23530   [(set (match_operand:V4SI 0 "register_operand" "=x")
23531         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23532                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23533   "TARGET_SSE2"
23534   "pcmpgtd\t{%2, %0|%0, %2}"
23535   [(set_attr "type" "ssecmp")
23536    (set_attr "mode" "TI")])
23537
23538
23539 ;; MMX max/min insns
23540
23541 (define_insn "umaxv16qi3"
23542   [(set (match_operand:V16QI 0 "register_operand" "=x")
23543         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23544                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23545   "TARGET_SSE2"
23546   "pmaxub\t{%2, %0|%0, %2}"
23547   [(set_attr "type" "sseiadd")
23548    (set_attr "mode" "TI")])
23549
23550 (define_insn "smaxv8hi3"
23551   [(set (match_operand:V8HI 0 "register_operand" "=x")
23552         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23553                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23554   "TARGET_SSE2"
23555   "pmaxsw\t{%2, %0|%0, %2}"
23556   [(set_attr "type" "sseiadd")
23557    (set_attr "mode" "TI")])
23558
23559 (define_insn "uminv16qi3"
23560   [(set (match_operand:V16QI 0 "register_operand" "=x")
23561         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23562                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23563   "TARGET_SSE2"
23564   "pminub\t{%2, %0|%0, %2}"
23565   [(set_attr "type" "sseiadd")
23566    (set_attr "mode" "TI")])
23567
23568 (define_insn "sminv8hi3"
23569   [(set (match_operand:V8HI 0 "register_operand" "=x")
23570         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23571                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23572   "TARGET_SSE2"
23573   "pminsw\t{%2, %0|%0, %2}"
23574   [(set_attr "type" "sseiadd")
23575    (set_attr "mode" "TI")])
23576
23577
23578 ;; MMX shifts
23579
23580 (define_insn "ashrv8hi3"
23581   [(set (match_operand:V8HI 0 "register_operand" "=x")
23582         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23583                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23584   "TARGET_SSE2"
23585   "psraw\t{%2, %0|%0, %2}"
23586   [(set_attr "type" "sseishft")
23587    (set_attr "mode" "TI")])
23588
23589 (define_insn "ashrv4si3"
23590   [(set (match_operand:V4SI 0 "register_operand" "=x")
23591         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23592                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23593   "TARGET_SSE2"
23594   "psrad\t{%2, %0|%0, %2}"
23595   [(set_attr "type" "sseishft")
23596    (set_attr "mode" "TI")])
23597
23598 (define_insn "lshrv8hi3"
23599   [(set (match_operand:V8HI 0 "register_operand" "=x")
23600         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23601                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23602   "TARGET_SSE2"
23603   "psrlw\t{%2, %0|%0, %2}"
23604   [(set_attr "type" "sseishft")
23605    (set_attr "mode" "TI")])
23606
23607 (define_insn "lshrv4si3"
23608   [(set (match_operand:V4SI 0 "register_operand" "=x")
23609         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23610                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23611   "TARGET_SSE2"
23612   "psrld\t{%2, %0|%0, %2}"
23613   [(set_attr "type" "sseishft")
23614    (set_attr "mode" "TI")])
23615
23616 (define_insn "lshrv2di3"
23617   [(set (match_operand:V2DI 0 "register_operand" "=x")
23618         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23619                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23620   "TARGET_SSE2"
23621   "psrlq\t{%2, %0|%0, %2}"
23622   [(set_attr "type" "sseishft")
23623    (set_attr "mode" "TI")])
23624
23625 (define_insn "ashlv8hi3"
23626   [(set (match_operand:V8HI 0 "register_operand" "=x")
23627         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23628                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23629   "TARGET_SSE2"
23630   "psllw\t{%2, %0|%0, %2}"
23631   [(set_attr "type" "sseishft")
23632    (set_attr "mode" "TI")])
23633
23634 (define_insn "ashlv4si3"
23635   [(set (match_operand:V4SI 0 "register_operand" "=x")
23636         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23637                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23638   "TARGET_SSE2"
23639   "pslld\t{%2, %0|%0, %2}"
23640   [(set_attr "type" "sseishft")
23641    (set_attr "mode" "TI")])
23642
23643 (define_insn "ashlv2di3"
23644   [(set (match_operand:V2DI 0 "register_operand" "=x")
23645         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23646                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23647   "TARGET_SSE2"
23648   "psllq\t{%2, %0|%0, %2}"
23649   [(set_attr "type" "sseishft")
23650    (set_attr "mode" "TI")])
23651
23652 (define_insn "ashrv8hi3_ti"
23653   [(set (match_operand:V8HI 0 "register_operand" "=x")
23654         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23655                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23656   "TARGET_SSE2"
23657   "psraw\t{%2, %0|%0, %2}"
23658   [(set_attr "type" "sseishft")
23659    (set_attr "mode" "TI")])
23660
23661 (define_insn "ashrv4si3_ti"
23662   [(set (match_operand:V4SI 0 "register_operand" "=x")
23663         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23664                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23665   "TARGET_SSE2"
23666   "psrad\t{%2, %0|%0, %2}"
23667   [(set_attr "type" "sseishft")
23668    (set_attr "mode" "TI")])
23669
23670 (define_insn "lshrv8hi3_ti"
23671   [(set (match_operand:V8HI 0 "register_operand" "=x")
23672         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23673                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23674   "TARGET_SSE2"
23675   "psrlw\t{%2, %0|%0, %2}"
23676   [(set_attr "type" "sseishft")
23677    (set_attr "mode" "TI")])
23678
23679 (define_insn "lshrv4si3_ti"
23680   [(set (match_operand:V4SI 0 "register_operand" "=x")
23681         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23682                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23683   "TARGET_SSE2"
23684   "psrld\t{%2, %0|%0, %2}"
23685   [(set_attr "type" "sseishft")
23686    (set_attr "mode" "TI")])
23687
23688 (define_insn "lshrv2di3_ti"
23689   [(set (match_operand:V2DI 0 "register_operand" "=x")
23690         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23691                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23692   "TARGET_SSE2"
23693   "psrlq\t{%2, %0|%0, %2}"
23694   [(set_attr "type" "sseishft")
23695    (set_attr "mode" "TI")])
23696
23697 (define_insn "ashlv8hi3_ti"
23698   [(set (match_operand:V8HI 0 "register_operand" "=x")
23699         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23700                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23701   "TARGET_SSE2"
23702   "psllw\t{%2, %0|%0, %2}"
23703   [(set_attr "type" "sseishft")
23704    (set_attr "mode" "TI")])
23705
23706 (define_insn "ashlv4si3_ti"
23707   [(set (match_operand:V4SI 0 "register_operand" "=x")
23708         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23709                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23710   "TARGET_SSE2"
23711   "pslld\t{%2, %0|%0, %2}"
23712   [(set_attr "type" "sseishft")
23713    (set_attr "mode" "TI")])
23714
23715 (define_insn "ashlv2di3_ti"
23716   [(set (match_operand:V2DI 0 "register_operand" "=x")
23717         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23718                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23719   "TARGET_SSE2"
23720   "psllq\t{%2, %0|%0, %2}"
23721   [(set_attr "type" "sseishft")
23722    (set_attr "mode" "TI")])
23723
23724 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
23725 ;; we wouldn't need here it since we never generate TImode arithmetic.
23726
23727 ;; There has to be some kind of prize for the weirdest new instruction...
23728 (define_insn "sse2_ashlti3"
23729   [(set (match_operand:TI 0 "register_operand" "=x")
23730         (unspec:TI
23731          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23732                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23733                                (const_int 8)))] UNSPEC_NOP))]
23734   "TARGET_SSE2"
23735   "pslldq\t{%2, %0|%0, %2}"
23736   [(set_attr "type" "sseishft")
23737    (set_attr "mode" "TI")])
23738
23739 (define_insn "sse2_lshrti3"
23740   [(set (match_operand:TI 0 "register_operand" "=x")
23741         (unspec:TI
23742          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23743                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23744                                 (const_int 8)))] UNSPEC_NOP))]
23745   "TARGET_SSE2"
23746   "psrldq\t{%2, %0|%0, %2}"
23747   [(set_attr "type" "sseishft")
23748    (set_attr "mode" "TI")])
23749
23750 ;; SSE unpack
23751
23752 (define_insn "sse2_unpckhpd"
23753   [(set (match_operand:V2DF 0 "register_operand" "=x")
23754         (vec_concat:V2DF
23755          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23756                         (parallel [(const_int 1)]))
23757          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23758                         (parallel [(const_int 1)]))))]
23759   "TARGET_SSE2"
23760   "unpckhpd\t{%2, %0|%0, %2}"
23761   [(set_attr "type" "ssecvt")
23762    (set_attr "mode" "V2DF")])
23763
23764 (define_insn "sse2_unpcklpd"
23765   [(set (match_operand:V2DF 0 "register_operand" "=x")
23766         (vec_concat:V2DF
23767          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23768                         (parallel [(const_int 0)]))
23769          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23770                         (parallel [(const_int 0)]))))]
23771   "TARGET_SSE2"
23772   "unpcklpd\t{%2, %0|%0, %2}"
23773   [(set_attr "type" "ssecvt")
23774    (set_attr "mode" "V2DF")])
23775
23776 ;; MMX pack/unpack insns.
23777
23778 (define_insn "sse2_packsswb"
23779   [(set (match_operand:V16QI 0 "register_operand" "=x")
23780         (vec_concat:V16QI
23781          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23782          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23783   "TARGET_SSE2"
23784   "packsswb\t{%2, %0|%0, %2}"
23785   [(set_attr "type" "ssecvt")
23786    (set_attr "mode" "TI")])
23787
23788 (define_insn "sse2_packssdw"
23789   [(set (match_operand:V8HI 0 "register_operand" "=x")
23790         (vec_concat:V8HI
23791          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23792          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23793   "TARGET_SSE2"
23794   "packssdw\t{%2, %0|%0, %2}"
23795   [(set_attr "type" "ssecvt")
23796    (set_attr "mode" "TI")])
23797
23798 (define_insn "sse2_packuswb"
23799   [(set (match_operand:V16QI 0 "register_operand" "=x")
23800         (vec_concat:V16QI
23801          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23802          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23803   "TARGET_SSE2"
23804   "packuswb\t{%2, %0|%0, %2}"
23805   [(set_attr "type" "ssecvt")
23806    (set_attr "mode" "TI")])
23807
23808 (define_insn "sse2_punpckhbw"
23809   [(set (match_operand:V16QI 0 "register_operand" "=x")
23810         (vec_merge:V16QI
23811          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23812                            (parallel [(const_int 8) (const_int 0)
23813                                       (const_int 9) (const_int 1)
23814                                       (const_int 10) (const_int 2)
23815                                       (const_int 11) (const_int 3)
23816                                       (const_int 12) (const_int 4)
23817                                       (const_int 13) (const_int 5)
23818                                       (const_int 14) (const_int 6)
23819                                       (const_int 15) (const_int 7)]))
23820          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23821                            (parallel [(const_int 0) (const_int 8)
23822                                       (const_int 1) (const_int 9)
23823                                       (const_int 2) (const_int 10)
23824                                       (const_int 3) (const_int 11)
23825                                       (const_int 4) (const_int 12)
23826                                       (const_int 5) (const_int 13)
23827                                       (const_int 6) (const_int 14)
23828                                       (const_int 7) (const_int 15)]))
23829          (const_int 21845)))]
23830   "TARGET_SSE2"
23831   "punpckhbw\t{%2, %0|%0, %2}"
23832   [(set_attr "type" "ssecvt")
23833    (set_attr "mode" "TI")])
23834
23835 (define_insn "sse2_punpckhwd"
23836   [(set (match_operand:V8HI 0 "register_operand" "=x")
23837         (vec_merge:V8HI
23838          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23839                           (parallel [(const_int 4) (const_int 0)
23840                                      (const_int 5) (const_int 1)
23841                                      (const_int 6) (const_int 2)
23842                                      (const_int 7) (const_int 3)]))
23843          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23844                           (parallel [(const_int 0) (const_int 4)
23845                                      (const_int 1) (const_int 5)
23846                                      (const_int 2) (const_int 6)
23847                                      (const_int 3) (const_int 7)]))
23848          (const_int 85)))]
23849   "TARGET_SSE2"
23850   "punpckhwd\t{%2, %0|%0, %2}"
23851   [(set_attr "type" "ssecvt")
23852    (set_attr "mode" "TI")])
23853
23854 (define_insn "sse2_punpckhdq"
23855   [(set (match_operand:V4SI 0 "register_operand" "=x")
23856         (vec_merge:V4SI
23857          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23858                           (parallel [(const_int 2) (const_int 0)
23859                                      (const_int 3) (const_int 1)]))
23860          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23861                           (parallel [(const_int 0) (const_int 2)
23862                                      (const_int 1) (const_int 3)]))
23863          (const_int 5)))]
23864   "TARGET_SSE2"
23865   "punpckhdq\t{%2, %0|%0, %2}"
23866   [(set_attr "type" "ssecvt")
23867    (set_attr "mode" "TI")])
23868
23869 (define_insn "sse2_punpcklbw"
23870   [(set (match_operand:V16QI 0 "register_operand" "=x")
23871         (vec_merge:V16QI
23872          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23873                            (parallel [(const_int 0) (const_int 8)
23874                                       (const_int 1) (const_int 9)
23875                                       (const_int 2) (const_int 10)
23876                                       (const_int 3) (const_int 11)
23877                                       (const_int 4) (const_int 12)
23878                                       (const_int 5) (const_int 13)
23879                                       (const_int 6) (const_int 14)
23880                                       (const_int 7) (const_int 15)]))
23881          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23882                            (parallel [(const_int 8) (const_int 0)
23883                                       (const_int 9) (const_int 1)
23884                                       (const_int 10) (const_int 2)
23885                                       (const_int 11) (const_int 3)
23886                                       (const_int 12) (const_int 4)
23887                                       (const_int 13) (const_int 5)
23888                                       (const_int 14) (const_int 6)
23889                                       (const_int 15) (const_int 7)]))
23890          (const_int 21845)))]
23891   "TARGET_SSE2"
23892   "punpcklbw\t{%2, %0|%0, %2}"
23893   [(set_attr "type" "ssecvt")
23894    (set_attr "mode" "TI")])
23895
23896 (define_insn "sse2_punpcklwd"
23897   [(set (match_operand:V8HI 0 "register_operand" "=x")
23898         (vec_merge:V8HI
23899          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23900                           (parallel [(const_int 0) (const_int 4)
23901                                      (const_int 1) (const_int 5)
23902                                      (const_int 2) (const_int 6)
23903                                      (const_int 3) (const_int 7)]))
23904          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23905                           (parallel [(const_int 4) (const_int 0)
23906                                      (const_int 5) (const_int 1)
23907                                      (const_int 6) (const_int 2)
23908                                      (const_int 7) (const_int 3)]))
23909          (const_int 85)))]
23910   "TARGET_SSE2"
23911   "punpcklwd\t{%2, %0|%0, %2}"
23912   [(set_attr "type" "ssecvt")
23913    (set_attr "mode" "TI")])
23914
23915 (define_insn "sse2_punpckldq"
23916   [(set (match_operand:V4SI 0 "register_operand" "=x")
23917         (vec_merge:V4SI
23918          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23919                           (parallel [(const_int 0) (const_int 2)
23920                                      (const_int 1) (const_int 3)]))
23921          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23922                           (parallel [(const_int 2) (const_int 0)
23923                                      (const_int 3) (const_int 1)]))
23924          (const_int 5)))]
23925   "TARGET_SSE2"
23926   "punpckldq\t{%2, %0|%0, %2}"
23927   [(set_attr "type" "ssecvt")
23928    (set_attr "mode" "TI")])
23929
23930 (define_insn "sse2_punpcklqdq"
23931   [(set (match_operand:V2DI 0 "register_operand" "=x")
23932         (vec_merge:V2DI
23933          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23934                           (parallel [(const_int 1)
23935                                      (const_int 0)]))
23936          (match_operand:V2DI 1 "register_operand" "0")
23937          (const_int 1)))]
23938   "TARGET_SSE2"
23939   "punpcklqdq\t{%2, %0|%0, %2}"
23940   [(set_attr "type" "ssecvt")
23941    (set_attr "mode" "TI")])
23942
23943 (define_insn "sse2_punpckhqdq"
23944   [(set (match_operand:V2DI 0 "register_operand" "=x")
23945         (vec_merge:V2DI
23946          (match_operand:V2DI 1 "register_operand" "0")
23947          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23948                           (parallel [(const_int 1)
23949                                      (const_int 0)]))
23950          (const_int 1)))]
23951   "TARGET_SSE2"
23952   "punpckhqdq\t{%2, %0|%0, %2}"
23953   [(set_attr "type" "ssecvt")
23954    (set_attr "mode" "TI")])
23955
23956 ;; SSE2 moves
23957
23958 (define_insn "sse2_movapd"
23959   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23960         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23961                      UNSPEC_MOVA))]
23962   "TARGET_SSE2
23963    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23964   "movapd\t{%1, %0|%0, %1}"
23965   [(set_attr "type" "ssemov")
23966    (set_attr "mode" "V2DF")])
23967
23968 (define_insn "sse2_movupd"
23969   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23970         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23971                      UNSPEC_MOVU))]
23972   "TARGET_SSE2
23973    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23974   "movupd\t{%1, %0|%0, %1}"
23975   [(set_attr "type" "ssecvt")
23976    (set_attr "mode" "V2DF")])
23977
23978 (define_insn "sse2_movdqa"
23979   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23980         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23981                        UNSPEC_MOVA))]
23982   "TARGET_SSE2
23983    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23984   "movdqa\t{%1, %0|%0, %1}"
23985   [(set_attr "type" "ssemov")
23986    (set_attr "mode" "TI")])
23987
23988 (define_insn "sse2_movdqu"
23989   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23990         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23991                        UNSPEC_MOVU))]
23992   "TARGET_SSE2
23993    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23994   "movdqu\t{%1, %0|%0, %1}"
23995   [(set_attr "type" "ssecvt")
23996    (set_attr "mode" "TI")])
23997
23998 (define_insn "sse2_movdq2q"
23999   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
24000         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
24001                        (parallel [(const_int 0)])))]
24002   "TARGET_SSE2 && !TARGET_64BIT"
24003   "@
24004    movq\t{%1, %0|%0, %1}
24005    movdq2q\t{%1, %0|%0, %1}"
24006   [(set_attr "type" "ssecvt")
24007    (set_attr "mode" "TI")])
24008
24009 (define_insn "sse2_movdq2q_rex64"
24010   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
24011         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
24012                        (parallel [(const_int 0)])))]
24013   "TARGET_SSE2 && TARGET_64BIT"
24014   "@
24015    movq\t{%1, %0|%0, %1}
24016    movdq2q\t{%1, %0|%0, %1}
24017    movd\t{%1, %0|%0, %1}"
24018   [(set_attr "type" "ssecvt")
24019    (set_attr "mode" "TI")])
24020
24021 (define_insn "sse2_movq2dq"
24022   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
24023         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
24024                          (const_int 0)))]
24025   "TARGET_SSE2 && !TARGET_64BIT"
24026   "@
24027    movq\t{%1, %0|%0, %1}
24028    movq2dq\t{%1, %0|%0, %1}"
24029   [(set_attr "type" "ssecvt,ssemov")
24030    (set_attr "mode" "TI")])
24031
24032 (define_insn "sse2_movq2dq_rex64"
24033   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
24034         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
24035                          (const_int 0)))]
24036   "TARGET_SSE2 && TARGET_64BIT"
24037   "@
24038    movq\t{%1, %0|%0, %1}
24039    movq2dq\t{%1, %0|%0, %1}
24040    movd\t{%1, %0|%0, %1}"
24041   [(set_attr "type" "ssecvt,ssemov,ssecvt")
24042    (set_attr "mode" "TI")])
24043
24044 (define_insn "sse2_movq"
24045   [(set (match_operand:V2DI 0 "register_operand" "=x")
24046         (vec_concat:V2DI (vec_select:DI
24047                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
24048                           (parallel [(const_int 0)]))
24049                          (const_int 0)))]
24050   "TARGET_SSE2"
24051   "movq\t{%1, %0|%0, %1}"
24052   [(set_attr "type" "ssemov")
24053    (set_attr "mode" "TI")])
24054
24055 (define_insn "sse2_loadd"
24056   [(set (match_operand:V4SI 0 "register_operand" "=x")
24057         (vec_merge:V4SI
24058          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
24059          (const_vector:V4SI [(const_int 0)
24060                              (const_int 0)
24061                              (const_int 0)
24062                              (const_int 0)])
24063          (const_int 1)))]
24064   "TARGET_SSE2"
24065   "movd\t{%1, %0|%0, %1}"
24066   [(set_attr "type" "ssemov")
24067    (set_attr "mode" "TI")])
24068
24069 (define_insn "sse2_stored"
24070   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
24071         (vec_select:SI
24072          (match_operand:V4SI 1 "register_operand" "x")
24073          (parallel [(const_int 0)])))]
24074   "TARGET_SSE2"
24075   "movd\t{%1, %0|%0, %1}"
24076   [(set_attr "type" "ssemov")
24077    (set_attr "mode" "TI")])
24078
24079 (define_insn "sse2_movhpd"
24080   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24081         (vec_merge:V2DF
24082          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
24083          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
24084          (const_int 1)))]
24085   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
24086   "movhpd\t{%2, %0|%0, %2}"
24087   [(set_attr "type" "ssecvt")
24088    (set_attr "mode" "V2DF")])
24089
24090 (define_expand "sse2_loadsd"
24091   [(match_operand:V2DF 0 "register_operand" "")
24092    (match_operand:DF 1 "memory_operand" "")]
24093   "TARGET_SSE2"
24094 {
24095   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
24096                                 CONST0_RTX (V2DFmode)));
24097   DONE;
24098 })
24099
24100 (define_insn "sse2_loadsd_1"
24101   [(set (match_operand:V2DF 0 "register_operand" "=x")
24102         (vec_merge:V2DF
24103          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
24104          (match_operand:V2DF 2 "const0_operand" "X")
24105          (const_int 1)))]
24106   "TARGET_SSE2"
24107   "movsd\t{%1, %0|%0, %1}"
24108   [(set_attr "type" "ssecvt")
24109    (set_attr "mode" "DF")])
24110
24111 (define_insn "sse2_movsd"
24112   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
24113         (vec_merge:V2DF
24114          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
24115          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
24116          (const_int 2)))]
24117   "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
24118   "@movsd\t{%2, %0|%0, %2}
24119     movlpd\t{%2, %0|%0, %2}
24120     movlpd\t{%2, %0|%0, %2}"
24121   [(set_attr "type" "ssecvt")
24122    (set_attr "mode" "DF,V2DF,V2DF")])
24123
24124 (define_insn "sse2_storesd"
24125   [(set (match_operand:DF 0 "memory_operand" "=m")
24126         (vec_select:DF
24127          (match_operand:V2DF 1 "register_operand" "x")
24128          (parallel [(const_int 0)])))]
24129   "TARGET_SSE2"
24130   "movsd\t{%1, %0|%0, %1}"
24131   [(set_attr "type" "ssecvt")
24132    (set_attr "mode" "DF")])
24133
24134 (define_insn "sse2_shufpd"
24135   [(set (match_operand:V2DF 0 "register_operand" "=x")
24136         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24137                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
24138                       (match_operand:SI 3 "immediate_operand" "i")]
24139                      UNSPEC_SHUFFLE))]
24140   "TARGET_SSE2"
24141   ;; @@@ check operand order for intel/nonintel syntax
24142   "shufpd\t{%3, %2, %0|%0, %2, %3}"
24143   [(set_attr "type" "ssecvt")
24144    (set_attr "mode" "V2DF")])
24145
24146 (define_insn "sse2_clflush"
24147   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
24148                     UNSPECV_CLFLUSH)]
24149   "TARGET_SSE2"
24150   "clflush\t%a0"
24151   [(set_attr "type" "sse")
24152    (set_attr "memory" "unknown")])
24153
24154 (define_expand "sse2_mfence"
24155   [(set (match_dup 0)
24156         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24157   "TARGET_SSE2"
24158 {
24159   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24160   MEM_VOLATILE_P (operands[0]) = 1;
24161 })
24162
24163 (define_insn "*mfence_insn"
24164   [(set (match_operand:BLK 0 "" "")
24165         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24166   "TARGET_SSE2"
24167   "mfence"
24168   [(set_attr "type" "sse")
24169    (set_attr "memory" "unknown")])
24170
24171 (define_expand "sse2_lfence"
24172   [(set (match_dup 0)
24173         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24174   "TARGET_SSE2"
24175 {
24176   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24177   MEM_VOLATILE_P (operands[0]) = 1;
24178 })
24179
24180 (define_insn "*lfence_insn"
24181   [(set (match_operand:BLK 0 "" "")
24182         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24183   "TARGET_SSE2"
24184   "lfence"
24185   [(set_attr "type" "sse")
24186    (set_attr "memory" "unknown")])
24187
24188 ;; SSE3
24189
24190 (define_insn "mwait"
24191   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24192                      (match_operand:SI 1 "register_operand" "c")]
24193                     UNSPECV_MWAIT)]
24194   "TARGET_SSE3"
24195   "mwait\t%0, %1"
24196   [(set_attr "length" "3")])
24197
24198 (define_insn "monitor"
24199   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24200                      (match_operand:SI 1 "register_operand" "c")
24201                      (match_operand:SI 2 "register_operand" "d")]
24202                     UNSPECV_MONITOR)]
24203   "TARGET_SSE3"
24204   "monitor\t%0, %1, %2"
24205   [(set_attr "length" "3")])
24206
24207 ;; SSE3 arithmetic
24208
24209 (define_insn "addsubv4sf3"
24210   [(set (match_operand:V4SF 0 "register_operand" "=x")
24211         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24212                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24213                      UNSPEC_ADDSUB))]
24214   "TARGET_SSE3"
24215   "addsubps\t{%2, %0|%0, %2}"
24216   [(set_attr "type" "sseadd")
24217    (set_attr "mode" "V4SF")])
24218
24219 (define_insn "addsubv2df3"
24220   [(set (match_operand:V2DF 0 "register_operand" "=x")
24221         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24222                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24223                      UNSPEC_ADDSUB))]
24224   "TARGET_SSE3"
24225   "addsubpd\t{%2, %0|%0, %2}"
24226   [(set_attr "type" "sseadd")
24227    (set_attr "mode" "V2DF")])
24228
24229 (define_insn "haddv4sf3"
24230   [(set (match_operand:V4SF 0 "register_operand" "=x")
24231         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24232                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24233                      UNSPEC_HADD))]
24234   "TARGET_SSE3"
24235   "haddps\t{%2, %0|%0, %2}"
24236   [(set_attr "type" "sseadd")
24237    (set_attr "mode" "V4SF")])
24238
24239 (define_insn "haddv2df3"
24240   [(set (match_operand:V2DF 0 "register_operand" "=x")
24241         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24242                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24243                      UNSPEC_HADD))]
24244   "TARGET_SSE3"
24245   "haddpd\t{%2, %0|%0, %2}"
24246   [(set_attr "type" "sseadd")
24247    (set_attr "mode" "V2DF")])
24248
24249 (define_insn "hsubv4sf3"
24250   [(set (match_operand:V4SF 0 "register_operand" "=x")
24251         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24252                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24253                      UNSPEC_HSUB))]
24254   "TARGET_SSE3"
24255   "hsubps\t{%2, %0|%0, %2}"
24256   [(set_attr "type" "sseadd")
24257    (set_attr "mode" "V4SF")])
24258
24259 (define_insn "hsubv2df3"
24260   [(set (match_operand:V2DF 0 "register_operand" "=x")
24261         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24262                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24263                      UNSPEC_HSUB))]
24264   "TARGET_SSE3"
24265   "hsubpd\t{%2, %0|%0, %2}"
24266   [(set_attr "type" "sseadd")
24267    (set_attr "mode" "V2DF")])
24268
24269 (define_insn "movshdup"
24270   [(set (match_operand:V4SF 0 "register_operand" "=x")
24271         (unspec:V4SF
24272          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
24273   "TARGET_SSE3"
24274   "movshdup\t{%1, %0|%0, %1}"
24275   [(set_attr "type" "sse")
24276    (set_attr "mode" "V4SF")])
24277
24278 (define_insn "movsldup"
24279   [(set (match_operand:V4SF 0 "register_operand" "=x")
24280         (unspec:V4SF
24281          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
24282   "TARGET_SSE3"
24283   "movsldup\t{%1, %0|%0, %1}"
24284   [(set_attr "type" "sse")
24285    (set_attr "mode" "V4SF")])
24286
24287 (define_insn "lddqu"
24288   [(set (match_operand:V16QI 0 "register_operand" "=x")
24289         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
24290                        UNSPEC_LDQQU))]
24291   "TARGET_SSE3"
24292   "lddqu\t{%1, %0|%0, %1}"
24293   [(set_attr "type" "ssecvt")
24294    (set_attr "mode" "TI")])
24295
24296 (define_insn "loadddup"
24297   [(set (match_operand:V2DF 0 "register_operand" "=x")
24298         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
24299   "TARGET_SSE3"
24300   "movddup\t{%1, %0|%0, %1}"
24301   [(set_attr "type" "ssecvt")
24302    (set_attr "mode" "DF")])
24303
24304 (define_insn "movddup"
24305   [(set (match_operand:V2DF 0 "register_operand" "=x")
24306         (vec_duplicate:V2DF
24307          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
24308                         (parallel [(const_int 0)]))))]
24309   "TARGET_SSE3"
24310   "movddup\t{%1, %0|%0, %1}"
24311   [(set_attr "type" "ssecvt")
24312    (set_attr "mode" "DF")])