OSDN Git Service

2004-08-10 H.J. Lu <hongjiu.lu@intel.com>
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1
2 ;; GCC machine description for IA-32 and x86-64.
3 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
4 ;; 2001, 2002, 2003, 2004
5 ;; Free Software Foundation, Inc.
6 ;; Mostly by William Schelter.
7 ;; x86_64 support added by Jan Hubicka
8 ;;
9 ;; This file is part of GCC.
10 ;;
11 ;; GCC is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; any later version.
15 ;;
16 ;; GCC is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;; GNU General Public License for more details.
20 ;;
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GCC; see the file COPYING.  If not, write to
23 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.  */
25 ;;
26 ;; The original PO technology requires these to be ordered by speed,
27 ;; so that assigner will pick the fastest.
28 ;;
29 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;;
31 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
32 ;; constraint letters.
33 ;;
34 ;; The special asm out single letter directives following a '%' are:
35 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;;     operands[1].
37 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
38 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
39 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
40 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
41 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
42 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
43 ;; 'J' Print the appropriate jump operand.
44 ;;
45 ;; 'b' Print the QImode name of the register for the indicated operand.
46 ;;     %b0 would print %al if operands[0] is reg 0.
47 ;; 'w' Likewise, print the HImode name of the register.
48 ;; 'k' Likewise, print the SImode name of the register.
49 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
50 ;; 'y' Print "st(0)" instead of "st" as a register.
51
52 ;; UNSPEC usage:
53
54 (define_constants
55   [; Relocation specifiers
56    (UNSPEC_GOT                  0)
57    (UNSPEC_GOTOFF               1)
58    (UNSPEC_GOTPCREL             2)
59    (UNSPEC_GOTTPOFF             3)
60    (UNSPEC_TPOFF                4)
61    (UNSPEC_NTPOFF               5)
62    (UNSPEC_DTPOFF               6)
63    (UNSPEC_GOTNTPOFF            7)
64    (UNSPEC_INDNTPOFF            8)
65
66    ; Prologue support
67    (UNSPEC_STACK_ALLOC          11)
68    (UNSPEC_SET_GOT              12)
69    (UNSPEC_SSE_PROLOGUE_SAVE    13)
70
71    ; TLS support
72    (UNSPEC_TP                   15)
73    (UNSPEC_TLS_GD               16)
74    (UNSPEC_TLS_LD_BASE          17)
75
76    ; Other random patterns
77    (UNSPEC_SCAS                 20)
78    (UNSPEC_SIN                  21)
79    (UNSPEC_COS                  22)
80    (UNSPEC_FNSTSW               24)
81    (UNSPEC_SAHF                 25)
82    (UNSPEC_FSTCW                26)
83    (UNSPEC_ADD_CARRY            27)
84    (UNSPEC_FLDCW                28)
85
86    ; For SSE/MMX support:
87    (UNSPEC_FIX                  30)
88    (UNSPEC_MASKMOV              32)
89    (UNSPEC_MOVMSK               33)
90    (UNSPEC_MOVNT                34)
91    (UNSPEC_MOVA                 38)
92    (UNSPEC_MOVU                 39)
93    (UNSPEC_SHUFFLE              41)
94    (UNSPEC_RCP                  42)
95    (UNSPEC_RSQRT                43)
96    (UNSPEC_SFENCE               44)
97    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
98    (UNSPEC_PAVGUSB              49)
99    (UNSPEC_PFRCP                50)
100    (UNSPEC_PFRCPIT1             51)
101    (UNSPEC_PFRCPIT2             52)
102    (UNSPEC_PFRSQRT              53)
103    (UNSPEC_PFRSQIT1             54)
104    (UNSPEC_PSHUFLW              55)
105    (UNSPEC_PSHUFHW              56)
106    (UNSPEC_MFENCE               59)
107    (UNSPEC_LFENCE               60)
108    (UNSPEC_PSADBW               61)
109    (UNSPEC_ADDSUB               71)
110    (UNSPEC_HADD                 72)
111    (UNSPEC_HSUB                 73)
112    (UNSPEC_MOVSHDUP             74)
113    (UNSPEC_MOVSLDUP             75)
114    (UNSPEC_LDQQU                76)
115    (UNSPEC_MOVDDUP              77)
116
117    ; x87 Floating point
118    (UNSPEC_FPATAN               65)
119    (UNSPEC_FYL2X                66)
120    (UNSPEC_FYL2XP1              67)
121    (UNSPEC_FRNDINT              68)
122    (UNSPEC_F2XM1                69)
123
124    ; x87 Double output FP
125    (UNSPEC_SINCOS_COS           80)
126    (UNSPEC_SINCOS_SIN           81)
127    (UNSPEC_TAN_ONE              82)
128    (UNSPEC_TAN_TAN              83)
129    (UNSPEC_XTRACT_FRACT         84)
130    (UNSPEC_XTRACT_EXP           85)
131    (UNSPEC_FSCALE_FRACT         86)
132    (UNSPEC_FSCALE_EXP           87)
133    (UNSPEC_FPREM_F              88)
134    (UNSPEC_FPREM_U              89)
135    (UNSPEC_FPREM1_F             90)
136    (UNSPEC_FPREM1_U             91)
137
138    ; REP instruction
139    (UNSPEC_REP                  75)
140
141    (UNSPEC_EH_RETURN            76)
142   ])
143
144 (define_constants
145   [(UNSPECV_BLOCKAGE            0)
146    (UNSPECV_STACK_PROBE         10)
147    (UNSPECV_EMMS                31)
148    (UNSPECV_LDMXCSR             37)
149    (UNSPECV_STMXCSR             40)
150    (UNSPECV_FEMMS               46)
151    (UNSPECV_CLFLUSH             57)
152    (UNSPECV_ALIGN               68)
153    (UNSPECV_MONITOR             69)
154    (UNSPECV_MWAIT               70)
155   ])
156
157 ;; Registers by name.
158 (define_constants
159   [(BP_REG                       6)
160    (SP_REG                       7)
161    (FLAGS_REG                   17)
162    (FPSR_REG                    18)
163    (DIRFLAG_REG                 19)
164   ])
165
166 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
167 ;; from i386.c.
168
169 ;; In C guard expressions, put expressions which may be compile-time
170 ;; constants first.  This allows for better optimization.  For
171 ;; example, write "TARGET_64BIT && reload_completed", not
172 ;; "reload_completed && TARGET_64BIT".
173
174 \f
175 ;; Processor type.  This attribute must exactly match the processor_type
176 ;; enumeration in i386.h.
177 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
178   (const (symbol_ref "ix86_tune")))
179
180 ;; A basic instruction type.  Refinements due to arguments to be
181 ;; provided in other attributes.
182 (define_attr "type"
183   "other,multi,
184    alu,alu1,negnot,imov,imovx,lea,
185    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
186    icmp,test,ibr,setcc,icmov,
187    push,pop,call,callv,leave,
188    str,cld,
189    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
190    sselog,sseiadd,sseishft,sseimul,
191    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
192    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
193   (const_string "other"))
194
195 ;; Main data type used by the insn
196 (define_attr "mode"
197   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
198   (const_string "unknown"))
199
200 ;; The CPU unit operations uses.
201 (define_attr "unit" "integer,i387,sse,mmx,unknown"
202   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
203            (const_string "i387")
204          (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
205                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
206            (const_string "sse")
207          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
208            (const_string "mmx")
209          (eq_attr "type" "other")
210            (const_string "unknown")]
211          (const_string "integer")))
212
213 ;; The (bounding maximum) length of an instruction immediate.
214 (define_attr "length_immediate" ""
215   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
216            (const_int 0)
217          (eq_attr "unit" "i387,sse,mmx")
218            (const_int 0)
219          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
220                           imul,icmp,push,pop")
221            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
222          (eq_attr "type" "imov,test")
223            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
224          (eq_attr "type" "call")
225            (if_then_else (match_operand 0 "constant_call_address_operand" "")
226              (const_int 4)
227              (const_int 0))
228          (eq_attr "type" "callv")
229            (if_then_else (match_operand 1 "constant_call_address_operand" "")
230              (const_int 4)
231              (const_int 0))
232          ;; We don't know the size before shorten_branches.  Expect
233          ;; the instruction to fit for better scheduling.
234          (eq_attr "type" "ibr")
235            (const_int 1)
236          ]
237          (symbol_ref "/* Update immediate_length and other attributes! */
238                       abort(),1")))
239
240 ;; The (bounding maximum) length of an instruction address.
241 (define_attr "length_address" ""
242   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
243            (const_int 0)
244          (and (eq_attr "type" "call")
245               (match_operand 0 "constant_call_address_operand" ""))
246              (const_int 0)
247          (and (eq_attr "type" "callv")
248               (match_operand 1 "constant_call_address_operand" ""))
249              (const_int 0)
250          ]
251          (symbol_ref "ix86_attr_length_address_default (insn)")))
252
253 ;; Set when length prefix is used.
254 (define_attr "prefix_data16" ""
255   (if_then_else (ior (eq_attr "mode" "HI")
256                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
257     (const_int 1)
258     (const_int 0)))
259
260 ;; Set when string REP prefix is used.
261 (define_attr "prefix_rep" "" 
262   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
263     (const_int 1)
264     (const_int 0)))
265
266 ;; Set when 0f opcode prefix is used.
267 (define_attr "prefix_0f" ""
268   (if_then_else 
269     (ior (eq_attr "type" "imovx,setcc,icmov")
270          (eq_attr "unit" "sse,mmx"))
271     (const_int 1)
272     (const_int 0)))
273
274 ;; Set when REX opcode prefix is used.
275 (define_attr "prefix_rex" ""
276   (cond [(and (eq_attr "mode" "DI")
277               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
278            (const_int 1)
279          (and (eq_attr "mode" "QI")
280               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
281                   (const_int 0)))
282            (const_int 1)
283          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
284              (const_int 0))
285            (const_int 1)
286         ]
287         (const_int 0)))
288
289 ;; Set when modrm byte is used.
290 (define_attr "modrm" ""
291   (cond [(eq_attr "type" "str,cld,leave")
292            (const_int 0)
293          (eq_attr "unit" "i387")
294            (const_int 0)
295          (and (eq_attr "type" "incdec")
296               (ior (match_operand:SI 1 "register_operand" "")
297                    (match_operand:HI 1 "register_operand" "")))
298            (const_int 0)
299          (and (eq_attr "type" "push")
300               (not (match_operand 1 "memory_operand" "")))
301            (const_int 0)
302          (and (eq_attr "type" "pop")
303               (not (match_operand 0 "memory_operand" "")))
304            (const_int 0)
305          (and (eq_attr "type" "imov")
306               (and (match_operand 0 "register_operand" "")
307                    (match_operand 1 "immediate_operand" "")))
308            (const_int 0)
309          (and (eq_attr "type" "call")
310               (match_operand 0 "constant_call_address_operand" ""))
311              (const_int 0)
312          (and (eq_attr "type" "callv")
313               (match_operand 1 "constant_call_address_operand" ""))
314              (const_int 0)
315          ]
316          (const_int 1)))
317
318 ;; The (bounding maximum) length of an instruction in bytes.
319 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence.  Later we may want
320 ;; to split it and compute proper length as for other insns.
321 (define_attr "length" ""
322   (cond [(eq_attr "type" "other,multi,fistp")
323            (const_int 16)
324          (eq_attr "type" "fcmp")
325            (const_int 4)
326          (eq_attr "unit" "i387")
327            (plus (const_int 2)
328                  (plus (attr "prefix_data16")
329                        (attr "length_address")))]
330          (plus (plus (attr "modrm")
331                      (plus (attr "prefix_0f")
332                            (plus (attr "prefix_rex")
333                                  (const_int 1))))
334                (plus (attr "prefix_rep")
335                      (plus (attr "prefix_data16")
336                            (plus (attr "length_immediate")
337                                  (attr "length_address")))))))
338
339 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
340 ;; `store' if there is a simple memory reference therein, or `unknown'
341 ;; if the instruction is complex.
342
343 (define_attr "memory" "none,load,store,both,unknown"
344   (cond [(eq_attr "type" "other,multi,str")
345            (const_string "unknown")
346          (eq_attr "type" "lea,fcmov,fpspc,cld")
347            (const_string "none")
348          (eq_attr "type" "fistp,leave")
349            (const_string "both")
350          (eq_attr "type" "push")
351            (if_then_else (match_operand 1 "memory_operand" "")
352              (const_string "both")
353              (const_string "store"))
354          (eq_attr "type" "pop")
355            (if_then_else (match_operand 0 "memory_operand" "")
356              (const_string "both")
357              (const_string "load"))
358          (eq_attr "type" "setcc")
359            (if_then_else (match_operand 0 "memory_operand" "")
360              (const_string "store")
361              (const_string "none"))
362          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
363            (if_then_else (ior (match_operand 0 "memory_operand" "")
364                               (match_operand 1 "memory_operand" ""))
365              (const_string "load")
366              (const_string "none"))
367          (eq_attr "type" "ibr")
368            (if_then_else (match_operand 0 "memory_operand" "")
369              (const_string "load")
370              (const_string "none"))
371          (eq_attr "type" "call")
372            (if_then_else (match_operand 0 "constant_call_address_operand" "")
373              (const_string "none")
374              (const_string "load"))
375          (eq_attr "type" "callv")
376            (if_then_else (match_operand 1 "constant_call_address_operand" "")
377              (const_string "none")
378              (const_string "load"))
379          (and (eq_attr "type" "alu1,negnot,ishift1")
380               (match_operand 1 "memory_operand" ""))
381            (const_string "both")
382          (and (match_operand 0 "memory_operand" "")
383               (match_operand 1 "memory_operand" ""))
384            (const_string "both")
385          (match_operand 0 "memory_operand" "")
386            (const_string "store")
387          (match_operand 1 "memory_operand" "")
388            (const_string "load")
389          (and (eq_attr "type"
390                  "!alu1,negnot,ishift1,
391                    imov,imovx,icmp,test,
392                    fmov,fcmp,fsgn,
393                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
394                    mmx,mmxmov,mmxcmp,mmxcvt")
395               (match_operand 2 "memory_operand" ""))
396            (const_string "load")
397          (and (eq_attr "type" "icmov")
398               (match_operand 3 "memory_operand" ""))
399            (const_string "load")
400         ]
401         (const_string "none")))
402
403 ;; Indicates if an instruction has both an immediate and a displacement.
404
405 (define_attr "imm_disp" "false,true,unknown"
406   (cond [(eq_attr "type" "other,multi")
407            (const_string "unknown")
408          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
409               (and (match_operand 0 "memory_displacement_operand" "")
410                    (match_operand 1 "immediate_operand" "")))
411            (const_string "true")
412          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
413               (and (match_operand 0 "memory_displacement_operand" "")
414                    (match_operand 2 "immediate_operand" "")))
415            (const_string "true")
416         ]
417         (const_string "false")))
418
419 ;; Indicates if an FP operation has an integer source.
420
421 (define_attr "fp_int_src" "false,true"
422   (const_string "false"))
423
424 ;; Describe a user's asm statement.
425 (define_asm_attributes
426   [(set_attr "length" "128")
427    (set_attr "type" "multi")])
428 \f
429 (include "pentium.md")
430 (include "ppro.md")
431 (include "k6.md")
432 (include "athlon.md")
433 \f
434 ;; Compare instructions.
435
436 ;; All compare insns have expanders that save the operands away without
437 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
438 ;; after the cmp) will actually emit the cmpM.
439
440 (define_expand "cmpdi"
441   [(set (reg:CC FLAGS_REG)
442         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
443                     (match_operand:DI 1 "x86_64_general_operand" "")))]
444   ""
445 {
446   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
447     operands[0] = force_reg (DImode, operands[0]);
448   ix86_compare_op0 = operands[0];
449   ix86_compare_op1 = operands[1];
450   DONE;
451 })
452
453 (define_expand "cmpsi"
454   [(set (reg:CC FLAGS_REG)
455         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
456                     (match_operand:SI 1 "general_operand" "")))]
457   ""
458 {
459   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
460     operands[0] = force_reg (SImode, operands[0]);
461   ix86_compare_op0 = operands[0];
462   ix86_compare_op1 = operands[1];
463   DONE;
464 })
465
466 (define_expand "cmphi"
467   [(set (reg:CC FLAGS_REG)
468         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
469                     (match_operand:HI 1 "general_operand" "")))]
470   ""
471 {
472   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
473     operands[0] = force_reg (HImode, operands[0]);
474   ix86_compare_op0 = operands[0];
475   ix86_compare_op1 = operands[1];
476   DONE;
477 })
478
479 (define_expand "cmpqi"
480   [(set (reg:CC FLAGS_REG)
481         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
482                     (match_operand:QI 1 "general_operand" "")))]
483   "TARGET_QIMODE_MATH"
484 {
485   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
486     operands[0] = force_reg (QImode, operands[0]);
487   ix86_compare_op0 = operands[0];
488   ix86_compare_op1 = operands[1];
489   DONE;
490 })
491
492 (define_insn "cmpdi_ccno_1_rex64"
493   [(set (reg 17)
494         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
495                  (match_operand:DI 1 "const0_operand" "n,n")))]
496   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
497   "@
498    test{q}\t{%0, %0|%0, %0}
499    cmp{q}\t{%1, %0|%0, %1}"
500   [(set_attr "type" "test,icmp")
501    (set_attr "length_immediate" "0,1")
502    (set_attr "mode" "DI")])
503
504 (define_insn "*cmpdi_minus_1_rex64"
505   [(set (reg 17)
506         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
507                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
508                  (const_int 0)))]
509   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
510   "cmp{q}\t{%1, %0|%0, %1}"
511   [(set_attr "type" "icmp")
512    (set_attr "mode" "DI")])
513
514 (define_expand "cmpdi_1_rex64"
515   [(set (reg:CC FLAGS_REG)
516         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
517                     (match_operand:DI 1 "general_operand" "")))]
518   "TARGET_64BIT"
519   "")
520
521 (define_insn "cmpdi_1_insn_rex64"
522   [(set (reg 17)
523         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
524                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
525   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
526   "cmp{q}\t{%1, %0|%0, %1}"
527   [(set_attr "type" "icmp")
528    (set_attr "mode" "DI")])
529
530
531 (define_insn "*cmpsi_ccno_1"
532   [(set (reg 17)
533         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
534                  (match_operand:SI 1 "const0_operand" "n,n")))]
535   "ix86_match_ccmode (insn, CCNOmode)"
536   "@
537    test{l}\t{%0, %0|%0, %0}
538    cmp{l}\t{%1, %0|%0, %1}"
539   [(set_attr "type" "test,icmp")
540    (set_attr "length_immediate" "0,1")
541    (set_attr "mode" "SI")])
542
543 (define_insn "*cmpsi_minus_1"
544   [(set (reg 17)
545         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
546                            (match_operand:SI 1 "general_operand" "ri,mr"))
547                  (const_int 0)))]
548   "ix86_match_ccmode (insn, CCGOCmode)"
549   "cmp{l}\t{%1, %0|%0, %1}"
550   [(set_attr "type" "icmp")
551    (set_attr "mode" "SI")])
552
553 (define_expand "cmpsi_1"
554   [(set (reg:CC FLAGS_REG)
555         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
556                     (match_operand:SI 1 "general_operand" "ri,mr")))]
557   ""
558   "")
559
560 (define_insn "*cmpsi_1_insn"
561   [(set (reg 17)
562         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
563                  (match_operand:SI 1 "general_operand" "ri,mr")))]
564   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
565     && ix86_match_ccmode (insn, CCmode)"
566   "cmp{l}\t{%1, %0|%0, %1}"
567   [(set_attr "type" "icmp")
568    (set_attr "mode" "SI")])
569
570 (define_insn "*cmphi_ccno_1"
571   [(set (reg 17)
572         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
573                  (match_operand:HI 1 "const0_operand" "n,n")))]
574   "ix86_match_ccmode (insn, CCNOmode)"
575   "@
576    test{w}\t{%0, %0|%0, %0}
577    cmp{w}\t{%1, %0|%0, %1}"
578   [(set_attr "type" "test,icmp")
579    (set_attr "length_immediate" "0,1")
580    (set_attr "mode" "HI")])
581
582 (define_insn "*cmphi_minus_1"
583   [(set (reg 17)
584         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
585                            (match_operand:HI 1 "general_operand" "ri,mr"))
586                  (const_int 0)))]
587   "ix86_match_ccmode (insn, CCGOCmode)"
588   "cmp{w}\t{%1, %0|%0, %1}"
589   [(set_attr "type" "icmp")
590    (set_attr "mode" "HI")])
591
592 (define_insn "*cmphi_1"
593   [(set (reg 17)
594         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
595                  (match_operand:HI 1 "general_operand" "ri,mr")))]
596   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
597    && ix86_match_ccmode (insn, CCmode)"
598   "cmp{w}\t{%1, %0|%0, %1}"
599   [(set_attr "type" "icmp")
600    (set_attr "mode" "HI")])
601
602 (define_insn "*cmpqi_ccno_1"
603   [(set (reg 17)
604         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
605                  (match_operand:QI 1 "const0_operand" "n,n")))]
606   "ix86_match_ccmode (insn, CCNOmode)"
607   "@
608    test{b}\t{%0, %0|%0, %0}
609    cmp{b}\t{$0, %0|%0, 0}"
610   [(set_attr "type" "test,icmp")
611    (set_attr "length_immediate" "0,1")
612    (set_attr "mode" "QI")])
613
614 (define_insn "*cmpqi_1"
615   [(set (reg 17)
616         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
617                  (match_operand:QI 1 "general_operand" "qi,mq")))]
618   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
619     && ix86_match_ccmode (insn, CCmode)"
620   "cmp{b}\t{%1, %0|%0, %1}"
621   [(set_attr "type" "icmp")
622    (set_attr "mode" "QI")])
623
624 (define_insn "*cmpqi_minus_1"
625   [(set (reg 17)
626         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
627                            (match_operand:QI 1 "general_operand" "qi,mq"))
628                  (const_int 0)))]
629   "ix86_match_ccmode (insn, CCGOCmode)"
630   "cmp{b}\t{%1, %0|%0, %1}"
631   [(set_attr "type" "icmp")
632    (set_attr "mode" "QI")])
633
634 (define_insn "*cmpqi_ext_1"
635   [(set (reg 17)
636         (compare
637           (match_operand:QI 0 "general_operand" "Qm")
638           (subreg:QI
639             (zero_extract:SI
640               (match_operand 1 "ext_register_operand" "Q")
641               (const_int 8)
642               (const_int 8)) 0)))]
643   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
644   "cmp{b}\t{%h1, %0|%0, %h1}"
645   [(set_attr "type" "icmp")
646    (set_attr "mode" "QI")])
647
648 (define_insn "*cmpqi_ext_1_rex64"
649   [(set (reg 17)
650         (compare
651           (match_operand:QI 0 "register_operand" "Q")
652           (subreg:QI
653             (zero_extract:SI
654               (match_operand 1 "ext_register_operand" "Q")
655               (const_int 8)
656               (const_int 8)) 0)))]
657   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
658   "cmp{b}\t{%h1, %0|%0, %h1}"
659   [(set_attr "type" "icmp")
660    (set_attr "mode" "QI")])
661
662 (define_insn "*cmpqi_ext_2"
663   [(set (reg 17)
664         (compare
665           (subreg:QI
666             (zero_extract:SI
667               (match_operand 0 "ext_register_operand" "Q")
668               (const_int 8)
669               (const_int 8)) 0)
670           (match_operand:QI 1 "const0_operand" "n")))]
671   "ix86_match_ccmode (insn, CCNOmode)"
672   "test{b}\t%h0, %h0"
673   [(set_attr "type" "test")
674    (set_attr "length_immediate" "0")
675    (set_attr "mode" "QI")])
676
677 (define_expand "cmpqi_ext_3"
678   [(set (reg:CC FLAGS_REG)
679         (compare:CC
680           (subreg:QI
681             (zero_extract:SI
682               (match_operand 0 "ext_register_operand" "")
683               (const_int 8)
684               (const_int 8)) 0)
685           (match_operand:QI 1 "general_operand" "")))]
686   ""
687   "")
688
689 (define_insn "cmpqi_ext_3_insn"
690   [(set (reg 17)
691         (compare
692           (subreg:QI
693             (zero_extract:SI
694               (match_operand 0 "ext_register_operand" "Q")
695               (const_int 8)
696               (const_int 8)) 0)
697           (match_operand:QI 1 "general_operand" "Qmn")))]
698   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
699   "cmp{b}\t{%1, %h0|%h0, %1}"
700   [(set_attr "type" "icmp")
701    (set_attr "mode" "QI")])
702
703 (define_insn "cmpqi_ext_3_insn_rex64"
704   [(set (reg 17)
705         (compare
706           (subreg:QI
707             (zero_extract:SI
708               (match_operand 0 "ext_register_operand" "Q")
709               (const_int 8)
710               (const_int 8)) 0)
711           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
712   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
713   "cmp{b}\t{%1, %h0|%h0, %1}"
714   [(set_attr "type" "icmp")
715    (set_attr "mode" "QI")])
716
717 (define_insn "*cmpqi_ext_4"
718   [(set (reg 17)
719         (compare
720           (subreg:QI
721             (zero_extract:SI
722               (match_operand 0 "ext_register_operand" "Q")
723               (const_int 8)
724               (const_int 8)) 0)
725           (subreg:QI
726             (zero_extract:SI
727               (match_operand 1 "ext_register_operand" "Q")
728               (const_int 8)
729               (const_int 8)) 0)))]
730   "ix86_match_ccmode (insn, CCmode)"
731   "cmp{b}\t{%h1, %h0|%h0, %h1}"
732   [(set_attr "type" "icmp")
733    (set_attr "mode" "QI")])
734
735 ;; These implement float point compares.
736 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
737 ;; which would allow mix and match FP modes on the compares.  Which is what
738 ;; the old patterns did, but with many more of them.
739
740 (define_expand "cmpxf"
741   [(set (reg:CC FLAGS_REG)
742         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
743                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
744   "TARGET_80387"
745 {
746   ix86_compare_op0 = operands[0];
747   ix86_compare_op1 = operands[1];
748   DONE;
749 })
750
751 (define_expand "cmpdf"
752   [(set (reg:CC FLAGS_REG)
753         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
754                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
755   "TARGET_80387 || TARGET_SSE2"
756 {
757   ix86_compare_op0 = operands[0];
758   ix86_compare_op1 = operands[1];
759   DONE;
760 })
761
762 (define_expand "cmpsf"
763   [(set (reg:CC FLAGS_REG)
764         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
765                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
766   "TARGET_80387 || TARGET_SSE"
767 {
768   ix86_compare_op0 = operands[0];
769   ix86_compare_op1 = operands[1];
770   DONE;
771 })
772
773 ;; FP compares, step 1:
774 ;; Set the FP condition codes.
775 ;;
776 ;; CCFPmode     compare with exceptions
777 ;; CCFPUmode    compare with no exceptions
778
779 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
780 ;; and that fp moves clobber the condition codes, and that there is
781 ;; currently no way to describe this fact to reg-stack.  So there are
782 ;; no splitters yet for this.
783
784 ;; %%% YIKES!  This scheme does not retain a strong connection between 
785 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
786 ;; work!  Only allow tos/mem with tos in op 0.
787 ;;
788 ;; Hmm, of course, this is what the actual _hardware_ does.  Perhaps
789 ;; things aren't as bad as they sound...
790
791 (define_insn "*cmpfp_0"
792   [(set (match_operand:HI 0 "register_operand" "=a")
793         (unspec:HI
794           [(compare:CCFP (match_operand 1 "register_operand" "f")
795                          (match_operand 2 "const0_operand" "X"))]
796           UNSPEC_FNSTSW))]
797   "TARGET_80387
798    && FLOAT_MODE_P (GET_MODE (operands[1]))
799    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
800 {
801   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
802     return "ftst\;fnstsw\t%0\;fstp\t%y0";
803   else
804     return "ftst\;fnstsw\t%0";
805 }
806   [(set_attr "type" "multi")
807    (set (attr "mode")
808      (cond [(match_operand:SF 1 "" "")
809               (const_string "SF")
810             (match_operand:DF 1 "" "")
811               (const_string "DF")
812            ]
813            (const_string "XF")))])
814
815 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
816 ;; used to manage the reg stack popping would not be preserved.
817
818 (define_insn "*cmpfp_2_sf"
819   [(set (reg:CCFP FPSR_REG)
820         (compare:CCFP
821           (match_operand:SF 0 "register_operand" "f")
822           (match_operand:SF 1 "nonimmediate_operand" "fm")))]
823   "TARGET_80387"
824   "* return output_fp_compare (insn, operands, 0, 0);"
825   [(set_attr "type" "fcmp")
826    (set_attr "mode" "SF")])
827
828 (define_insn "*cmpfp_2_sf_1"
829   [(set (match_operand:HI 0 "register_operand" "=a")
830         (unspec:HI
831           [(compare:CCFP
832              (match_operand:SF 1 "register_operand" "f")
833              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
834           UNSPEC_FNSTSW))]
835   "TARGET_80387"
836   "* return output_fp_compare (insn, operands, 2, 0);"
837   [(set_attr "type" "fcmp")
838    (set_attr "mode" "SF")])
839
840 (define_insn "*cmpfp_2_df"
841   [(set (reg:CCFP FPSR_REG)
842         (compare:CCFP
843           (match_operand:DF 0 "register_operand" "f")
844           (match_operand:DF 1 "nonimmediate_operand" "fm")))]
845   "TARGET_80387"
846   "* return output_fp_compare (insn, operands, 0, 0);"
847   [(set_attr "type" "fcmp")
848    (set_attr "mode" "DF")])
849
850 (define_insn "*cmpfp_2_df_1"
851   [(set (match_operand:HI 0 "register_operand" "=a")
852         (unspec:HI
853           [(compare:CCFP
854              (match_operand:DF 1 "register_operand" "f")
855              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
856           UNSPEC_FNSTSW))]
857   "TARGET_80387"
858   "* return output_fp_compare (insn, operands, 2, 0);"
859   [(set_attr "type" "multi")
860    (set_attr "mode" "DF")])
861
862 (define_insn "*cmpfp_2_xf"
863   [(set (reg:CCFP FPSR_REG)
864         (compare:CCFP
865           (match_operand:XF 0 "register_operand" "f")
866           (match_operand:XF 1 "register_operand" "f")))]
867   "TARGET_80387"
868   "* return output_fp_compare (insn, operands, 0, 0);"
869   [(set_attr "type" "fcmp")
870    (set_attr "mode" "XF")])
871
872 (define_insn "*cmpfp_2_xf_1"
873   [(set (match_operand:HI 0 "register_operand" "=a")
874         (unspec:HI
875           [(compare:CCFP
876              (match_operand:XF 1 "register_operand" "f")
877              (match_operand:XF 2 "register_operand" "f"))]
878           UNSPEC_FNSTSW))]
879   "TARGET_80387"
880   "* return output_fp_compare (insn, operands, 2, 0);"
881   [(set_attr "type" "multi")
882    (set_attr "mode" "XF")])
883
884 (define_insn "*cmpfp_2u"
885   [(set (reg:CCFPU FPSR_REG)
886         (compare:CCFPU
887           (match_operand 0 "register_operand" "f")
888           (match_operand 1 "register_operand" "f")))]
889   "TARGET_80387
890    && FLOAT_MODE_P (GET_MODE (operands[0]))
891    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
892   "* return output_fp_compare (insn, operands, 0, 1);"
893   [(set_attr "type" "fcmp")
894    (set (attr "mode")
895      (cond [(match_operand:SF 1 "" "")
896               (const_string "SF")
897             (match_operand:DF 1 "" "")
898               (const_string "DF")
899            ]
900            (const_string "XF")))])
901
902 (define_insn "*cmpfp_2u_1"
903   [(set (match_operand:HI 0 "register_operand" "=a")
904         (unspec:HI
905           [(compare:CCFPU
906              (match_operand 1 "register_operand" "f")
907              (match_operand 2 "register_operand" "f"))]
908           UNSPEC_FNSTSW))]
909   "TARGET_80387
910    && FLOAT_MODE_P (GET_MODE (operands[1]))
911    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
912   "* return output_fp_compare (insn, operands, 2, 1);"
913   [(set_attr "type" "multi")
914    (set (attr "mode")
915      (cond [(match_operand:SF 1 "" "")
916               (const_string "SF")
917             (match_operand:DF 1 "" "")
918               (const_string "DF")
919            ]
920            (const_string "XF")))])
921
922 ;; Patterns to match the SImode-in-memory ficom instructions.
923 ;;
924 ;; %%% Play games with accepting gp registers, as otherwise we have to
925 ;; force them to memory during rtl generation, which is no good.  We
926 ;; can get rid of this once we teach reload to do memory input reloads 
927 ;; via pushes.
928
929 (define_insn "*ficom_1"
930   [(set (reg:CCFP FPSR_REG)
931         (compare:CCFP
932           (match_operand 0 "register_operand" "f,f")
933           (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
934   "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
935    && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
936   "#")
937
938 ;; Split the not-really-implemented gp register case into a
939 ;; push-op-pop sequence.
940 ;;
941 ;; %%% This is most efficient, but am I gonna get in trouble
942 ;; for separating cc0_setter and cc0_user?
943
944 (define_split
945   [(set (reg:CCFP FPSR_REG)
946         (compare:CCFP
947           (match_operand:SF 0 "register_operand" "")
948           (float (match_operand:SI 1 "register_operand" ""))))]
949   "0 && TARGET_80387 && reload_completed"
950   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 1))
951    (set (reg:CCFP FPSR_REG) (compare:CCFP (match_dup 0) (match_dup 2)))
952    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
953               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
954   "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
955    operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
956
957 ;; FP compares, step 2
958 ;; Move the fpsw to ax.
959
960 (define_insn "x86_fnstsw_1"
961   [(set (match_operand:HI 0 "register_operand" "=a")
962         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
963   "TARGET_80387"
964   "fnstsw\t%0"
965   [(set_attr "length" "2")
966    (set_attr "mode" "SI")
967    (set_attr "unit" "i387")])
968
969 ;; FP compares, step 3
970 ;; Get ax into flags, general case.
971
972 (define_insn "x86_sahf_1"
973   [(set (reg:CC FLAGS_REG)
974         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
975   "!TARGET_64BIT"
976   "sahf"
977   [(set_attr "length" "1")
978    (set_attr "athlon_decode" "vector")
979    (set_attr "mode" "SI")])
980
981 ;; Pentium Pro can do steps 1 through 3 in one go.
982
983 (define_insn "*cmpfp_i"
984   [(set (reg:CCFP FLAGS_REG)
985         (compare:CCFP (match_operand 0 "register_operand" "f")
986                       (match_operand 1 "register_operand" "f")))]
987   "TARGET_80387 && TARGET_CMOVE
988    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
989    && FLOAT_MODE_P (GET_MODE (operands[0]))
990    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
991   "* return output_fp_compare (insn, operands, 1, 0);"
992   [(set_attr "type" "fcmp")
993    (set (attr "mode")
994      (cond [(match_operand:SF 1 "" "")
995               (const_string "SF")
996             (match_operand:DF 1 "" "")
997               (const_string "DF")
998            ]
999            (const_string "XF")))
1000    (set_attr "athlon_decode" "vector")])
1001
1002 (define_insn "*cmpfp_i_sse"
1003   [(set (reg:CCFP FLAGS_REG)
1004         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1005                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1006   "TARGET_80387
1007    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1008    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1009   "* return output_fp_compare (insn, operands, 1, 0);"
1010   [(set_attr "type" "fcmp,ssecomi")
1011    (set (attr "mode")
1012      (if_then_else (match_operand:SF 1 "" "")
1013         (const_string "SF")
1014         (const_string "DF")))
1015    (set_attr "athlon_decode" "vector")])
1016
1017 (define_insn "*cmpfp_i_sse_only"
1018   [(set (reg:CCFP FLAGS_REG)
1019         (compare:CCFP (match_operand 0 "register_operand" "x")
1020                       (match_operand 1 "nonimmediate_operand" "xm")))]
1021   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1022    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1023   "* return output_fp_compare (insn, operands, 1, 0);"
1024   [(set_attr "type" "ssecomi")
1025    (set (attr "mode")
1026      (if_then_else (match_operand:SF 1 "" "")
1027         (const_string "SF")
1028         (const_string "DF")))
1029    (set_attr "athlon_decode" "vector")])
1030
1031 (define_insn "*cmpfp_iu"
1032   [(set (reg:CCFPU FLAGS_REG)
1033         (compare:CCFPU (match_operand 0 "register_operand" "f")
1034                        (match_operand 1 "register_operand" "f")))]
1035   "TARGET_80387 && TARGET_CMOVE
1036    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1037    && FLOAT_MODE_P (GET_MODE (operands[0]))
1038    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1039   "* return output_fp_compare (insn, operands, 1, 1);"
1040   [(set_attr "type" "fcmp")
1041    (set (attr "mode")
1042      (cond [(match_operand:SF 1 "" "")
1043               (const_string "SF")
1044             (match_operand:DF 1 "" "")
1045               (const_string "DF")
1046            ]
1047            (const_string "XF")))
1048    (set_attr "athlon_decode" "vector")])
1049
1050 (define_insn "*cmpfp_iu_sse"
1051   [(set (reg:CCFPU FLAGS_REG)
1052         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1053                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1054   "TARGET_80387
1055    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1056    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1057   "* return output_fp_compare (insn, operands, 1, 1);"
1058   [(set_attr "type" "fcmp,ssecomi")
1059    (set (attr "mode")
1060      (if_then_else (match_operand:SF 1 "" "")
1061         (const_string "SF")
1062         (const_string "DF")))
1063    (set_attr "athlon_decode" "vector")])
1064
1065 (define_insn "*cmpfp_iu_sse_only"
1066   [(set (reg:CCFPU FLAGS_REG)
1067         (compare:CCFPU (match_operand 0 "register_operand" "x")
1068                        (match_operand 1 "nonimmediate_operand" "xm")))]
1069   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1070    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1071   "* return output_fp_compare (insn, operands, 1, 1);"
1072   [(set_attr "type" "ssecomi")
1073    (set (attr "mode")
1074      (if_then_else (match_operand:SF 1 "" "")
1075         (const_string "SF")
1076         (const_string "DF")))
1077    (set_attr "athlon_decode" "vector")])
1078 \f
1079 ;; Move instructions.
1080
1081 ;; General case of fullword move.
1082
1083 (define_expand "movsi"
1084   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1085         (match_operand:SI 1 "general_operand" ""))]
1086   ""
1087   "ix86_expand_move (SImode, operands); DONE;")
1088
1089 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1090 ;; general_operand.
1091 ;;
1092 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1093 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1094 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1095 ;; targets without our curiosities, and it is just as easy to represent
1096 ;; this differently.
1097
1098 (define_insn "*pushsi2"
1099   [(set (match_operand:SI 0 "push_operand" "=<")
1100         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1101   "!TARGET_64BIT"
1102   "push{l}\t%1"
1103   [(set_attr "type" "push")
1104    (set_attr "mode" "SI")])
1105
1106 ;; For 64BIT abi we always round up to 8 bytes.
1107 (define_insn "*pushsi2_rex64"
1108   [(set (match_operand:SI 0 "push_operand" "=X")
1109         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1110   "TARGET_64BIT"
1111   "push{q}\t%q1"
1112   [(set_attr "type" "push")
1113    (set_attr "mode" "SI")])
1114
1115 (define_insn "*pushsi2_prologue"
1116   [(set (match_operand:SI 0 "push_operand" "=<")
1117         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1118    (clobber (mem:BLK (scratch)))]
1119   "!TARGET_64BIT"
1120   "push{l}\t%1"
1121   [(set_attr "type" "push")
1122    (set_attr "mode" "SI")])
1123
1124 (define_insn "*popsi1_epilogue"
1125   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1126         (mem:SI (reg:SI SP_REG)))
1127    (set (reg:SI SP_REG)
1128         (plus:SI (reg:SI SP_REG) (const_int 4)))
1129    (clobber (mem:BLK (scratch)))]
1130   "!TARGET_64BIT"
1131   "pop{l}\t%0"
1132   [(set_attr "type" "pop")
1133    (set_attr "mode" "SI")])
1134
1135 (define_insn "popsi1"
1136   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1137         (mem:SI (reg:SI SP_REG)))
1138    (set (reg:SI SP_REG)
1139         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1140   "!TARGET_64BIT"
1141   "pop{l}\t%0"
1142   [(set_attr "type" "pop")
1143    (set_attr "mode" "SI")])
1144
1145 (define_insn "*movsi_xor"
1146   [(set (match_operand:SI 0 "register_operand" "=r")
1147         (match_operand:SI 1 "const0_operand" "i"))
1148    (clobber (reg:CC FLAGS_REG))]
1149   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1150   "xor{l}\t{%0, %0|%0, %0}"
1151   [(set_attr "type" "alu1")
1152    (set_attr "mode" "SI")
1153    (set_attr "length_immediate" "0")])
1154  
1155 (define_insn "*movsi_or"
1156   [(set (match_operand:SI 0 "register_operand" "=r")
1157         (match_operand:SI 1 "immediate_operand" "i"))
1158    (clobber (reg:CC FLAGS_REG))]
1159   "reload_completed
1160    && operands[1] == constm1_rtx
1161    && (TARGET_PENTIUM || optimize_size)"
1162 {
1163   operands[1] = constm1_rtx;
1164   return "or{l}\t{%1, %0|%0, %1}";
1165 }
1166   [(set_attr "type" "alu1")
1167    (set_attr "mode" "SI")
1168    (set_attr "length_immediate" "1")])
1169
1170 (define_insn "*movsi_1"
1171   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1172         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1173   "(TARGET_INTER_UNIT_MOVES || optimize_size)
1174    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1175 {
1176   switch (get_attr_type (insn))
1177     {
1178     case TYPE_SSEMOV:
1179       if (get_attr_mode (insn) == MODE_TI)
1180         return "movdqa\t{%1, %0|%0, %1}";
1181       return "movd\t{%1, %0|%0, %1}";
1182
1183     case TYPE_MMXMOV:
1184       if (get_attr_mode (insn) == MODE_DI)
1185         return "movq\t{%1, %0|%0, %1}";
1186       return "movd\t{%1, %0|%0, %1}";
1187
1188     case TYPE_LEA:
1189       return "lea{l}\t{%1, %0|%0, %1}";
1190
1191     default:
1192       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1193         abort();
1194       return "mov{l}\t{%1, %0|%0, %1}";
1195     }
1196 }
1197   [(set (attr "type")
1198      (cond [(eq_attr "alternative" "2,3,4")
1199               (const_string "mmxmov")
1200             (eq_attr "alternative" "5,6,7")
1201               (const_string "ssemov")
1202             (and (ne (symbol_ref "flag_pic") (const_int 0))
1203                  (match_operand:SI 1 "symbolic_operand" ""))
1204               (const_string "lea")
1205            ]
1206            (const_string "imov")))
1207    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1208
1209 (define_insn "*movsi_1_nointernunit"
1210   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1211         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1212   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1213    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1214 {
1215   switch (get_attr_type (insn))
1216     {
1217     case TYPE_SSEMOV:
1218       if (get_attr_mode (insn) == MODE_TI)
1219         return "movdqa\t{%1, %0|%0, %1}";
1220       return "movd\t{%1, %0|%0, %1}";
1221
1222     case TYPE_MMXMOV:
1223       if (get_attr_mode (insn) == MODE_DI)
1224         return "movq\t{%1, %0|%0, %1}";
1225       return "movd\t{%1, %0|%0, %1}";
1226
1227     case TYPE_LEA:
1228       return "lea{l}\t{%1, %0|%0, %1}";
1229
1230     default:
1231       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1232         abort();
1233       return "mov{l}\t{%1, %0|%0, %1}";
1234     }
1235 }
1236   [(set (attr "type")
1237      (cond [(eq_attr "alternative" "2,3,4")
1238               (const_string "mmxmov")
1239             (eq_attr "alternative" "5,6,7")
1240               (const_string "ssemov")
1241             (and (ne (symbol_ref "flag_pic") (const_int 0))
1242                  (match_operand:SI 1 "symbolic_operand" ""))
1243               (const_string "lea")
1244            ]
1245            (const_string "imov")))
1246    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1247
1248 ;; Stores and loads of ax to arbitrary constant address.
1249 ;; We fake an second form of instruction to force reload to load address
1250 ;; into register when rax is not available
1251 (define_insn "*movabssi_1_rex64"
1252   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1253         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1254   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1255   "@
1256    movabs{l}\t{%1, %P0|%P0, %1}
1257    mov{l}\t{%1, %a0|%a0, %1}"
1258   [(set_attr "type" "imov")
1259    (set_attr "modrm" "0,*")
1260    (set_attr "length_address" "8,0")
1261    (set_attr "length_immediate" "0,*")
1262    (set_attr "memory" "store")
1263    (set_attr "mode" "SI")])
1264
1265 (define_insn "*movabssi_2_rex64"
1266   [(set (match_operand:SI 0 "register_operand" "=a,r")
1267         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1268   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1269   "@
1270    movabs{l}\t{%P1, %0|%0, %P1}
1271    mov{l}\t{%a1, %0|%0, %a1}"
1272   [(set_attr "type" "imov")
1273    (set_attr "modrm" "0,*")
1274    (set_attr "length_address" "8,0")
1275    (set_attr "length_immediate" "0")
1276    (set_attr "memory" "load")
1277    (set_attr "mode" "SI")])
1278
1279 (define_insn "*swapsi"
1280   [(set (match_operand:SI 0 "register_operand" "+r")
1281         (match_operand:SI 1 "register_operand" "+r"))
1282    (set (match_dup 1)
1283         (match_dup 0))]
1284   ""
1285   "xchg{l}\t%1, %0"
1286   [(set_attr "type" "imov")
1287    (set_attr "pent_pair" "np")
1288    (set_attr "athlon_decode" "vector")
1289    (set_attr "mode" "SI")
1290    (set_attr "modrm" "0")])
1291
1292 (define_expand "movhi"
1293   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1294         (match_operand:HI 1 "general_operand" ""))]
1295   ""
1296   "ix86_expand_move (HImode, operands); DONE;")
1297
1298 (define_insn "*pushhi2"
1299   [(set (match_operand:HI 0 "push_operand" "=<,<")
1300         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1301   "!TARGET_64BIT"
1302   "@
1303    push{w}\t{|WORD PTR }%1
1304    push{w}\t%1"
1305   [(set_attr "type" "push")
1306    (set_attr "mode" "HI")])
1307
1308 ;; For 64BIT abi we always round up to 8 bytes.
1309 (define_insn "*pushhi2_rex64"
1310   [(set (match_operand:HI 0 "push_operand" "=X")
1311         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1312   "TARGET_64BIT"
1313   "push{q}\t%q1"
1314   [(set_attr "type" "push")
1315    (set_attr "mode" "QI")])
1316
1317 (define_insn "*movhi_1"
1318   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1319         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1320   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1321 {
1322   switch (get_attr_type (insn))
1323     {
1324     case TYPE_IMOVX:
1325       /* movzwl is faster than movw on p2 due to partial word stalls,
1326          though not as fast as an aligned movl.  */
1327       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1328     default:
1329       if (get_attr_mode (insn) == MODE_SI)
1330         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1331       else
1332         return "mov{w}\t{%1, %0|%0, %1}";
1333     }
1334 }
1335   [(set (attr "type")
1336      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1337               (const_string "imov")
1338             (and (eq_attr "alternative" "0")
1339                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1340                           (const_int 0))
1341                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1342                           (const_int 0))))
1343               (const_string "imov")
1344             (and (eq_attr "alternative" "1,2")
1345                  (match_operand:HI 1 "aligned_operand" ""))
1346               (const_string "imov")
1347             (and (ne (symbol_ref "TARGET_MOVX")
1348                      (const_int 0))
1349                  (eq_attr "alternative" "0,2"))
1350               (const_string "imovx")
1351            ]
1352            (const_string "imov")))
1353     (set (attr "mode")
1354       (cond [(eq_attr "type" "imovx")
1355                (const_string "SI")
1356              (and (eq_attr "alternative" "1,2")
1357                   (match_operand:HI 1 "aligned_operand" ""))
1358                (const_string "SI")
1359              (and (eq_attr "alternative" "0")
1360                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1361                            (const_int 0))
1362                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1363                            (const_int 0))))
1364                (const_string "SI")
1365             ]
1366             (const_string "HI")))])
1367
1368 ;; Stores and loads of ax to arbitrary constant address.
1369 ;; We fake an second form of instruction to force reload to load address
1370 ;; into register when rax is not available
1371 (define_insn "*movabshi_1_rex64"
1372   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1373         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1374   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1375   "@
1376    movabs{w}\t{%1, %P0|%P0, %1}
1377    mov{w}\t{%1, %a0|%a0, %1}"
1378   [(set_attr "type" "imov")
1379    (set_attr "modrm" "0,*")
1380    (set_attr "length_address" "8,0")
1381    (set_attr "length_immediate" "0,*")
1382    (set_attr "memory" "store")
1383    (set_attr "mode" "HI")])
1384
1385 (define_insn "*movabshi_2_rex64"
1386   [(set (match_operand:HI 0 "register_operand" "=a,r")
1387         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1388   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1389   "@
1390    movabs{w}\t{%P1, %0|%0, %P1}
1391    mov{w}\t{%a1, %0|%0, %a1}"
1392   [(set_attr "type" "imov")
1393    (set_attr "modrm" "0,*")
1394    (set_attr "length_address" "8,0")
1395    (set_attr "length_immediate" "0")
1396    (set_attr "memory" "load")
1397    (set_attr "mode" "HI")])
1398
1399 (define_insn "*swaphi_1"
1400   [(set (match_operand:HI 0 "register_operand" "+r")
1401         (match_operand:HI 1 "register_operand" "+r"))
1402    (set (match_dup 1)
1403         (match_dup 0))]
1404   "TARGET_PARTIAL_REG_STALL"
1405   "xchg{w}\t%1, %0"
1406   [(set_attr "type" "imov")
1407    (set_attr "pent_pair" "np")
1408    (set_attr "mode" "HI")
1409    (set_attr "modrm" "0")])
1410
1411 (define_insn "*swaphi_2"
1412   [(set (match_operand:HI 0 "register_operand" "+r")
1413         (match_operand:HI 1 "register_operand" "+r"))
1414    (set (match_dup 1)
1415         (match_dup 0))]
1416   "! TARGET_PARTIAL_REG_STALL"
1417   "xchg{l}\t%k1, %k0"
1418   [(set_attr "type" "imov")
1419    (set_attr "pent_pair" "np")
1420    (set_attr "mode" "SI")
1421    (set_attr "modrm" "0")])
1422
1423 (define_expand "movstricthi"
1424   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1425         (match_operand:HI 1 "general_operand" ""))]
1426   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1427 {
1428   /* Don't generate memory->memory moves, go through a register */
1429   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1430     operands[1] = force_reg (HImode, operands[1]);
1431 })
1432
1433 (define_insn "*movstricthi_1"
1434   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1435         (match_operand:HI 1 "general_operand" "rn,m"))]
1436   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1437    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1438   "mov{w}\t{%1, %0|%0, %1}"
1439   [(set_attr "type" "imov")
1440    (set_attr "mode" "HI")])
1441
1442 (define_insn "*movstricthi_xor"
1443   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1444         (match_operand:HI 1 "const0_operand" "i"))
1445    (clobber (reg:CC FLAGS_REG))]
1446   "reload_completed
1447    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1448   "xor{w}\t{%0, %0|%0, %0}"
1449   [(set_attr "type" "alu1")
1450    (set_attr "mode" "HI")
1451    (set_attr "length_immediate" "0")])
1452
1453 (define_expand "movqi"
1454   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1455         (match_operand:QI 1 "general_operand" ""))]
1456   ""
1457   "ix86_expand_move (QImode, operands); DONE;")
1458
1459 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1460 ;; "push a byte".  But actually we use pushw, which has the effect
1461 ;; of rounding the amount pushed up to a halfword.
1462
1463 (define_insn "*pushqi2"
1464   [(set (match_operand:QI 0 "push_operand" "=X,X")
1465         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1466   "!TARGET_64BIT"
1467   "@
1468    push{w}\t{|word ptr }%1
1469    push{w}\t%w1"
1470   [(set_attr "type" "push")
1471    (set_attr "mode" "HI")])
1472
1473 ;; For 64BIT abi we always round up to 8 bytes.
1474 (define_insn "*pushqi2_rex64"
1475   [(set (match_operand:QI 0 "push_operand" "=X")
1476         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1477   "TARGET_64BIT"
1478   "push{q}\t%q1"
1479   [(set_attr "type" "push")
1480    (set_attr "mode" "QI")])
1481
1482 ;; Situation is quite tricky about when to choose full sized (SImode) move
1483 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1484 ;; partial register dependency machines (such as AMD Athlon), where QImode
1485 ;; moves issue extra dependency and for partial register stalls machines
1486 ;; that don't use QImode patterns (and QImode move cause stall on the next
1487 ;; instruction).
1488 ;;
1489 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1490 ;; register stall machines with, where we use QImode instructions, since
1491 ;; partial register stall can be caused there.  Then we use movzx.
1492 (define_insn "*movqi_1"
1493   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1494         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1495   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1496 {
1497   switch (get_attr_type (insn))
1498     {
1499     case TYPE_IMOVX:
1500       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1501         abort ();
1502       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1503     default:
1504       if (get_attr_mode (insn) == MODE_SI)
1505         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1506       else
1507         return "mov{b}\t{%1, %0|%0, %1}";
1508     }
1509 }
1510   [(set (attr "type")
1511      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1512               (const_string "imov")
1513             (and (eq_attr "alternative" "3")
1514                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1515                           (const_int 0))
1516                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1517                           (const_int 0))))
1518               (const_string "imov")
1519             (eq_attr "alternative" "3,5")
1520               (const_string "imovx")
1521             (and (ne (symbol_ref "TARGET_MOVX")
1522                      (const_int 0))
1523                  (eq_attr "alternative" "2"))
1524               (const_string "imovx")
1525            ]
1526            (const_string "imov")))
1527    (set (attr "mode")
1528       (cond [(eq_attr "alternative" "3,4,5")
1529                (const_string "SI")
1530              (eq_attr "alternative" "6")
1531                (const_string "QI")
1532              (eq_attr "type" "imovx")
1533                (const_string "SI")
1534              (and (eq_attr "type" "imov")
1535                   (and (eq_attr "alternative" "0,1,2")
1536                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1537                            (const_int 0))))
1538                (const_string "SI")
1539              ;; Avoid partial register stalls when not using QImode arithmetic
1540              (and (eq_attr "type" "imov")
1541                   (and (eq_attr "alternative" "0,1,2")
1542                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1543                                 (const_int 0))
1544                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1545                                 (const_int 0)))))
1546                (const_string "SI")
1547            ]
1548            (const_string "QI")))])
1549
1550 (define_expand "reload_outqi"
1551   [(parallel [(match_operand:QI 0 "" "=m")
1552               (match_operand:QI 1 "register_operand" "r")
1553               (match_operand:QI 2 "register_operand" "=&q")])]
1554   ""
1555 {
1556   rtx op0, op1, op2;
1557   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1558
1559   if (reg_overlap_mentioned_p (op2, op0))
1560     abort ();
1561   if (! q_regs_operand (op1, QImode))
1562     {
1563       emit_insn (gen_movqi (op2, op1));
1564       op1 = op2;
1565     }
1566   emit_insn (gen_movqi (op0, op1));
1567   DONE;
1568 })
1569
1570 (define_insn "*swapqi"
1571   [(set (match_operand:QI 0 "register_operand" "+r")
1572         (match_operand:QI 1 "register_operand" "+r"))
1573    (set (match_dup 1)
1574         (match_dup 0))]
1575   ""
1576   "xchg{b}\t%1, %0"
1577   [(set_attr "type" "imov")
1578    (set_attr "pent_pair" "np")
1579    (set_attr "mode" "QI")
1580    (set_attr "modrm" "0")])
1581
1582 (define_expand "movstrictqi"
1583   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1584         (match_operand:QI 1 "general_operand" ""))]
1585   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1586 {
1587   /* Don't generate memory->memory moves, go through a register.  */
1588   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1589     operands[1] = force_reg (QImode, operands[1]);
1590 })
1591
1592 (define_insn "*movstrictqi_1"
1593   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1594         (match_operand:QI 1 "general_operand" "*qn,m"))]
1595   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1596    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1597   "mov{b}\t{%1, %0|%0, %1}"
1598   [(set_attr "type" "imov")
1599    (set_attr "mode" "QI")])
1600
1601 (define_insn "*movstrictqi_xor"
1602   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1603         (match_operand:QI 1 "const0_operand" "i"))
1604    (clobber (reg:CC FLAGS_REG))]
1605   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1606   "xor{b}\t{%0, %0|%0, %0}"
1607   [(set_attr "type" "alu1")
1608    (set_attr "mode" "QI")
1609    (set_attr "length_immediate" "0")])
1610
1611 (define_insn "*movsi_extv_1"
1612   [(set (match_operand:SI 0 "register_operand" "=R")
1613         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1614                          (const_int 8)
1615                          (const_int 8)))]
1616   ""
1617   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1618   [(set_attr "type" "imovx")
1619    (set_attr "mode" "SI")])
1620
1621 (define_insn "*movhi_extv_1"
1622   [(set (match_operand:HI 0 "register_operand" "=R")
1623         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1624                          (const_int 8)
1625                          (const_int 8)))]
1626   ""
1627   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1628   [(set_attr "type" "imovx")
1629    (set_attr "mode" "SI")])
1630
1631 (define_insn "*movqi_extv_1"
1632   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1633         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1634                          (const_int 8)
1635                          (const_int 8)))]
1636   "!TARGET_64BIT"
1637 {
1638   switch (get_attr_type (insn))
1639     {
1640     case TYPE_IMOVX:
1641       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1642     default:
1643       return "mov{b}\t{%h1, %0|%0, %h1}";
1644     }
1645 }
1646   [(set (attr "type")
1647      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1648                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1649                              (ne (symbol_ref "TARGET_MOVX")
1650                                  (const_int 0))))
1651         (const_string "imovx")
1652         (const_string "imov")))
1653    (set (attr "mode")
1654      (if_then_else (eq_attr "type" "imovx")
1655         (const_string "SI")
1656         (const_string "QI")))])
1657
1658 (define_insn "*movqi_extv_1_rex64"
1659   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1660         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1661                          (const_int 8)
1662                          (const_int 8)))]
1663   "TARGET_64BIT"
1664 {
1665   switch (get_attr_type (insn))
1666     {
1667     case TYPE_IMOVX:
1668       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1669     default:
1670       return "mov{b}\t{%h1, %0|%0, %h1}";
1671     }
1672 }
1673   [(set (attr "type")
1674      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1675                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1676                              (ne (symbol_ref "TARGET_MOVX")
1677                                  (const_int 0))))
1678         (const_string "imovx")
1679         (const_string "imov")))
1680    (set (attr "mode")
1681      (if_then_else (eq_attr "type" "imovx")
1682         (const_string "SI")
1683         (const_string "QI")))])
1684
1685 ;; Stores and loads of ax to arbitrary constant address.
1686 ;; We fake an second form of instruction to force reload to load address
1687 ;; into register when rax is not available
1688 (define_insn "*movabsqi_1_rex64"
1689   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1690         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1691   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1692   "@
1693    movabs{b}\t{%1, %P0|%P0, %1}
1694    mov{b}\t{%1, %a0|%a0, %1}"
1695   [(set_attr "type" "imov")
1696    (set_attr "modrm" "0,*")
1697    (set_attr "length_address" "8,0")
1698    (set_attr "length_immediate" "0,*")
1699    (set_attr "memory" "store")
1700    (set_attr "mode" "QI")])
1701
1702 (define_insn "*movabsqi_2_rex64"
1703   [(set (match_operand:QI 0 "register_operand" "=a,r")
1704         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1705   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1706   "@
1707    movabs{b}\t{%P1, %0|%0, %P1}
1708    mov{b}\t{%a1, %0|%0, %a1}"
1709   [(set_attr "type" "imov")
1710    (set_attr "modrm" "0,*")
1711    (set_attr "length_address" "8,0")
1712    (set_attr "length_immediate" "0")
1713    (set_attr "memory" "load")
1714    (set_attr "mode" "QI")])
1715
1716 (define_insn "*movsi_extzv_1"
1717   [(set (match_operand:SI 0 "register_operand" "=R")
1718         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1719                          (const_int 8)
1720                          (const_int 8)))]
1721   ""
1722   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1723   [(set_attr "type" "imovx")
1724    (set_attr "mode" "SI")])
1725
1726 (define_insn "*movqi_extzv_2"
1727   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1728         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1729                                     (const_int 8)
1730                                     (const_int 8)) 0))]
1731   "!TARGET_64BIT"
1732 {
1733   switch (get_attr_type (insn))
1734     {
1735     case TYPE_IMOVX:
1736       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1737     default:
1738       return "mov{b}\t{%h1, %0|%0, %h1}";
1739     }
1740 }
1741   [(set (attr "type")
1742      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1743                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1744                              (ne (symbol_ref "TARGET_MOVX")
1745                                  (const_int 0))))
1746         (const_string "imovx")
1747         (const_string "imov")))
1748    (set (attr "mode")
1749      (if_then_else (eq_attr "type" "imovx")
1750         (const_string "SI")
1751         (const_string "QI")))])
1752
1753 (define_insn "*movqi_extzv_2_rex64"
1754   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1755         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1756                                     (const_int 8)
1757                                     (const_int 8)) 0))]
1758   "TARGET_64BIT"
1759 {
1760   switch (get_attr_type (insn))
1761     {
1762     case TYPE_IMOVX:
1763       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1764     default:
1765       return "mov{b}\t{%h1, %0|%0, %h1}";
1766     }
1767 }
1768   [(set (attr "type")
1769      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1770                         (ne (symbol_ref "TARGET_MOVX")
1771                             (const_int 0)))
1772         (const_string "imovx")
1773         (const_string "imov")))
1774    (set (attr "mode")
1775      (if_then_else (eq_attr "type" "imovx")
1776         (const_string "SI")
1777         (const_string "QI")))])
1778
1779 (define_insn "movsi_insv_1"
1780   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1781                          (const_int 8)
1782                          (const_int 8))
1783         (match_operand:SI 1 "general_operand" "Qmn"))]
1784   "!TARGET_64BIT"
1785   "mov{b}\t{%b1, %h0|%h0, %b1}"
1786   [(set_attr "type" "imov")
1787    (set_attr "mode" "QI")])
1788
1789 (define_insn "movdi_insv_1_rex64"
1790   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1791                          (const_int 8)
1792                          (const_int 8))
1793         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1794   "TARGET_64BIT"
1795   "mov{b}\t{%b1, %h0|%h0, %b1}"
1796   [(set_attr "type" "imov")
1797    (set_attr "mode" "QI")])
1798
1799 (define_insn "*movqi_insv_2"
1800   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1801                          (const_int 8)
1802                          (const_int 8))
1803         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1804                      (const_int 8)))]
1805   ""
1806   "mov{b}\t{%h1, %h0|%h0, %h1}"
1807   [(set_attr "type" "imov")
1808    (set_attr "mode" "QI")])
1809
1810 (define_expand "movdi"
1811   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1812         (match_operand:DI 1 "general_operand" ""))]
1813   ""
1814   "ix86_expand_move (DImode, operands); DONE;")
1815
1816 (define_insn "*pushdi"
1817   [(set (match_operand:DI 0 "push_operand" "=<")
1818         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1819   "!TARGET_64BIT"
1820   "#")
1821
1822 (define_insn "pushdi2_rex64"
1823   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1824         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1825   "TARGET_64BIT"
1826   "@
1827    push{q}\t%1
1828    #"
1829   [(set_attr "type" "push,multi")
1830    (set_attr "mode" "DI")])
1831
1832 ;; Convert impossible pushes of immediate to existing instructions.
1833 ;; First try to get scratch register and go through it.  In case this
1834 ;; fails, push sign extended lower part first and then overwrite
1835 ;; upper part by 32bit move.
1836 (define_peephole2
1837   [(match_scratch:DI 2 "r")
1838    (set (match_operand:DI 0 "push_operand" "")
1839         (match_operand:DI 1 "immediate_operand" ""))]
1840   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1841    && !x86_64_immediate_operand (operands[1], DImode)"
1842   [(set (match_dup 2) (match_dup 1))
1843    (set (match_dup 0) (match_dup 2))]
1844   "")
1845
1846 ;; We need to define this as both peepholer and splitter for case
1847 ;; peephole2 pass is not run.
1848 (define_peephole2
1849   [(set (match_operand:DI 0 "push_operand" "")
1850         (match_operand:DI 1 "immediate_operand" ""))]
1851   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1852    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1853   [(set (match_dup 0) (match_dup 1))
1854    (set (match_dup 2) (match_dup 3))]
1855   "split_di (operands + 1, 1, operands + 2, operands + 3);
1856    operands[1] = gen_lowpart (DImode, operands[2]);
1857    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1858                                                     GEN_INT (4)));
1859   ")
1860
1861 (define_split
1862   [(set (match_operand:DI 0 "push_operand" "")
1863         (match_operand:DI 1 "immediate_operand" ""))]
1864   "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1865    && !symbolic_operand (operands[1], DImode)
1866    && !x86_64_immediate_operand (operands[1], DImode)"
1867   [(set (match_dup 0) (match_dup 1))
1868    (set (match_dup 2) (match_dup 3))]
1869   "split_di (operands + 1, 1, operands + 2, operands + 3);
1870    operands[1] = gen_lowpart (DImode, operands[2]);
1871    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1872                                                     GEN_INT (4)));
1873   ")
1874
1875 (define_insn "*pushdi2_prologue_rex64"
1876   [(set (match_operand:DI 0 "push_operand" "=<")
1877         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1878    (clobber (mem:BLK (scratch)))]
1879   "TARGET_64BIT"
1880   "push{q}\t%1"
1881   [(set_attr "type" "push")
1882    (set_attr "mode" "DI")])
1883
1884 (define_insn "*popdi1_epilogue_rex64"
1885   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1886         (mem:DI (reg:DI SP_REG)))
1887    (set (reg:DI SP_REG)
1888         (plus:DI (reg:DI SP_REG) (const_int 8)))
1889    (clobber (mem:BLK (scratch)))]
1890   "TARGET_64BIT"
1891   "pop{q}\t%0"
1892   [(set_attr "type" "pop")
1893    (set_attr "mode" "DI")])
1894
1895 (define_insn "popdi1"
1896   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1897         (mem:DI (reg:DI SP_REG)))
1898    (set (reg:DI SP_REG)
1899         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1900   "TARGET_64BIT"
1901   "pop{q}\t%0"
1902   [(set_attr "type" "pop")
1903    (set_attr "mode" "DI")])
1904
1905 (define_insn "*movdi_xor_rex64"
1906   [(set (match_operand:DI 0 "register_operand" "=r")
1907         (match_operand:DI 1 "const0_operand" "i"))
1908    (clobber (reg:CC FLAGS_REG))]
1909   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1910    && reload_completed"
1911   "xor{l}\t{%k0, %k0|%k0, %k0}"
1912   [(set_attr "type" "alu1")
1913    (set_attr "mode" "SI")
1914    (set_attr "length_immediate" "0")])
1915
1916 (define_insn "*movdi_or_rex64"
1917   [(set (match_operand:DI 0 "register_operand" "=r")
1918         (match_operand:DI 1 "const_int_operand" "i"))
1919    (clobber (reg:CC FLAGS_REG))]
1920   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1921    && reload_completed
1922    && operands[1] == constm1_rtx"
1923 {
1924   operands[1] = constm1_rtx;
1925   return "or{q}\t{%1, %0|%0, %1}";
1926 }
1927   [(set_attr "type" "alu1")
1928    (set_attr "mode" "DI")
1929    (set_attr "length_immediate" "1")])
1930
1931 (define_insn "*movdi_2"
1932   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1933         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1934   "!TARGET_64BIT
1935    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1936   "@
1937    #
1938    #
1939    movq\t{%1, %0|%0, %1}
1940    movq\t{%1, %0|%0, %1}
1941    movq\t{%1, %0|%0, %1}
1942    movdqa\t{%1, %0|%0, %1}
1943    movq\t{%1, %0|%0, %1}"
1944   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1945    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1946
1947 (define_split
1948   [(set (match_operand:DI 0 "push_operand" "")
1949         (match_operand:DI 1 "general_operand" ""))]
1950   "!TARGET_64BIT && reload_completed
1951    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1952   [(const_int 0)]
1953   "ix86_split_long_move (operands); DONE;")
1954
1955 ;; %%% This multiword shite has got to go.
1956 (define_split
1957   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1958         (match_operand:DI 1 "general_operand" ""))]
1959   "!TARGET_64BIT && reload_completed
1960    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1961    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1962   [(const_int 0)]
1963   "ix86_split_long_move (operands); DONE;")
1964
1965 (define_insn "*movdi_1_rex64"
1966   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y,!*Y,!*y")
1967         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm,*y,*Y"))]
1968   "TARGET_64BIT
1969    && (TARGET_INTER_UNIT_MOVES || optimize_size)
1970    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1971 {
1972   switch (get_attr_type (insn))
1973     {
1974     case TYPE_SSECVT:
1975       if (which_alternative == 11)
1976         return "movq2dq\t{%1, %0|%0, %1}";
1977       else
1978         return "movdq2q\t{%1, %0|%0, %1}";
1979     case TYPE_SSEMOV:
1980       if (get_attr_mode (insn) == MODE_TI)
1981           return "movdqa\t{%1, %0|%0, %1}";
1982       /* FALLTHRU */
1983     case TYPE_MMXMOV:
1984       /* Moves from and into integer register is done using movd opcode with
1985          REX prefix.  */
1986       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1987           return "movd\t{%1, %0|%0, %1}";
1988       return "movq\t{%1, %0|%0, %1}";
1989     case TYPE_MULTI:
1990       return "#";
1991     case TYPE_LEA:
1992       return "lea{q}\t{%a1, %0|%0, %a1}";
1993     default:
1994       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1995         abort ();
1996       if (get_attr_mode (insn) == MODE_SI)
1997         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1998       else if (which_alternative == 2)
1999         return "movabs{q}\t{%1, %0|%0, %1}";
2000       else
2001         return "mov{q}\t{%1, %0|%0, %1}";
2002     }
2003 }
2004   [(set (attr "type")
2005      (cond [(eq_attr "alternative" "5,6,7")
2006               (const_string "mmxmov")
2007             (eq_attr "alternative" "8,9,10")
2008               (const_string "ssemov")
2009             (eq_attr "alternative" "11,12")
2010               (const_string "ssecvt")
2011             (eq_attr "alternative" "4")
2012               (const_string "multi")
2013             (and (ne (symbol_ref "flag_pic") (const_int 0))
2014                  (match_operand:DI 1 "symbolic_operand" ""))
2015               (const_string "lea")
2016            ]
2017            (const_string "imov")))
2018    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
2019    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
2020    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
2021
2022 (define_insn "*movdi_1_rex64_nointerunit"
2023   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2024         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2025   "TARGET_64BIT
2026    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2027    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2028 {
2029   switch (get_attr_type (insn))
2030     {
2031     case TYPE_SSEMOV:
2032       if (get_attr_mode (insn) == MODE_TI)
2033           return "movdqa\t{%1, %0|%0, %1}";
2034       /* FALLTHRU */
2035     case TYPE_MMXMOV:
2036       return "movq\t{%1, %0|%0, %1}";
2037     case TYPE_MULTI:
2038       return "#";
2039     case TYPE_LEA:
2040       return "lea{q}\t{%a1, %0|%0, %a1}";
2041     default:
2042       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2043         abort ();
2044       if (get_attr_mode (insn) == MODE_SI)
2045         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2046       else if (which_alternative == 2)
2047         return "movabs{q}\t{%1, %0|%0, %1}";
2048       else
2049         return "mov{q}\t{%1, %0|%0, %1}";
2050     }
2051 }
2052   [(set (attr "type")
2053      (cond [(eq_attr "alternative" "5,6,7")
2054               (const_string "mmxmov")
2055             (eq_attr "alternative" "8,9,10")
2056               (const_string "ssemov")
2057             (eq_attr "alternative" "4")
2058               (const_string "multi")
2059             (and (ne (symbol_ref "flag_pic") (const_int 0))
2060                  (match_operand:DI 1 "symbolic_operand" ""))
2061               (const_string "lea")
2062            ]
2063            (const_string "imov")))
2064    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2065    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2066    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2067
2068 ;; Stores and loads of ax to arbitrary constant address.
2069 ;; We fake an second form of instruction to force reload to load address
2070 ;; into register when rax is not available
2071 (define_insn "*movabsdi_1_rex64"
2072   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2073         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2074   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2075   "@
2076    movabs{q}\t{%1, %P0|%P0, %1}
2077    mov{q}\t{%1, %a0|%a0, %1}"
2078   [(set_attr "type" "imov")
2079    (set_attr "modrm" "0,*")
2080    (set_attr "length_address" "8,0")
2081    (set_attr "length_immediate" "0,*")
2082    (set_attr "memory" "store")
2083    (set_attr "mode" "DI")])
2084
2085 (define_insn "*movabsdi_2_rex64"
2086   [(set (match_operand:DI 0 "register_operand" "=a,r")
2087         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2088   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2089   "@
2090    movabs{q}\t{%P1, %0|%0, %P1}
2091    mov{q}\t{%a1, %0|%0, %a1}"
2092   [(set_attr "type" "imov")
2093    (set_attr "modrm" "0,*")
2094    (set_attr "length_address" "8,0")
2095    (set_attr "length_immediate" "0")
2096    (set_attr "memory" "load")
2097    (set_attr "mode" "DI")])
2098
2099 ;; Convert impossible stores of immediate to existing instructions.
2100 ;; First try to get scratch register and go through it.  In case this
2101 ;; fails, move by 32bit parts.
2102 (define_peephole2
2103   [(match_scratch:DI 2 "r")
2104    (set (match_operand:DI 0 "memory_operand" "")
2105         (match_operand:DI 1 "immediate_operand" ""))]
2106   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2107    && !x86_64_immediate_operand (operands[1], DImode)"
2108   [(set (match_dup 2) (match_dup 1))
2109    (set (match_dup 0) (match_dup 2))]
2110   "")
2111
2112 ;; We need to define this as both peepholer and splitter for case
2113 ;; peephole2 pass is not run.
2114 (define_peephole2
2115   [(set (match_operand:DI 0 "memory_operand" "")
2116         (match_operand:DI 1 "immediate_operand" ""))]
2117   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2118    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2119   [(set (match_dup 2) (match_dup 3))
2120    (set (match_dup 4) (match_dup 5))]
2121   "split_di (operands, 2, operands + 2, operands + 4);")
2122
2123 (define_split
2124   [(set (match_operand:DI 0 "memory_operand" "")
2125         (match_operand:DI 1 "immediate_operand" ""))]
2126   "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2127    && !symbolic_operand (operands[1], DImode)
2128    && !x86_64_immediate_operand (operands[1], DImode)"
2129   [(set (match_dup 2) (match_dup 3))
2130    (set (match_dup 4) (match_dup 5))]
2131   "split_di (operands, 2, operands + 2, operands + 4);")
2132
2133 (define_insn "*swapdi_rex64"
2134   [(set (match_operand:DI 0 "register_operand" "+r")
2135         (match_operand:DI 1 "register_operand" "+r"))
2136    (set (match_dup 1)
2137         (match_dup 0))]
2138   "TARGET_64BIT"
2139   "xchg{q}\t%1, %0"
2140   [(set_attr "type" "imov")
2141    (set_attr "pent_pair" "np")
2142    (set_attr "athlon_decode" "vector")
2143    (set_attr "mode" "DI")
2144    (set_attr "modrm" "0")])
2145
2146   
2147 (define_expand "movsf"
2148   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2149         (match_operand:SF 1 "general_operand" ""))]
2150   ""
2151   "ix86_expand_move (SFmode, operands); DONE;")
2152
2153 (define_insn "*pushsf"
2154   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2155         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2156   "!TARGET_64BIT"
2157 {
2158   switch (which_alternative)
2159     {
2160     case 1:
2161       return "push{l}\t%1";
2162
2163     default:
2164       /* This insn should be already split before reg-stack.  */
2165       abort ();
2166     }
2167 }
2168   [(set_attr "type" "multi,push,multi")
2169    (set_attr "mode" "SF,SI,SF")])
2170
2171 (define_insn "*pushsf_rex64"
2172   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2173         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2174   "TARGET_64BIT"
2175 {
2176   switch (which_alternative)
2177     {
2178     case 1:
2179       return "push{q}\t%q1";
2180
2181     default:
2182       /* This insn should be already split before reg-stack.  */
2183       abort ();
2184     }
2185 }
2186   [(set_attr "type" "multi,push,multi")
2187    (set_attr "mode" "SF,DI,SF")])
2188
2189 (define_split
2190   [(set (match_operand:SF 0 "push_operand" "")
2191         (match_operand:SF 1 "memory_operand" ""))]
2192   "reload_completed
2193    && GET_CODE (operands[1]) == MEM
2194    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2195    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2196   [(set (match_dup 0)
2197         (match_dup 1))]
2198   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2199
2200
2201 ;; %%% Kill this when call knows how to work this out.
2202 (define_split
2203   [(set (match_operand:SF 0 "push_operand" "")
2204         (match_operand:SF 1 "any_fp_register_operand" ""))]
2205   "!TARGET_64BIT"
2206   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2207    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2208
2209 (define_split
2210   [(set (match_operand:SF 0 "push_operand" "")
2211         (match_operand:SF 1 "any_fp_register_operand" ""))]
2212   "TARGET_64BIT"
2213   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2214    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2215
2216 (define_insn "*movsf_1"
2217   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
2218         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2219   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2220    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2221    && (reload_in_progress || reload_completed
2222        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2223        || GET_CODE (operands[1]) != CONST_DOUBLE
2224        || memory_operand (operands[0], SFmode))" 
2225 {
2226   switch (which_alternative)
2227     {
2228     case 0:
2229       return output_387_reg_move (insn, operands);
2230
2231     case 1:
2232       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2233         return "fstp%z0\t%y0";
2234       else
2235         return "fst%z0\t%y0";
2236
2237     case 2:
2238       return standard_80387_constant_opcode (operands[1]);
2239
2240     case 3:
2241     case 4:
2242       return "mov{l}\t{%1, %0|%0, %1}";
2243     case 5:
2244       if (get_attr_mode (insn) == MODE_TI)
2245         return "pxor\t%0, %0";
2246       else
2247         return "xorps\t%0, %0";
2248     case 6:
2249       if (get_attr_mode (insn) == MODE_V4SF)
2250         return "movaps\t{%1, %0|%0, %1}";
2251       else
2252         return "movss\t{%1, %0|%0, %1}";
2253     case 7:
2254     case 8:
2255       return "movss\t{%1, %0|%0, %1}";
2256
2257     case 9:
2258     case 10:
2259       return "movd\t{%1, %0|%0, %1}";
2260
2261     case 11:
2262       return "movq\t{%1, %0|%0, %1}";
2263
2264     default:
2265       abort();
2266     }
2267 }
2268   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2269    (set (attr "mode")
2270         (cond [(eq_attr "alternative" "3,4,9,10")
2271                  (const_string "SI")
2272                (eq_attr "alternative" "5")
2273                  (if_then_else
2274                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2275                                  (const_int 0))
2276                              (ne (symbol_ref "TARGET_SSE2")
2277                                  (const_int 0)))
2278                         (eq (symbol_ref "optimize_size")
2279                             (const_int 0)))
2280                    (const_string "TI")
2281                    (const_string "V4SF"))
2282                /* For architectures resolving dependencies on
2283                   whole SSE registers use APS move to break dependency
2284                   chains, otherwise use short move to avoid extra work. 
2285
2286                   Do the same for architectures resolving dependencies on
2287                   the parts.  While in DF mode it is better to always handle
2288                   just register parts, the SF mode is different due to lack
2289                   of instructions to load just part of the register.  It is
2290                   better to maintain the whole registers in single format
2291                   to avoid problems on using packed logical operations.  */
2292                (eq_attr "alternative" "6")
2293                  (if_then_else
2294                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2295                             (const_int 0))
2296                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2297                             (const_int 0)))
2298                    (const_string "V4SF")
2299                    (const_string "SF"))
2300                (eq_attr "alternative" "11")
2301                  (const_string "DI")]
2302                (const_string "SF")))])
2303
2304 (define_insn "*movsf_1_nointerunit"
2305   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!m,!*y")
2306         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2307   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2308    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2309    && (reload_in_progress || reload_completed
2310        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2311        || GET_CODE (operands[1]) != CONST_DOUBLE
2312        || memory_operand (operands[0], SFmode))" 
2313 {
2314   switch (which_alternative)
2315     {
2316     case 0:
2317       return output_387_reg_move (insn, operands);
2318
2319     case 1:
2320       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2321         return "fstp%z0\t%y0";
2322       else
2323         return "fst%z0\t%y0";
2324
2325     case 2:
2326       return standard_80387_constant_opcode (operands[1]);
2327
2328     case 3:
2329     case 4:
2330       return "mov{l}\t{%1, %0|%0, %1}";
2331     case 5:
2332       if (get_attr_mode (insn) == MODE_TI)
2333         return "pxor\t%0, %0";
2334       else
2335         return "xorps\t%0, %0";
2336     case 6:
2337       if (get_attr_mode (insn) == MODE_V4SF)
2338         return "movaps\t{%1, %0|%0, %1}";
2339       else
2340         return "movss\t{%1, %0|%0, %1}";
2341     case 7:
2342     case 8:
2343       return "movss\t{%1, %0|%0, %1}";
2344
2345     case 9:
2346     case 10:
2347       return "movd\t{%1, %0|%0, %1}";
2348
2349     case 11:
2350       return "movq\t{%1, %0|%0, %1}";
2351
2352     default:
2353       abort();
2354     }
2355 }
2356   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2357    (set (attr "mode")
2358         (cond [(eq_attr "alternative" "3,4,9,10")
2359                  (const_string "SI")
2360                (eq_attr "alternative" "5")
2361                  (if_then_else
2362                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2363                                  (const_int 0))
2364                              (ne (symbol_ref "TARGET_SSE2")
2365                                  (const_int 0)))
2366                         (eq (symbol_ref "optimize_size")
2367                             (const_int 0)))
2368                    (const_string "TI")
2369                    (const_string "V4SF"))
2370                /* For architectures resolving dependencies on
2371                   whole SSE registers use APS move to break dependency
2372                   chains, otherwise use short move to avoid extra work. 
2373
2374                   Do the same for architectures resolving dependencies on
2375                   the parts.  While in DF mode it is better to always handle
2376                   just register parts, the SF mode is different due to lack
2377                   of instructions to load just part of the register.  It is
2378                   better to maintain the whole registers in single format
2379                   to avoid problems on using packed logical operations.  */
2380                (eq_attr "alternative" "6")
2381                  (if_then_else
2382                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2383                             (const_int 0))
2384                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2385                             (const_int 0)))
2386                    (const_string "V4SF")
2387                    (const_string "SF"))
2388                (eq_attr "alternative" "11")
2389                  (const_string "DI")]
2390                (const_string "SF")))])
2391
2392 (define_insn "*swapsf"
2393   [(set (match_operand:SF 0 "register_operand" "+f")
2394         (match_operand:SF 1 "register_operand" "+f"))
2395    (set (match_dup 1)
2396         (match_dup 0))]
2397   "reload_completed || !TARGET_SSE"
2398 {
2399   if (STACK_TOP_P (operands[0]))
2400     return "fxch\t%1";
2401   else
2402     return "fxch\t%0";
2403 }
2404   [(set_attr "type" "fxch")
2405    (set_attr "mode" "SF")])
2406
2407 (define_expand "movdf"
2408   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2409         (match_operand:DF 1 "general_operand" ""))]
2410   ""
2411   "ix86_expand_move (DFmode, operands); DONE;")
2412
2413 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2414 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2415 ;; On the average, pushdf using integers can be still shorter.  Allow this
2416 ;; pattern for optimize_size too.
2417
2418 (define_insn "*pushdf_nointeger"
2419   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2420         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2421   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2422 {
2423   /* This insn should be already split before reg-stack.  */
2424   abort ();
2425 }
2426   [(set_attr "type" "multi")
2427    (set_attr "mode" "DF,SI,SI,DF")])
2428
2429 (define_insn "*pushdf_integer"
2430   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2431         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2432   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2433 {
2434   /* This insn should be already split before reg-stack.  */
2435   abort ();
2436 }
2437   [(set_attr "type" "multi")
2438    (set_attr "mode" "DF,SI,DF")])
2439
2440 ;; %%% Kill this when call knows how to work this out.
2441 (define_split
2442   [(set (match_operand:DF 0 "push_operand" "")
2443         (match_operand:DF 1 "any_fp_register_operand" ""))]
2444   "!TARGET_64BIT && reload_completed"
2445   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2446    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2447   "")
2448
2449 (define_split
2450   [(set (match_operand:DF 0 "push_operand" "")
2451         (match_operand:DF 1 "any_fp_register_operand" ""))]
2452   "TARGET_64BIT && reload_completed"
2453   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2454    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2455   "")
2456
2457 (define_split
2458   [(set (match_operand:DF 0 "push_operand" "")
2459         (match_operand:DF 1 "general_operand" ""))]
2460   "reload_completed"
2461   [(const_int 0)]
2462   "ix86_split_long_move (operands); DONE;")
2463
2464 ;; Moving is usually shorter when only FP registers are used. This separate
2465 ;; movdf pattern avoids the use of integer registers for FP operations
2466 ;; when optimizing for size.
2467
2468 (define_insn "*movdf_nointeger"
2469   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2470         (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2471   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2472    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2473    && (reload_in_progress || reload_completed
2474        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2475        || GET_CODE (operands[1]) != CONST_DOUBLE
2476        || memory_operand (operands[0], DFmode))" 
2477 {
2478   switch (which_alternative)
2479     {
2480     case 0:
2481       return output_387_reg_move (insn, operands);
2482
2483     case 1:
2484       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2485         return "fstp%z0\t%y0";
2486       else
2487         return "fst%z0\t%y0";
2488
2489     case 2:
2490       return standard_80387_constant_opcode (operands[1]);
2491
2492     case 3:
2493     case 4:
2494       return "#";
2495     case 5:
2496       switch (get_attr_mode (insn))
2497         {
2498         case MODE_V4SF:
2499           return "xorps\t%0, %0";
2500         case MODE_V2DF:
2501           return "xorpd\t%0, %0";
2502         case MODE_TI:
2503           return "pxor\t%0, %0";
2504         default:
2505           abort ();
2506         }
2507     case 6:
2508       switch (get_attr_mode (insn))
2509         {
2510         case MODE_V4SF:
2511           return "movaps\t{%1, %0|%0, %1}";
2512         case MODE_V2DF:
2513           return "movapd\t{%1, %0|%0, %1}";
2514         case MODE_DF:
2515           return "movsd\t{%1, %0|%0, %1}";
2516         default:
2517           abort ();
2518         }
2519     case 7:
2520       if (get_attr_mode (insn) == MODE_V2DF)
2521         return "movlpd\t{%1, %0|%0, %1}";
2522       else
2523         return "movsd\t{%1, %0|%0, %1}";
2524     case 8:
2525       return "movsd\t{%1, %0|%0, %1}";
2526
2527     default:
2528       abort();
2529     }
2530 }
2531   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2532    (set (attr "mode")
2533         (cond [(eq_attr "alternative" "3,4")
2534                  (const_string "SI")
2535                /* xorps is one byte shorter.  */
2536                (eq_attr "alternative" "5")
2537                  (cond [(ne (symbol_ref "optimize_size")
2538                             (const_int 0))
2539                           (const_string "V4SF")
2540                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2541                             (const_int 0))
2542                           (const_string "TI")]
2543                        (const_string "V2DF"))
2544                /* For architectures resolving dependencies on
2545                   whole SSE registers use APD move to break dependency
2546                   chains, otherwise use short move to avoid extra work.
2547
2548                   movaps encodes one byte shorter.  */
2549                (eq_attr "alternative" "6")
2550                  (cond
2551                   [(ne (symbol_ref "optimize_size")
2552                        (const_int 0))
2553                      (const_string "V4SF")
2554                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2555                        (const_int 0))
2556                      (const_string "V2DF")]
2557                    (const_string "DF"))
2558                /* For architectures resolving dependencies on register
2559                   parts we may avoid extra work to zero out upper part
2560                   of register.  */
2561                (eq_attr "alternative" "7")
2562                  (if_then_else
2563                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2564                        (const_int 0))
2565                    (const_string "V2DF")
2566                    (const_string "DF"))]
2567                (const_string "DF")))])
2568
2569 (define_insn "*movdf_integer"
2570   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2571         (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2572   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2573    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2574    && (reload_in_progress || reload_completed
2575        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2576        || GET_CODE (operands[1]) != CONST_DOUBLE
2577        || memory_operand (operands[0], DFmode))" 
2578 {
2579   switch (which_alternative)
2580     {
2581     case 0:
2582       return output_387_reg_move (insn, operands);
2583
2584     case 1:
2585       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2586         return "fstp%z0\t%y0";
2587       else
2588         return "fst%z0\t%y0";
2589
2590     case 2:
2591       return standard_80387_constant_opcode (operands[1]);
2592
2593     case 3:
2594     case 4:
2595       return "#";
2596
2597     case 5:
2598       switch (get_attr_mode (insn))
2599         {
2600         case MODE_V4SF:
2601           return "xorps\t%0, %0";
2602         case MODE_V2DF:
2603           return "xorpd\t%0, %0";
2604         case MODE_TI:
2605           return "pxor\t%0, %0";
2606         default:
2607           abort ();
2608         }
2609     case 6:
2610       switch (get_attr_mode (insn))
2611         {
2612         case MODE_V4SF:
2613           return "movaps\t{%1, %0|%0, %1}";
2614         case MODE_V2DF:
2615           return "movapd\t{%1, %0|%0, %1}";
2616         case MODE_DF:
2617           return "movsd\t{%1, %0|%0, %1}";
2618         default:
2619           abort ();
2620         }
2621     case 7:
2622       if (get_attr_mode (insn) == MODE_V2DF)
2623         return "movlpd\t{%1, %0|%0, %1}";
2624       else
2625         return "movsd\t{%1, %0|%0, %1}";
2626     case 8:
2627       return "movsd\t{%1, %0|%0, %1}";
2628
2629     default:
2630       abort();
2631     }
2632 }
2633   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2634    (set (attr "mode")
2635         (cond [(eq_attr "alternative" "3,4")
2636                  (const_string "SI")
2637                /* xorps is one byte shorter.  */
2638                (eq_attr "alternative" "5")
2639                  (cond [(ne (symbol_ref "optimize_size")
2640                             (const_int 0))
2641                           (const_string "V4SF")
2642                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2643                             (const_int 0))
2644                           (const_string "TI")]
2645                        (const_string "V2DF"))
2646                /* For architectures resolving dependencies on
2647                   whole SSE registers use APD move to break dependency
2648                   chains, otherwise use short move to avoid extra work.  
2649
2650                   movaps encodes one byte shorter.  */
2651                (eq_attr "alternative" "6")
2652                  (cond
2653                   [(ne (symbol_ref "optimize_size")
2654                        (const_int 0))
2655                      (const_string "V4SF")
2656                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2657                        (const_int 0))
2658                      (const_string "V2DF")]
2659                    (const_string "DF"))
2660                /* For architectures resolving dependencies on register
2661                   parts we may avoid extra work to zero out upper part
2662                   of register.  */
2663                (eq_attr "alternative" "7")
2664                  (if_then_else
2665                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2666                        (const_int 0))
2667                    (const_string "V2DF")
2668                    (const_string "DF"))]
2669                (const_string "DF")))])
2670
2671 (define_split
2672   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2673         (match_operand:DF 1 "general_operand" ""))]
2674   "reload_completed
2675    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2676    && ! (ANY_FP_REG_P (operands[0]) || 
2677          (GET_CODE (operands[0]) == SUBREG
2678           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2679    && ! (ANY_FP_REG_P (operands[1]) || 
2680          (GET_CODE (operands[1]) == SUBREG
2681           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2682   [(const_int 0)]
2683   "ix86_split_long_move (operands); DONE;")
2684
2685 (define_insn "*swapdf"
2686   [(set (match_operand:DF 0 "register_operand" "+f")
2687         (match_operand:DF 1 "register_operand" "+f"))
2688    (set (match_dup 1)
2689         (match_dup 0))]
2690   "reload_completed || !TARGET_SSE2"
2691 {
2692   if (STACK_TOP_P (operands[0]))
2693     return "fxch\t%1";
2694   else
2695     return "fxch\t%0";
2696 }
2697   [(set_attr "type" "fxch")
2698    (set_attr "mode" "DF")])
2699
2700 (define_expand "movxf"
2701   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2702         (match_operand:XF 1 "general_operand" ""))]
2703   ""
2704   "ix86_expand_move (XFmode, operands); DONE;")
2705
2706 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2707 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2708 ;; Pushing using integer instructions is longer except for constants
2709 ;; and direct memory references.
2710 ;; (assuming that any given constant is pushed only once, but this ought to be
2711 ;;  handled elsewhere).
2712
2713 (define_insn "*pushxf_nointeger"
2714   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2715         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2716   "optimize_size"
2717 {
2718   /* This insn should be already split before reg-stack.  */
2719   abort ();
2720 }
2721   [(set_attr "type" "multi")
2722    (set_attr "mode" "XF,SI,SI")])
2723
2724 (define_insn "*pushxf_integer"
2725   [(set (match_operand:XF 0 "push_operand" "=<,<")
2726         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2727   "!optimize_size"
2728 {
2729   /* This insn should be already split before reg-stack.  */
2730   abort ();
2731 }
2732   [(set_attr "type" "multi")
2733    (set_attr "mode" "XF,SI")])
2734
2735 (define_split
2736   [(set (match_operand 0 "push_operand" "")
2737         (match_operand 1 "general_operand" ""))]
2738   "reload_completed
2739    && (GET_MODE (operands[0]) == XFmode
2740        || GET_MODE (operands[0]) == DFmode)
2741    && !ANY_FP_REG_P (operands[1])"
2742   [(const_int 0)]
2743   "ix86_split_long_move (operands); DONE;")
2744
2745 (define_split
2746   [(set (match_operand:XF 0 "push_operand" "")
2747         (match_operand:XF 1 "any_fp_register_operand" ""))]
2748   "!TARGET_64BIT"
2749   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2750    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2751   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2752
2753 (define_split
2754   [(set (match_operand:XF 0 "push_operand" "")
2755         (match_operand:XF 1 "any_fp_register_operand" ""))]
2756   "TARGET_64BIT"
2757   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2758    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2759   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2760
2761 ;; Do not use integer registers when optimizing for size
2762 (define_insn "*movxf_nointeger"
2763   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2764         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2765   "optimize_size
2766    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2767    && (reload_in_progress || reload_completed
2768        || GET_CODE (operands[1]) != CONST_DOUBLE
2769        || memory_operand (operands[0], XFmode))" 
2770 {
2771   switch (which_alternative)
2772     {
2773     case 0:
2774       return output_387_reg_move (insn, operands);
2775
2776     case 1:
2777       /* There is no non-popping store to memory for XFmode.  So if
2778          we need one, follow the store with a load.  */
2779       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2780         return "fstp%z0\t%y0\;fld%z0\t%y0";
2781       else
2782         return "fstp%z0\t%y0";
2783
2784     case 2:
2785       return standard_80387_constant_opcode (operands[1]);
2786
2787     case 3: case 4:
2788       return "#";
2789     }
2790   abort();
2791 }
2792   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2793    (set_attr "mode" "XF,XF,XF,SI,SI")])
2794
2795 (define_insn "*movxf_integer"
2796   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2797         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2798   "!optimize_size
2799    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2800    && (reload_in_progress || reload_completed
2801        || GET_CODE (operands[1]) != CONST_DOUBLE
2802        || memory_operand (operands[0], XFmode))" 
2803 {
2804   switch (which_alternative)
2805     {
2806     case 0:
2807       return output_387_reg_move (insn, operands);
2808
2809     case 1:
2810       /* There is no non-popping store to memory for XFmode.  So if
2811          we need one, follow the store with a load.  */
2812       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2813         return "fstp%z0\t%y0\;fld%z0\t%y0";
2814       else
2815         return "fstp%z0\t%y0";
2816
2817     case 2:
2818       return standard_80387_constant_opcode (operands[1]);
2819
2820     case 3: case 4:
2821       return "#";
2822     }
2823   abort();
2824 }
2825   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2826    (set_attr "mode" "XF,XF,XF,SI,SI")])
2827
2828 (define_split
2829   [(set (match_operand 0 "nonimmediate_operand" "")
2830         (match_operand 1 "general_operand" ""))]
2831   "reload_completed
2832    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2833    && GET_MODE (operands[0]) == XFmode
2834    && ! (ANY_FP_REG_P (operands[0]) || 
2835          (GET_CODE (operands[0]) == SUBREG
2836           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2837    && ! (ANY_FP_REG_P (operands[1]) || 
2838          (GET_CODE (operands[1]) == SUBREG
2839           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2840   [(const_int 0)]
2841   "ix86_split_long_move (operands); DONE;")
2842
2843 (define_split
2844   [(set (match_operand 0 "register_operand" "")
2845         (match_operand 1 "memory_operand" ""))]
2846   "reload_completed
2847    && GET_CODE (operands[1]) == MEM
2848    && (GET_MODE (operands[0]) == XFmode
2849        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2850    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2851    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2852   [(set (match_dup 0) (match_dup 1))]
2853 {
2854   rtx c = get_pool_constant (XEXP (operands[1], 0));
2855   rtx r = operands[0];
2856
2857   if (GET_CODE (r) == SUBREG)
2858     r = SUBREG_REG (r);
2859
2860   if (SSE_REG_P (r))
2861     {
2862       if (!standard_sse_constant_p (c))
2863         FAIL;
2864     }
2865   else if (FP_REG_P (r))
2866     {
2867       if (!standard_80387_constant_p (c))
2868         FAIL;
2869     }
2870   else if (MMX_REG_P (r))
2871     FAIL;
2872
2873   operands[1] = c;
2874 })
2875
2876 (define_insn "swapxf"
2877   [(set (match_operand:XF 0 "register_operand" "+f")
2878         (match_operand:XF 1 "register_operand" "+f"))
2879    (set (match_dup 1)
2880         (match_dup 0))]
2881   ""
2882 {
2883   if (STACK_TOP_P (operands[0]))
2884     return "fxch\t%1";
2885   else
2886     return "fxch\t%0";
2887 }
2888   [(set_attr "type" "fxch")
2889    (set_attr "mode" "XF")])
2890 \f
2891 ;; Zero extension instructions
2892
2893 (define_expand "zero_extendhisi2"
2894   [(set (match_operand:SI 0 "register_operand" "")
2895      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2896   ""
2897 {
2898   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2899     {
2900       operands[1] = force_reg (HImode, operands[1]);
2901       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2902       DONE;
2903     }
2904 })
2905
2906 (define_insn "zero_extendhisi2_and"
2907   [(set (match_operand:SI 0 "register_operand" "=r")
2908      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2909    (clobber (reg:CC FLAGS_REG))]
2910   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2911   "#"
2912   [(set_attr "type" "alu1")
2913    (set_attr "mode" "SI")])
2914
2915 (define_split
2916   [(set (match_operand:SI 0 "register_operand" "")
2917         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2918    (clobber (reg:CC FLAGS_REG))]
2919   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2920   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2921               (clobber (reg:CC FLAGS_REG))])]
2922   "")
2923
2924 (define_insn "*zero_extendhisi2_movzwl"
2925   [(set (match_operand:SI 0 "register_operand" "=r")
2926      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2927   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2928   "movz{wl|x}\t{%1, %0|%0, %1}"
2929   [(set_attr "type" "imovx")
2930    (set_attr "mode" "SI")])
2931
2932 (define_expand "zero_extendqihi2"
2933   [(parallel
2934     [(set (match_operand:HI 0 "register_operand" "")
2935        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2936      (clobber (reg:CC FLAGS_REG))])]
2937   ""
2938   "")
2939
2940 (define_insn "*zero_extendqihi2_and"
2941   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2942      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2943    (clobber (reg:CC FLAGS_REG))]
2944   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2945   "#"
2946   [(set_attr "type" "alu1")
2947    (set_attr "mode" "HI")])
2948
2949 (define_insn "*zero_extendqihi2_movzbw_and"
2950   [(set (match_operand:HI 0 "register_operand" "=r,r")
2951      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2952    (clobber (reg:CC FLAGS_REG))]
2953   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2954   "#"
2955   [(set_attr "type" "imovx,alu1")
2956    (set_attr "mode" "HI")])
2957
2958 (define_insn "*zero_extendqihi2_movzbw"
2959   [(set (match_operand:HI 0 "register_operand" "=r")
2960      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2961   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2962   "movz{bw|x}\t{%1, %0|%0, %1}"
2963   [(set_attr "type" "imovx")
2964    (set_attr "mode" "HI")])
2965
2966 ;; For the movzbw case strip only the clobber
2967 (define_split
2968   [(set (match_operand:HI 0 "register_operand" "")
2969         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2970    (clobber (reg:CC FLAGS_REG))]
2971   "reload_completed 
2972    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2973    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2974   [(set (match_operand:HI 0 "register_operand" "")
2975         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2976
2977 ;; When source and destination does not overlap, clear destination
2978 ;; first and then do the movb
2979 (define_split
2980   [(set (match_operand:HI 0 "register_operand" "")
2981         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2982    (clobber (reg:CC FLAGS_REG))]
2983   "reload_completed
2984    && ANY_QI_REG_P (operands[0])
2985    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2986    && !reg_overlap_mentioned_p (operands[0], operands[1])"
2987   [(set (match_dup 0) (const_int 0))
2988    (set (strict_low_part (match_dup 2)) (match_dup 1))]
2989   "operands[2] = gen_lowpart (QImode, operands[0]);")
2990
2991 ;; Rest is handled by single and.
2992 (define_split
2993   [(set (match_operand:HI 0 "register_operand" "")
2994         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
2995    (clobber (reg:CC FLAGS_REG))]
2996   "reload_completed
2997    && true_regnum (operands[0]) == true_regnum (operands[1])"
2998   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
2999               (clobber (reg:CC FLAGS_REG))])]
3000   "")
3001
3002 (define_expand "zero_extendqisi2"
3003   [(parallel
3004     [(set (match_operand:SI 0 "register_operand" "")
3005        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3006      (clobber (reg:CC FLAGS_REG))])]
3007   ""
3008   "")
3009
3010 (define_insn "*zero_extendqisi2_and"
3011   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3012      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3013    (clobber (reg:CC FLAGS_REG))]
3014   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3015   "#"
3016   [(set_attr "type" "alu1")
3017    (set_attr "mode" "SI")])
3018
3019 (define_insn "*zero_extendqisi2_movzbw_and"
3020   [(set (match_operand:SI 0 "register_operand" "=r,r")
3021      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3022    (clobber (reg:CC FLAGS_REG))]
3023   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3024   "#"
3025   [(set_attr "type" "imovx,alu1")
3026    (set_attr "mode" "SI")])
3027
3028 (define_insn "*zero_extendqisi2_movzbw"
3029   [(set (match_operand:SI 0 "register_operand" "=r")
3030      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3031   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3032   "movz{bl|x}\t{%1, %0|%0, %1}"
3033   [(set_attr "type" "imovx")
3034    (set_attr "mode" "SI")])
3035
3036 ;; For the movzbl case strip only the clobber
3037 (define_split
3038   [(set (match_operand:SI 0 "register_operand" "")
3039         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3040    (clobber (reg:CC FLAGS_REG))]
3041   "reload_completed 
3042    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3043    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3044   [(set (match_dup 0)
3045         (zero_extend:SI (match_dup 1)))])
3046
3047 ;; When source and destination does not overlap, clear destination
3048 ;; first and then do the movb
3049 (define_split
3050   [(set (match_operand:SI 0 "register_operand" "")
3051         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3052    (clobber (reg:CC FLAGS_REG))]
3053   "reload_completed
3054    && ANY_QI_REG_P (operands[0])
3055    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3056    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3057    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3058   [(set (match_dup 0) (const_int 0))
3059    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3060   "operands[2] = gen_lowpart (QImode, operands[0]);")
3061
3062 ;; Rest is handled by single and.
3063 (define_split
3064   [(set (match_operand:SI 0 "register_operand" "")
3065         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3066    (clobber (reg:CC FLAGS_REG))]
3067   "reload_completed
3068    && true_regnum (operands[0]) == true_regnum (operands[1])"
3069   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3070               (clobber (reg:CC FLAGS_REG))])]
3071   "")
3072
3073 ;; %%% Kill me once multi-word ops are sane.
3074 (define_expand "zero_extendsidi2"
3075   [(set (match_operand:DI 0 "register_operand" "=r")
3076      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3077   ""
3078   "if (!TARGET_64BIT)
3079      {
3080        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3081        DONE;
3082      }
3083   ")
3084
3085 (define_insn "zero_extendsidi2_32"
3086   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3087         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3088    (clobber (reg:CC FLAGS_REG))]
3089   "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3090   "@
3091    #
3092    #
3093    #
3094    movd\t{%1, %0|%0, %1}
3095    movd\t{%1, %0|%0, %1}"
3096   [(set_attr "mode" "SI,SI,SI,DI,TI")
3097    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3098
3099 (define_insn "*zero_extendsidi2_32_1"
3100   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3101         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3102    (clobber (reg:CC FLAGS_REG))]
3103   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3104   "@
3105    #
3106    #
3107    #
3108    movd\t{%1, %0|%0, %1}
3109    movd\t{%1, %0|%0, %1}"
3110   [(set_attr "mode" "SI,SI,SI,DI,TI")
3111    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3112
3113 (define_insn "zero_extendsidi2_rex64"
3114   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3115      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3116   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3117   "@
3118    mov\t{%k1, %k0|%k0, %k1}
3119    #
3120    movd\t{%1, %0|%0, %1}
3121    movd\t{%1, %0|%0, %1}"
3122   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3123    (set_attr "mode" "SI,DI,DI,TI")])
3124
3125 (define_insn "*zero_extendsidi2_rex64_1"
3126   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3127      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3128   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3129   "@
3130    mov\t{%k1, %k0|%k0, %k1}
3131    #
3132    movd\t{%1, %0|%0, %1}
3133    movd\t{%1, %0|%0, %1}"
3134   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3135    (set_attr "mode" "SI,DI,SI,SI")])
3136
3137 (define_split
3138   [(set (match_operand:DI 0 "memory_operand" "")
3139      (zero_extend:DI (match_dup 0)))]
3140   "TARGET_64BIT"
3141   [(set (match_dup 4) (const_int 0))]
3142   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3143
3144 (define_split 
3145   [(set (match_operand:DI 0 "register_operand" "")
3146         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3147    (clobber (reg:CC FLAGS_REG))]
3148   "!TARGET_64BIT && reload_completed
3149    && true_regnum (operands[0]) == true_regnum (operands[1])"
3150   [(set (match_dup 4) (const_int 0))]
3151   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3152
3153 (define_split 
3154   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3155         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3156    (clobber (reg:CC FLAGS_REG))]
3157   "!TARGET_64BIT && reload_completed
3158    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3159   [(set (match_dup 3) (match_dup 1))
3160    (set (match_dup 4) (const_int 0))]
3161   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3162
3163 (define_insn "zero_extendhidi2"
3164   [(set (match_operand:DI 0 "register_operand" "=r,r")
3165      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3166   "TARGET_64BIT"
3167   "@
3168    movz{wl|x}\t{%1, %k0|%k0, %1}
3169    movz{wq|x}\t{%1, %0|%0, %1}"
3170   [(set_attr "type" "imovx")
3171    (set_attr "mode" "SI,DI")])
3172
3173 (define_insn "zero_extendqidi2"
3174   [(set (match_operand:DI 0 "register_operand" "=r,r")
3175      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3176   "TARGET_64BIT"
3177   "@
3178    movz{bl|x}\t{%1, %k0|%k0, %1}
3179    movz{bq|x}\t{%1, %0|%0, %1}"
3180   [(set_attr "type" "imovx")
3181    (set_attr "mode" "SI,DI")])
3182 \f
3183 ;; Sign extension instructions
3184
3185 (define_expand "extendsidi2"
3186   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3187                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3188               (clobber (reg:CC FLAGS_REG))
3189               (clobber (match_scratch:SI 2 ""))])]
3190   ""
3191 {
3192   if (TARGET_64BIT)
3193     {
3194       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3195       DONE;
3196     }
3197 })
3198
3199 (define_insn "*extendsidi2_1"
3200   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3201         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3202    (clobber (reg:CC FLAGS_REG))
3203    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3204   "!TARGET_64BIT"
3205   "#")
3206
3207 (define_insn "extendsidi2_rex64"
3208   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3209         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3210   "TARGET_64BIT"
3211   "@
3212    {cltq|cdqe}
3213    movs{lq|x}\t{%1,%0|%0, %1}"
3214   [(set_attr "type" "imovx")
3215    (set_attr "mode" "DI")
3216    (set_attr "prefix_0f" "0")
3217    (set_attr "modrm" "0,1")])
3218
3219 (define_insn "extendhidi2"
3220   [(set (match_operand:DI 0 "register_operand" "=r")
3221         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3222   "TARGET_64BIT"
3223   "movs{wq|x}\t{%1,%0|%0, %1}"
3224   [(set_attr "type" "imovx")
3225    (set_attr "mode" "DI")])
3226
3227 (define_insn "extendqidi2"
3228   [(set (match_operand:DI 0 "register_operand" "=r")
3229         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3230   "TARGET_64BIT"
3231   "movs{bq|x}\t{%1,%0|%0, %1}"
3232    [(set_attr "type" "imovx")
3233     (set_attr "mode" "DI")])
3234
3235 ;; Extend to memory case when source register does die.
3236 (define_split 
3237   [(set (match_operand:DI 0 "memory_operand" "")
3238         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3239    (clobber (reg:CC FLAGS_REG))
3240    (clobber (match_operand:SI 2 "register_operand" ""))]
3241   "(reload_completed
3242     && dead_or_set_p (insn, operands[1])
3243     && !reg_mentioned_p (operands[1], operands[0]))"
3244   [(set (match_dup 3) (match_dup 1))
3245    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3246               (clobber (reg:CC FLAGS_REG))])
3247    (set (match_dup 4) (match_dup 1))]
3248   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3249
3250 ;; Extend to memory case when source register does not die.
3251 (define_split 
3252   [(set (match_operand:DI 0 "memory_operand" "")
3253         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3254    (clobber (reg:CC FLAGS_REG))
3255    (clobber (match_operand:SI 2 "register_operand" ""))]
3256   "reload_completed"
3257   [(const_int 0)]
3258 {
3259   split_di (&operands[0], 1, &operands[3], &operands[4]);
3260
3261   emit_move_insn (operands[3], operands[1]);
3262
3263   /* Generate a cltd if possible and doing so it profitable.  */
3264   if (true_regnum (operands[1]) == 0
3265       && true_regnum (operands[2]) == 1
3266       && (optimize_size || TARGET_USE_CLTD))
3267     {
3268       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3269     }
3270   else
3271     {
3272       emit_move_insn (operands[2], operands[1]);
3273       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3274     }
3275   emit_move_insn (operands[4], operands[2]);
3276   DONE;
3277 })
3278
3279 ;; Extend to register case.  Optimize case where source and destination
3280 ;; registers match and cases where we can use cltd.
3281 (define_split 
3282   [(set (match_operand:DI 0 "register_operand" "")
3283         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3284    (clobber (reg:CC FLAGS_REG))
3285    (clobber (match_scratch:SI 2 ""))]
3286   "reload_completed"
3287   [(const_int 0)]
3288 {
3289   split_di (&operands[0], 1, &operands[3], &operands[4]);
3290
3291   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3292     emit_move_insn (operands[3], operands[1]);
3293
3294   /* Generate a cltd if possible and doing so it profitable.  */
3295   if (true_regnum (operands[3]) == 0
3296       && (optimize_size || TARGET_USE_CLTD))
3297     {
3298       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3299       DONE;
3300     }
3301
3302   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3303     emit_move_insn (operands[4], operands[1]);
3304
3305   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3306   DONE;
3307 })
3308
3309 (define_insn "extendhisi2"
3310   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3311         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3312   ""
3313 {
3314   switch (get_attr_prefix_0f (insn))
3315     {
3316     case 0:
3317       return "{cwtl|cwde}";
3318     default:
3319       return "movs{wl|x}\t{%1,%0|%0, %1}";
3320     }
3321 }
3322   [(set_attr "type" "imovx")
3323    (set_attr "mode" "SI")
3324    (set (attr "prefix_0f")
3325      ;; movsx is short decodable while cwtl is vector decoded.
3326      (if_then_else (and (eq_attr "cpu" "!k6")
3327                         (eq_attr "alternative" "0"))
3328         (const_string "0")
3329         (const_string "1")))
3330    (set (attr "modrm")
3331      (if_then_else (eq_attr "prefix_0f" "0")
3332         (const_string "0")
3333         (const_string "1")))])
3334
3335 (define_insn "*extendhisi2_zext"
3336   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3337         (zero_extend:DI
3338           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3339   "TARGET_64BIT"
3340 {
3341   switch (get_attr_prefix_0f (insn))
3342     {
3343     case 0:
3344       return "{cwtl|cwde}";
3345     default:
3346       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3347     }
3348 }
3349   [(set_attr "type" "imovx")
3350    (set_attr "mode" "SI")
3351    (set (attr "prefix_0f")
3352      ;; movsx is short decodable while cwtl is vector decoded.
3353      (if_then_else (and (eq_attr "cpu" "!k6")
3354                         (eq_attr "alternative" "0"))
3355         (const_string "0")
3356         (const_string "1")))
3357    (set (attr "modrm")
3358      (if_then_else (eq_attr "prefix_0f" "0")
3359         (const_string "0")
3360         (const_string "1")))])
3361
3362 (define_insn "extendqihi2"
3363   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3364         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3365   ""
3366 {
3367   switch (get_attr_prefix_0f (insn))
3368     {
3369     case 0:
3370       return "{cbtw|cbw}";
3371     default:
3372       return "movs{bw|x}\t{%1,%0|%0, %1}";
3373     }
3374 }
3375   [(set_attr "type" "imovx")
3376    (set_attr "mode" "HI")
3377    (set (attr "prefix_0f")
3378      ;; movsx is short decodable while cwtl is vector decoded.
3379      (if_then_else (and (eq_attr "cpu" "!k6")
3380                         (eq_attr "alternative" "0"))
3381         (const_string "0")
3382         (const_string "1")))
3383    (set (attr "modrm")
3384      (if_then_else (eq_attr "prefix_0f" "0")
3385         (const_string "0")
3386         (const_string "1")))])
3387
3388 (define_insn "extendqisi2"
3389   [(set (match_operand:SI 0 "register_operand" "=r")
3390         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3391   ""
3392   "movs{bl|x}\t{%1,%0|%0, %1}"
3393    [(set_attr "type" "imovx")
3394     (set_attr "mode" "SI")])
3395
3396 (define_insn "*extendqisi2_zext"
3397   [(set (match_operand:DI 0 "register_operand" "=r")
3398         (zero_extend:DI
3399           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3400   "TARGET_64BIT"
3401   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3402    [(set_attr "type" "imovx")
3403     (set_attr "mode" "SI")])
3404 \f
3405 ;; Conversions between float and double.
3406
3407 ;; These are all no-ops in the model used for the 80387.  So just
3408 ;; emit moves.
3409
3410 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3411 (define_insn "*dummy_extendsfdf2"
3412   [(set (match_operand:DF 0 "push_operand" "=<")
3413         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3414   "0"
3415   "#")
3416
3417 (define_split
3418   [(set (match_operand:DF 0 "push_operand" "")
3419         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3420   "!TARGET_64BIT"
3421   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3422    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3423
3424 (define_split
3425   [(set (match_operand:DF 0 "push_operand" "")
3426         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3427   "TARGET_64BIT"
3428   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3429    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3430
3431 (define_insn "*dummy_extendsfxf2"
3432   [(set (match_operand:XF 0 "push_operand" "=<")
3433         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3434   "0"
3435   "#")
3436
3437 (define_split
3438   [(set (match_operand:XF 0 "push_operand" "")
3439         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3440   ""
3441   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3442    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3443   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3444
3445 (define_split
3446   [(set (match_operand:XF 0 "push_operand" "")
3447         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3448   "TARGET_64BIT"
3449   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3450    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3451   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3452
3453 (define_split
3454   [(set (match_operand:XF 0 "push_operand" "")
3455         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3456   ""
3457   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3458    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3459   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3460
3461 (define_split
3462   [(set (match_operand:XF 0 "push_operand" "")
3463         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3464   "TARGET_64BIT"
3465   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3466    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3467   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3468
3469 (define_expand "extendsfdf2"
3470   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3471         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3472   "TARGET_80387 || TARGET_SSE2"
3473 {
3474   /* ??? Needed for compress_float_constant since all fp constants
3475      are LEGITIMATE_CONSTANT_P.  */
3476   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3477     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3478   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3479     operands[1] = force_reg (SFmode, operands[1]);
3480 })
3481
3482 (define_insn "*extendsfdf2_1"
3483   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3484         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3485   "(TARGET_80387 || TARGET_SSE2)
3486    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3487 {
3488   switch (which_alternative)
3489     {
3490     case 0:
3491       return output_387_reg_move (insn, operands);
3492
3493     case 1:
3494       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3495         return "fstp%z0\t%y0";
3496       else
3497         return "fst%z0\t%y0";
3498
3499     case 2:
3500       return "cvtss2sd\t{%1, %0|%0, %1}";
3501
3502     default:
3503       abort ();
3504     }
3505 }
3506   [(set_attr "type" "fmov,fmov,ssecvt")
3507    (set_attr "mode" "SF,XF,DF")])
3508
3509 (define_insn "*extendsfdf2_1_sse_only"
3510   [(set (match_operand:DF 0 "register_operand" "=Y")
3511         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3512   "!TARGET_80387 && TARGET_SSE2
3513    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3514   "cvtss2sd\t{%1, %0|%0, %1}"
3515   [(set_attr "type" "ssecvt")
3516    (set_attr "mode" "DF")])
3517
3518 (define_expand "extendsfxf2"
3519   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3520         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3521   "TARGET_80387"
3522 {
3523   /* ??? Needed for compress_float_constant since all fp constants
3524      are LEGITIMATE_CONSTANT_P.  */
3525   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3526     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3527   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3528     operands[1] = force_reg (SFmode, operands[1]);
3529 })
3530
3531 (define_insn "*extendsfxf2_1"
3532   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3533         (float_extend:XF (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       /* There is no non-popping store to memory for XFmode.  So if
3544          we need one, follow the store with a load.  */
3545       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3546         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3547       else
3548         return "fstp%z0\t%y0";
3549
3550     default:
3551       abort ();
3552     }
3553 }
3554   [(set_attr "type" "fmov")
3555    (set_attr "mode" "SF,XF")])
3556
3557 (define_expand "extenddfxf2"
3558   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3559         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3560   "TARGET_80387"
3561 {
3562   /* ??? Needed for compress_float_constant since all fp constants
3563      are LEGITIMATE_CONSTANT_P.  */
3564   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3565     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3566   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3567     operands[1] = force_reg (DFmode, operands[1]);
3568 })
3569
3570 (define_insn "*extenddfxf2_1"
3571   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3572         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3573   "TARGET_80387
3574    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3575 {
3576   switch (which_alternative)
3577     {
3578     case 0:
3579       return output_387_reg_move (insn, operands);
3580
3581     case 1:
3582       /* There is no non-popping store to memory for XFmode.  So if
3583          we need one, follow the store with a load.  */
3584       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3585         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3586       else
3587         return "fstp%z0\t%y0";
3588
3589     default:
3590       abort ();
3591     }
3592 }
3593   [(set_attr "type" "fmov")
3594    (set_attr "mode" "DF,XF")])
3595
3596 ;; %%% This seems bad bad news.
3597 ;; This cannot output into an f-reg because there is no way to be sure
3598 ;; of truncating in that case.  Otherwise this is just like a simple move
3599 ;; insn.  So we pretend we can output to a reg in order to get better
3600 ;; register preferencing, but we really use a stack slot.
3601
3602 (define_expand "truncdfsf2"
3603   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3604                    (float_truncate:SF
3605                     (match_operand:DF 1 "register_operand" "")))
3606               (clobber (match_dup 2))])]
3607   "TARGET_80387 || TARGET_SSE2"
3608   "
3609    if (!TARGET_80387)
3610      {
3611         emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3612         DONE;
3613      }
3614    else if (flag_unsafe_math_optimizations)
3615      {
3616         rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3617         emit_insn (gen_truncdfsf2_noop (reg, operands[1]));
3618         if (reg != operands[0])
3619           emit_move_insn (operands[0], reg);
3620         DONE;
3621      }
3622    else
3623      operands[2] = assign_386_stack_local (SFmode, 0);
3624 ")
3625
3626 (define_insn "truncdfsf2_noop"
3627   [(set (match_operand:SF 0 "register_operand" "=f")
3628         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3629   "TARGET_80387 && flag_unsafe_math_optimizations"
3630 {
3631   return output_387_reg_move (insn, operands);
3632 }
3633   [(set_attr "type" "fmov")
3634    (set_attr "mode" "SF")])
3635
3636 (define_insn "*truncdfsf2_1"
3637   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3638         (float_truncate:SF
3639          (match_operand:DF 1 "register_operand" "f,f,f,f")))
3640    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3641   "TARGET_80387 && !TARGET_SSE2"
3642 {
3643   switch (which_alternative)
3644     {
3645     case 0:
3646       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3647         return "fstp%z0\t%y0";
3648       else
3649         return "fst%z0\t%y0";
3650     default:
3651       abort ();
3652     }
3653 }
3654   [(set_attr "type" "fmov,multi,multi,multi")
3655    (set_attr "mode" "SF,SF,SF,SF")])
3656
3657 (define_insn "*truncdfsf2_1_sse"
3658   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3659         (float_truncate:SF
3660          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3661    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3662   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3663 {
3664   switch (which_alternative)
3665     {
3666     case 0:
3667       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3668         return "fstp%z0\t%y0";
3669       else
3670         return "fst%z0\t%y0";
3671     case 4:
3672       return "#";
3673     default:
3674       abort ();
3675     }
3676 }
3677   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3678    (set_attr "mode" "SF,SF,SF,SF,DF")])
3679
3680 (define_insn "*truncdfsf2_1_sse_nooverlap"
3681   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3682         (float_truncate:SF
3683          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3684    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3685   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3686 {
3687   switch (which_alternative)
3688     {
3689     case 0:
3690       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3691         return "fstp%z0\t%y0";
3692       else
3693         return "fst%z0\t%y0";
3694     case 4:
3695       return "#";
3696     default:
3697       abort ();
3698     }
3699 }
3700   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3701    (set_attr "mode" "SF,SF,SF,SF,DF")])
3702
3703 (define_insn "*truncdfsf2_2"
3704   [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3705         (float_truncate:SF
3706          (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3707   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3708    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3709 {
3710   switch (which_alternative)
3711     {
3712     case 0:
3713     case 1:
3714       return "cvtsd2ss\t{%1, %0|%0, %1}";
3715     case 2:
3716       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3717         return "fstp%z0\t%y0";
3718       else
3719         return "fst%z0\t%y0";
3720     default:
3721       abort ();
3722     }
3723 }
3724   [(set_attr "type" "ssecvt,ssecvt,fmov")
3725    (set_attr "athlon_decode" "vector,double,*")
3726    (set_attr "mode" "SF,SF,SF")])
3727
3728 (define_insn "*truncdfsf2_2_nooverlap"
3729   [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3730         (float_truncate:SF
3731          (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3732   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3733    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3734 {
3735   switch (which_alternative)
3736     {
3737     case 0:
3738       return "#";
3739     case 1:
3740       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3741         return "fstp%z0\t%y0";
3742       else
3743         return "fst%z0\t%y0";
3744     default:
3745       abort ();
3746     }
3747 }
3748   [(set_attr "type" "ssecvt,fmov")
3749    (set_attr "mode" "DF,SF")])
3750
3751 (define_insn "*truncdfsf2_3"
3752   [(set (match_operand:SF 0 "memory_operand" "=m")
3753         (float_truncate:SF
3754          (match_operand:DF 1 "register_operand" "f")))]
3755   "TARGET_80387"
3756 {
3757   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3758     return "fstp%z0\t%y0";
3759   else
3760     return "fst%z0\t%y0";
3761 }
3762   [(set_attr "type" "fmov")
3763    (set_attr "mode" "SF")])
3764
3765 (define_insn "truncdfsf2_sse_only"
3766   [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3767         (float_truncate:SF
3768          (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3769   "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3770   "cvtsd2ss\t{%1, %0|%0, %1}"
3771   [(set_attr "type" "ssecvt")
3772    (set_attr "athlon_decode" "vector,double")
3773    (set_attr "mode" "SF")])
3774
3775 (define_insn "*truncdfsf2_sse_only_nooverlap"
3776   [(set (match_operand:SF 0 "register_operand" "=&Y")
3777         (float_truncate:SF
3778          (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3779   "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3780   "#"
3781   [(set_attr "type" "ssecvt")
3782    (set_attr "mode" "DF")])
3783
3784 (define_split
3785   [(set (match_operand:SF 0 "memory_operand" "")
3786         (float_truncate:SF
3787          (match_operand:DF 1 "register_operand" "")))
3788    (clobber (match_operand:SF 2 "memory_operand" ""))]
3789   "TARGET_80387"
3790   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3791   "")
3792
3793 ; Avoid possible reformatting penalty on the destination by first
3794 ; zeroing it out
3795 (define_split
3796   [(set (match_operand:SF 0 "register_operand" "")
3797         (float_truncate:SF
3798          (match_operand:DF 1 "nonimmediate_operand" "")))
3799    (clobber (match_operand 2 "" ""))]
3800   "TARGET_80387 && reload_completed
3801    && SSE_REG_P (operands[0])
3802    && !STACK_REG_P (operands[1])"
3803   [(const_int 0)]
3804 {
3805   rtx src, dest;
3806   if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3807     emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3808   else
3809     {
3810       dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3811       src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3812       /* simplify_gen_subreg refuses to widen memory references.  */
3813       if (GET_CODE (src) == SUBREG)
3814         alter_subreg (&src);
3815       if (reg_overlap_mentioned_p (operands[0], operands[1]))
3816         abort ();
3817       emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3818       emit_insn (gen_cvtsd2ss (dest, dest, src));
3819     }
3820   DONE;
3821 })
3822
3823 (define_split
3824   [(set (match_operand:SF 0 "register_operand" "")
3825         (float_truncate:SF
3826          (match_operand:DF 1 "nonimmediate_operand" "")))]
3827   "TARGET_80387 && reload_completed
3828    && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3829   [(const_int 0)]
3830 {
3831   rtx src, dest;
3832   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3833   src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3834   /* simplify_gen_subreg refuses to widen memory references.  */
3835   if (GET_CODE (src) == SUBREG)
3836     alter_subreg (&src);
3837   if (reg_overlap_mentioned_p (operands[0], operands[1]))
3838     abort ();
3839   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3840   emit_insn (gen_cvtsd2ss (dest, dest, src));
3841   DONE;
3842 })
3843
3844 (define_split
3845   [(set (match_operand:SF 0 "register_operand" "")
3846         (float_truncate:SF
3847          (match_operand:DF 1 "fp_register_operand" "")))
3848    (clobber (match_operand:SF 2 "memory_operand" ""))]
3849   "TARGET_80387 && reload_completed"
3850   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3851    (set (match_dup 0) (match_dup 2))]
3852   "")
3853
3854 (define_expand "truncxfsf2"
3855   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3856                    (float_truncate:SF
3857                     (match_operand:XF 1 "register_operand" "")))
3858               (clobber (match_dup 2))])]
3859   "TARGET_80387"
3860   "
3861   if (flag_unsafe_math_optimizations)
3862     {
3863       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3864       emit_insn (gen_truncxfsf2_noop (reg, operands[1]));
3865       if (reg != operands[0])
3866         emit_move_insn (operands[0], reg);
3867       DONE;
3868     }
3869   else
3870     operands[2] = assign_386_stack_local (SFmode, 0);
3871   ")
3872
3873 (define_insn "truncxfsf2_noop"
3874   [(set (match_operand:SF 0 "register_operand" "=f")
3875         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3876   "TARGET_80387 && flag_unsafe_math_optimizations"
3877 {
3878   return output_387_reg_move (insn, operands);
3879 }
3880   [(set_attr "type" "fmov")
3881    (set_attr "mode" "SF")])
3882
3883 (define_insn "*truncxfsf2_1"
3884   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3885         (float_truncate:SF
3886          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3887    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3888   "TARGET_80387"
3889 {
3890   switch (which_alternative)
3891     {
3892     case 0:
3893       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3894         return "fstp%z0\t%y0";
3895       else
3896         return "fst%z0\t%y0";
3897     default:
3898       abort();
3899     }
3900 }
3901   [(set_attr "type" "fmov,multi,multi,multi")
3902    (set_attr "mode" "SF")])
3903
3904 (define_insn "*truncxfsf2_2"
3905   [(set (match_operand:SF 0 "memory_operand" "=m")
3906         (float_truncate:SF
3907          (match_operand:XF 1 "register_operand" "f")))]
3908   "TARGET_80387"
3909 {
3910   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3911     return "fstp%z0\t%y0";
3912   else
3913     return "fst%z0\t%y0";
3914 }
3915   [(set_attr "type" "fmov")
3916    (set_attr "mode" "SF")])
3917
3918 (define_split
3919   [(set (match_operand:SF 0 "memory_operand" "")
3920         (float_truncate:SF
3921          (match_operand:XF 1 "register_operand" "")))
3922    (clobber (match_operand:SF 2 "memory_operand" ""))]
3923   "TARGET_80387"
3924   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3925   "")
3926
3927 (define_split
3928   [(set (match_operand:SF 0 "register_operand" "")
3929         (float_truncate:SF
3930          (match_operand:XF 1 "register_operand" "")))
3931    (clobber (match_operand:SF 2 "memory_operand" ""))]
3932   "TARGET_80387 && reload_completed"
3933   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3934    (set (match_dup 0) (match_dup 2))]
3935   "")
3936
3937 (define_expand "truncxfdf2"
3938   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3939                    (float_truncate:DF
3940                     (match_operand:XF 1 "register_operand" "")))
3941               (clobber (match_dup 2))])]
3942   "TARGET_80387"
3943   "
3944   if (flag_unsafe_math_optimizations)
3945     {
3946       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3947       emit_insn (gen_truncxfdf2_noop (reg, operands[1]));
3948       if (reg != operands[0])
3949         emit_move_insn (operands[0], reg);
3950       DONE;
3951     }
3952   else
3953     operands[2] = assign_386_stack_local (DFmode, 0);
3954   ")
3955
3956 (define_insn "truncxfdf2_noop"
3957   [(set (match_operand:DF 0 "register_operand" "=f")
3958         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3959   "TARGET_80387 && flag_unsafe_math_optimizations"
3960 {
3961   return output_387_reg_move (insn, operands);
3962 }
3963   [(set_attr "type" "fmov")
3964    (set_attr "mode" "DF")])
3965
3966 (define_insn "*truncxfdf2_1"
3967   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3968         (float_truncate:DF
3969          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3970    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3971   "TARGET_80387"
3972 {
3973   switch (which_alternative)
3974     {
3975     case 0:
3976       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3977         return "fstp%z0\t%y0";
3978       else
3979         return "fst%z0\t%y0";
3980     default:
3981       abort();
3982     }
3983   abort ();
3984 }
3985   [(set_attr "type" "fmov,multi,multi,multi")
3986    (set_attr "mode" "DF")])
3987
3988 (define_insn "*truncxfdf2_2"
3989   [(set (match_operand:DF 0 "memory_operand" "=m")
3990         (float_truncate:DF
3991           (match_operand:XF 1 "register_operand" "f")))]
3992   "TARGET_80387"
3993 {
3994   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3995     return "fstp%z0\t%y0";
3996   else
3997     return "fst%z0\t%y0";
3998 }
3999   [(set_attr "type" "fmov")
4000    (set_attr "mode" "DF")])
4001
4002 (define_split
4003   [(set (match_operand:DF 0 "memory_operand" "")
4004         (float_truncate:DF
4005          (match_operand:XF 1 "register_operand" "")))
4006    (clobber (match_operand:DF 2 "memory_operand" ""))]
4007   "TARGET_80387"
4008   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4009   "")
4010
4011 (define_split
4012   [(set (match_operand:DF 0 "register_operand" "")
4013         (float_truncate:DF
4014          (match_operand:XF 1 "register_operand" "")))
4015    (clobber (match_operand:DF 2 "memory_operand" ""))]
4016   "TARGET_80387 && reload_completed"
4017   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4018    (set (match_dup 0) (match_dup 2))]
4019   "")
4020
4021 \f
4022 ;; %%% Break up all these bad boys.
4023
4024 ;; Signed conversion to DImode.
4025
4026 (define_expand "fix_truncxfdi2"
4027   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4028                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4029               (clobber (reg:CC FLAGS_REG))])]
4030   "TARGET_80387"
4031   "")
4032
4033 (define_expand "fix_truncdfdi2"
4034   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4035                    (fix:DI (match_operand:DF 1 "register_operand" "")))
4036               (clobber (reg:CC FLAGS_REG))])]
4037   "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4038 {
4039   if (TARGET_64BIT && TARGET_SSE2)
4040    {
4041      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4042      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4043      if (out != operands[0])
4044         emit_move_insn (operands[0], out);
4045      DONE;
4046    }
4047 })
4048
4049 (define_expand "fix_truncsfdi2"
4050   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4051                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4052               (clobber (reg:CC FLAGS_REG))])] 
4053   "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4054 {
4055   if (TARGET_SSE && TARGET_64BIT)
4056    {
4057      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4058      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4059      if (out != operands[0])
4060         emit_move_insn (operands[0], out);
4061      DONE;
4062    }
4063 })
4064
4065 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4066 ;; of the machinery.
4067 (define_insn_and_split "*fix_truncdi_1"
4068   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4069         (fix:DI (match_operand 1 "register_operand" "f,f")))
4070    (clobber (reg:CC FLAGS_REG))]
4071   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4072    && !reload_completed && !reload_in_progress
4073    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4074   "#"
4075   "&& 1"
4076   [(const_int 0)]
4077 {
4078   ix86_optimize_mode_switching = 1;
4079   operands[2] = assign_386_stack_local (HImode, 1);
4080   operands[3] = assign_386_stack_local (HImode, 2);
4081   if (memory_operand (operands[0], VOIDmode))
4082     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4083                                        operands[2], operands[3]));
4084   else
4085     {
4086       operands[4] = assign_386_stack_local (DImode, 0);
4087       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4088                                            operands[2], operands[3],
4089                                            operands[4]));
4090     }
4091   DONE;
4092 }
4093   [(set_attr "type" "fistp")
4094    (set_attr "mode" "DI")])
4095
4096 (define_insn "fix_truncdi_nomemory"
4097   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4098         (fix:DI (match_operand 1 "register_operand" "f,f")))
4099    (use (match_operand:HI 2 "memory_operand" "m,m"))
4100    (use (match_operand:HI 3 "memory_operand" "m,m"))
4101    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4102    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4103   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4104    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4105   "#"
4106   [(set_attr "type" "fistp")
4107    (set_attr "mode" "DI")])
4108
4109 (define_insn "fix_truncdi_memory"
4110   [(set (match_operand:DI 0 "memory_operand" "=m")
4111         (fix:DI (match_operand 1 "register_operand" "f")))
4112    (use (match_operand:HI 2 "memory_operand" "m"))
4113    (use (match_operand:HI 3 "memory_operand" "m"))
4114    (clobber (match_scratch:DF 4 "=&1f"))]
4115   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4116    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4117   "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4118   [(set_attr "type" "fistp")
4119    (set_attr "mode" "DI")])
4120
4121 (define_split 
4122   [(set (match_operand:DI 0 "register_operand" "")
4123         (fix:DI (match_operand 1 "register_operand" "")))
4124    (use (match_operand:HI 2 "memory_operand" ""))
4125    (use (match_operand:HI 3 "memory_operand" ""))
4126    (clobber (match_operand:DI 4 "memory_operand" ""))
4127    (clobber (match_scratch 5 ""))]
4128   "reload_completed"
4129   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4130               (use (match_dup 2))
4131               (use (match_dup 3))
4132               (clobber (match_dup 5))])
4133    (set (match_dup 0) (match_dup 4))]
4134   "")
4135
4136 (define_split 
4137   [(set (match_operand:DI 0 "memory_operand" "")
4138         (fix:DI (match_operand 1 "register_operand" "")))
4139    (use (match_operand:HI 2 "memory_operand" ""))
4140    (use (match_operand:HI 3 "memory_operand" ""))
4141    (clobber (match_operand:DI 4 "memory_operand" ""))
4142    (clobber (match_scratch 5 ""))]
4143   "reload_completed"
4144   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4145               (use (match_dup 2))
4146               (use (match_dup 3))
4147               (clobber (match_dup 5))])]
4148   "")
4149
4150 ;; When SSE available, it is always faster to use it!
4151 (define_insn "fix_truncsfdi_sse"
4152   [(set (match_operand:DI 0 "register_operand" "=r,r")
4153         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4154   "TARGET_64BIT && TARGET_SSE"
4155   "cvttss2si{q}\t{%1, %0|%0, %1}"
4156   [(set_attr "type" "sseicvt")
4157    (set_attr "mode" "SF")
4158    (set_attr "athlon_decode" "double,vector")])
4159
4160 ;; Avoid vector decoded form of the instruction.
4161 (define_peephole2
4162   [(match_scratch:SF 2 "x")
4163    (set (match_operand:DI 0 "register_operand" "")
4164         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4165   "TARGET_K8 && !optimize_size"
4166   [(set (match_dup 2) (match_dup 1))
4167    (set (match_dup 0) (fix:DI (match_dup 2)))]
4168   "")
4169
4170 (define_insn "fix_truncdfdi_sse"
4171   [(set (match_operand:DI 0 "register_operand" "=r,r")
4172         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4173   "TARGET_64BIT && TARGET_SSE2"
4174   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4175   [(set_attr "type" "sseicvt,sseicvt")
4176    (set_attr "mode" "DF")
4177    (set_attr "athlon_decode" "double,vector")])
4178
4179 ;; Avoid vector decoded form of the instruction.
4180 (define_peephole2
4181   [(match_scratch:DF 2 "Y")
4182    (set (match_operand:DI 0 "register_operand" "")
4183         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4184   "TARGET_K8 && !optimize_size"
4185   [(set (match_dup 2) (match_dup 1))
4186    (set (match_dup 0) (fix:DI (match_dup 2)))]
4187   "")
4188
4189 ;; Signed conversion to SImode.
4190
4191 (define_expand "fix_truncxfsi2"
4192   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4193                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4194               (clobber (reg:CC FLAGS_REG))])]
4195   "TARGET_80387"
4196   "")
4197
4198 (define_expand "fix_truncdfsi2"
4199   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4200                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4201               (clobber (reg:CC FLAGS_REG))])]
4202   "TARGET_80387 || TARGET_SSE2"
4203 {
4204   if (TARGET_SSE2)
4205    {
4206      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4207      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4208      if (out != operands[0])
4209         emit_move_insn (operands[0], out);
4210      DONE;
4211    }
4212 })
4213
4214 (define_expand "fix_truncsfsi2"
4215   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4216                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4217               (clobber (reg:CC FLAGS_REG))])] 
4218   "TARGET_80387 || TARGET_SSE"
4219 {
4220   if (TARGET_SSE)
4221    {
4222      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4223      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4224      if (out != operands[0])
4225         emit_move_insn (operands[0], out);
4226      DONE;
4227    }
4228 })
4229
4230 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4231 ;; of the machinery.
4232 (define_insn_and_split "*fix_truncsi_1"
4233   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4234         (fix:SI (match_operand 1 "register_operand" "f,f")))
4235    (clobber (reg:CC FLAGS_REG))]
4236   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4237    && !reload_completed && !reload_in_progress
4238    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4239   "#"
4240   "&& 1"
4241   [(const_int 0)]
4242 {
4243   ix86_optimize_mode_switching = 1;
4244   operands[2] = assign_386_stack_local (HImode, 1);
4245   operands[3] = assign_386_stack_local (HImode, 2);
4246   if (memory_operand (operands[0], VOIDmode))
4247     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4248                                        operands[2], operands[3]));
4249   else
4250     {
4251       operands[4] = assign_386_stack_local (SImode, 0);
4252       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4253                                            operands[2], operands[3],
4254                                            operands[4]));
4255     }
4256   DONE;
4257 }
4258   [(set_attr "type" "fistp")
4259    (set_attr "mode" "SI")])
4260
4261 (define_insn "fix_truncsi_nomemory"
4262   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4263         (fix:SI (match_operand 1 "register_operand" "f,f")))
4264    (use (match_operand:HI 2 "memory_operand" "m,m"))
4265    (use (match_operand:HI 3 "memory_operand" "m,m"))
4266    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4267   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4268    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4269   "#"
4270   [(set_attr "type" "fistp")
4271    (set_attr "mode" "SI")])
4272
4273 (define_insn "fix_truncsi_memory"
4274   [(set (match_operand:SI 0 "memory_operand" "=m")
4275         (fix:SI (match_operand 1 "register_operand" "f")))
4276    (use (match_operand:HI 2 "memory_operand" "m"))
4277    (use (match_operand:HI 3 "memory_operand" "m"))]
4278   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4279    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4280   "* return output_fix_trunc (insn, operands);"
4281   [(set_attr "type" "fistp")
4282    (set_attr "mode" "SI")])
4283
4284 ;; When SSE available, it is always faster to use it!
4285 (define_insn "fix_truncsfsi_sse"
4286   [(set (match_operand:SI 0 "register_operand" "=r,r")
4287         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4288   "TARGET_SSE"
4289   "cvttss2si\t{%1, %0|%0, %1}"
4290   [(set_attr "type" "sseicvt")
4291    (set_attr "mode" "DF")
4292    (set_attr "athlon_decode" "double,vector")])
4293
4294 ;; Avoid vector decoded form of the instruction.
4295 (define_peephole2
4296   [(match_scratch:SF 2 "x")
4297    (set (match_operand:SI 0 "register_operand" "")
4298         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4299   "TARGET_K8 && !optimize_size"
4300   [(set (match_dup 2) (match_dup 1))
4301    (set (match_dup 0) (fix:SI (match_dup 2)))]
4302   "")
4303
4304 (define_insn "fix_truncdfsi_sse"
4305   [(set (match_operand:SI 0 "register_operand" "=r,r")
4306         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4307   "TARGET_SSE2"
4308   "cvttsd2si\t{%1, %0|%0, %1}"
4309   [(set_attr "type" "sseicvt")
4310    (set_attr "mode" "DF")
4311    (set_attr "athlon_decode" "double,vector")])
4312
4313 ;; Avoid vector decoded form of the instruction.
4314 (define_peephole2
4315   [(match_scratch:DF 2 "Y")
4316    (set (match_operand:SI 0 "register_operand" "")
4317         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4318   "TARGET_K8 && !optimize_size"
4319   [(set (match_dup 2) (match_dup 1))
4320    (set (match_dup 0) (fix:SI (match_dup 2)))]
4321   "")
4322
4323 (define_split 
4324   [(set (match_operand:SI 0 "register_operand" "")
4325         (fix:SI (match_operand 1 "register_operand" "")))
4326    (use (match_operand:HI 2 "memory_operand" ""))
4327    (use (match_operand:HI 3 "memory_operand" ""))
4328    (clobber (match_operand:SI 4 "memory_operand" ""))]
4329   "reload_completed"
4330   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4331               (use (match_dup 2))
4332               (use (match_dup 3))])
4333    (set (match_dup 0) (match_dup 4))]
4334   "")
4335
4336 (define_split 
4337   [(set (match_operand:SI 0 "memory_operand" "")
4338         (fix:SI (match_operand 1 "register_operand" "")))
4339    (use (match_operand:HI 2 "memory_operand" ""))
4340    (use (match_operand:HI 3 "memory_operand" ""))
4341    (clobber (match_operand:SI 4 "memory_operand" ""))]
4342   "reload_completed"
4343   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4344               (use (match_dup 2))
4345               (use (match_dup 3))])]
4346   "")
4347
4348 ;; Signed conversion to HImode.
4349
4350 (define_expand "fix_truncxfhi2"
4351   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4352                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4353               (clobber (reg:CC FLAGS_REG))])] 
4354   "TARGET_80387"
4355   "")
4356
4357 (define_expand "fix_truncdfhi2"
4358   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4359                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4360               (clobber (reg:CC FLAGS_REG))])]
4361   "TARGET_80387 && !TARGET_SSE2"
4362   "")
4363
4364 (define_expand "fix_truncsfhi2"
4365   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4366                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4367                (clobber (reg:CC FLAGS_REG))])]
4368   "TARGET_80387 && !TARGET_SSE"
4369   "")
4370
4371 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4372 ;; of the machinery.
4373 (define_insn_and_split "*fix_trunchi_1"
4374   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4375         (fix:HI (match_operand 1 "register_operand" "f,f")))
4376    (clobber (reg:CC FLAGS_REG))]
4377   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4378    && !reload_completed && !reload_in_progress
4379    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4380   "#"
4381   ""
4382   [(const_int 0)]
4383 {
4384   ix86_optimize_mode_switching = 1;
4385   operands[2] = assign_386_stack_local (HImode, 1);
4386   operands[3] = assign_386_stack_local (HImode, 2);
4387   if (memory_operand (operands[0], VOIDmode))
4388     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4389                                        operands[2], operands[3]));
4390   else
4391     {
4392       operands[4] = assign_386_stack_local (HImode, 0);
4393       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4394                                            operands[2], operands[3],
4395                                            operands[4]));
4396     }
4397   DONE;
4398 }
4399   [(set_attr "type" "fistp")
4400    (set_attr "mode" "HI")])
4401
4402 (define_insn "fix_trunchi_nomemory"
4403   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4404         (fix:HI (match_operand 1 "register_operand" "f,f")))
4405    (use (match_operand:HI 2 "memory_operand" "m,m"))
4406    (use (match_operand:HI 3 "memory_operand" "m,m"))
4407    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4408   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4409    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4410   "#"
4411   [(set_attr "type" "fistp")
4412    (set_attr "mode" "HI")])
4413
4414 (define_insn "fix_trunchi_memory"
4415   [(set (match_operand:HI 0 "memory_operand" "=m")
4416         (fix:HI (match_operand 1 "register_operand" "f")))
4417    (use (match_operand:HI 2 "memory_operand" "m"))
4418    (use (match_operand:HI 3 "memory_operand" "m"))]
4419   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4420    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4421   "* return output_fix_trunc (insn, operands);"
4422   [(set_attr "type" "fistp")
4423    (set_attr "mode" "HI")])
4424
4425 (define_split 
4426   [(set (match_operand:HI 0 "memory_operand" "")
4427         (fix:HI (match_operand 1 "register_operand" "")))
4428    (use (match_operand:HI 2 "memory_operand" ""))
4429    (use (match_operand:HI 3 "memory_operand" ""))
4430    (clobber (match_operand:HI 4 "memory_operand" ""))]
4431   "reload_completed"
4432   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4433               (use (match_dup 2))
4434               (use (match_dup 3))])]
4435   "")
4436
4437 (define_split 
4438   [(set (match_operand:HI 0 "register_operand" "")
4439         (fix:HI (match_operand 1 "register_operand" "")))
4440    (use (match_operand:HI 2 "memory_operand" ""))
4441    (use (match_operand:HI 3 "memory_operand" ""))
4442    (clobber (match_operand:HI 4 "memory_operand" ""))]
4443   "reload_completed"
4444   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4445               (use (match_dup 2))
4446               (use (match_dup 3))
4447               (clobber (match_dup 4))])
4448    (set (match_dup 0) (match_dup 4))]
4449   "")
4450
4451 ;; %% Not used yet.
4452 (define_insn "x86_fnstcw_1"
4453   [(set (match_operand:HI 0 "memory_operand" "=m")
4454         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4455   "TARGET_80387"
4456   "fnstcw\t%0"
4457   [(set_attr "length" "2")
4458    (set_attr "mode" "HI")
4459    (set_attr "unit" "i387")])
4460
4461 (define_insn "x86_fldcw_1"
4462   [(set (reg:HI FPSR_REG)
4463         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4464   "TARGET_80387"
4465   "fldcw\t%0"
4466   [(set_attr "length" "2")
4467    (set_attr "mode" "HI")
4468    (set_attr "unit" "i387")
4469    (set_attr "athlon_decode" "vector")])
4470 \f
4471 ;; Conversion between fixed point and floating point.
4472
4473 ;; Even though we only accept memory inputs, the backend _really_
4474 ;; wants to be able to do this between registers.
4475
4476 (define_expand "floathisf2"
4477   [(set (match_operand:SF 0 "register_operand" "")
4478         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4479   "TARGET_SSE || TARGET_80387"
4480 {
4481   if (TARGET_SSE && TARGET_SSE_MATH)
4482     {
4483       emit_insn (gen_floatsisf2 (operands[0],
4484                                  convert_to_mode (SImode, operands[1], 0)));
4485       DONE;
4486     }
4487 })
4488
4489 (define_insn "*floathisf2_1"
4490   [(set (match_operand:SF 0 "register_operand" "=f,f")
4491         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4492   "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4493   "@
4494    fild%z1\t%1
4495    #"
4496   [(set_attr "type" "fmov,multi")
4497    (set_attr "mode" "SF")
4498    (set_attr "fp_int_src" "true")])
4499
4500 (define_expand "floatsisf2"
4501   [(set (match_operand:SF 0 "register_operand" "")
4502         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4503   "TARGET_SSE || TARGET_80387"
4504   "")
4505
4506 (define_insn "*floatsisf2_i387"
4507   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4508         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4509   "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4510   "@
4511    fild%z1\t%1
4512    #
4513    cvtsi2ss\t{%1, %0|%0, %1}
4514    cvtsi2ss\t{%1, %0|%0, %1}"
4515   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4516    (set_attr "mode" "SF")
4517    (set_attr "athlon_decode" "*,*,vector,double")
4518    (set_attr "fp_int_src" "true")])
4519
4520 (define_insn "*floatsisf2_sse"
4521   [(set (match_operand:SF 0 "register_operand" "=x,x")
4522         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4523   "TARGET_SSE"
4524   "cvtsi2ss\t{%1, %0|%0, %1}"
4525   [(set_attr "type" "sseicvt")
4526    (set_attr "mode" "SF")
4527    (set_attr "athlon_decode" "vector,double")
4528    (set_attr "fp_int_src" "true")])
4529
4530 ; Avoid possible reformatting penalty on the destination by first
4531 ; zeroing it out
4532 (define_split
4533   [(set (match_operand:SF 0 "register_operand" "")
4534         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4535   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4536    && SSE_REG_P (operands[0])"
4537   [(const_int 0)]
4538 {
4539   rtx dest;
4540   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4541   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4542   emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4543   DONE;
4544 })
4545
4546 (define_expand "floatdisf2"
4547   [(set (match_operand:SF 0 "register_operand" "")
4548         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4549   "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4550   "")
4551
4552 (define_insn "*floatdisf2_i387_only"
4553   [(set (match_operand:SF 0 "register_operand" "=f,?f")
4554         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4555   "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4556   "@
4557    fild%z1\t%1
4558    #"
4559   [(set_attr "type" "fmov,multi")
4560    (set_attr "mode" "SF")
4561    (set_attr "fp_int_src" "true")])
4562
4563 (define_insn "*floatdisf2_i387"
4564   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4565         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4566   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4567   "@
4568    fild%z1\t%1
4569    #
4570    cvtsi2ss{q}\t{%1, %0|%0, %1}
4571    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4572   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4573    (set_attr "mode" "SF")
4574    (set_attr "athlon_decode" "*,*,vector,double")
4575    (set_attr "fp_int_src" "true")])
4576
4577 (define_insn "*floatdisf2_sse"
4578   [(set (match_operand:SF 0 "register_operand" "=x,x")
4579         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4580   "TARGET_64BIT && TARGET_SSE"
4581   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4582   [(set_attr "type" "sseicvt")
4583    (set_attr "mode" "SF")
4584    (set_attr "athlon_decode" "vector,double")
4585    (set_attr "fp_int_src" "true")])
4586
4587 ; Avoid possible reformatting penalty on the destination by first
4588 ; zeroing it out
4589 (define_split
4590   [(set (match_operand:SF 0 "register_operand" "")
4591         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4592   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4593    && SSE_REG_P (operands[0])"
4594   [(const_int 0)]
4595 {
4596   rtx dest;
4597   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4598   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4599   emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4600   DONE;
4601 })
4602
4603 (define_expand "floathidf2"
4604   [(set (match_operand:DF 0 "register_operand" "")
4605         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4606   "TARGET_SSE2 || TARGET_80387"
4607 {
4608   if (TARGET_SSE && TARGET_SSE_MATH)
4609     {
4610       emit_insn (gen_floatsidf2 (operands[0],
4611                                  convert_to_mode (SImode, operands[1], 0)));
4612       DONE;
4613     }
4614 })
4615
4616 (define_insn "*floathidf2_1"
4617   [(set (match_operand:DF 0 "register_operand" "=f,f")
4618         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4619   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4620   "@
4621    fild%z1\t%1
4622    #"
4623   [(set_attr "type" "fmov,multi")
4624    (set_attr "mode" "DF")
4625    (set_attr "fp_int_src" "true")])
4626
4627 (define_expand "floatsidf2"
4628   [(set (match_operand:DF 0 "register_operand" "")
4629         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4630   "TARGET_80387 || TARGET_SSE2"
4631   "")
4632
4633 (define_insn "*floatsidf2_i387"
4634   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4635         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4636   "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4637   "@
4638    fild%z1\t%1
4639    #
4640    cvtsi2sd\t{%1, %0|%0, %1}
4641    cvtsi2sd\t{%1, %0|%0, %1}"
4642   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4643    (set_attr "mode" "DF")
4644    (set_attr "athlon_decode" "*,*,double,direct")
4645    (set_attr "fp_int_src" "true")])
4646
4647 (define_insn "*floatsidf2_sse"
4648   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4649         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4650   "TARGET_SSE2"
4651   "cvtsi2sd\t{%1, %0|%0, %1}"
4652   [(set_attr "type" "sseicvt")
4653    (set_attr "mode" "DF")
4654    (set_attr "athlon_decode" "double,direct")
4655    (set_attr "fp_int_src" "true")])
4656
4657 (define_expand "floatdidf2"
4658   [(set (match_operand:DF 0 "register_operand" "")
4659         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4660   "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4661   "")
4662
4663 (define_insn "*floatdidf2_i387_only"
4664   [(set (match_operand:DF 0 "register_operand" "=f,?f")
4665         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4666   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4667   "@
4668    fild%z1\t%1
4669    #"
4670   [(set_attr "type" "fmov,multi")
4671    (set_attr "mode" "DF")
4672    (set_attr "fp_int_src" "true")])
4673
4674 (define_insn "*floatdidf2_i387"
4675   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4676         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4677   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4678   "@
4679    fild%z1\t%1
4680    #
4681    cvtsi2sd{q}\t{%1, %0|%0, %1}
4682    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4683   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4684    (set_attr "mode" "DF")
4685    (set_attr "athlon_decode" "*,*,double,direct")
4686    (set_attr "fp_int_src" "true")])
4687
4688 (define_insn "*floatdidf2_sse"
4689   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4690         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4691   "TARGET_SSE2"
4692   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4693   [(set_attr "type" "sseicvt")
4694    (set_attr "mode" "DF")
4695    (set_attr "athlon_decode" "double,direct")
4696    (set_attr "fp_int_src" "true")])
4697
4698 (define_insn "floathixf2"
4699   [(set (match_operand:XF 0 "register_operand" "=f,f")
4700         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4701   "TARGET_80387"
4702   "@
4703    fild%z1\t%1
4704    #"
4705   [(set_attr "type" "fmov,multi")
4706    (set_attr "mode" "XF")
4707    (set_attr "fp_int_src" "true")])
4708
4709 (define_insn "floatsixf2"
4710   [(set (match_operand:XF 0 "register_operand" "=f,f")
4711         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4712   "TARGET_80387"
4713   "@
4714    fild%z1\t%1
4715    #"
4716   [(set_attr "type" "fmov,multi")
4717    (set_attr "mode" "XF")
4718    (set_attr "fp_int_src" "true")])
4719
4720 (define_insn "floatdixf2"
4721   [(set (match_operand:XF 0 "register_operand" "=f,f")
4722         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4723   "TARGET_80387"
4724   "@
4725    fild%z1\t%1
4726    #"
4727   [(set_attr "type" "fmov,multi")
4728    (set_attr "mode" "XF")
4729    (set_attr "fp_int_src" "true")])
4730
4731 ;; %%% Kill these when reload knows how to do it.
4732 (define_split
4733   [(set (match_operand 0 "fp_register_operand" "")
4734         (float (match_operand 1 "register_operand" "")))]
4735   "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4736   [(const_int 0)]
4737 {
4738   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4739   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4740   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4741   ix86_free_from_memory (GET_MODE (operands[1]));
4742   DONE;
4743 })
4744
4745 (define_expand "floatunssisf2"
4746   [(use (match_operand:SF 0 "register_operand" ""))
4747    (use (match_operand:SI 1 "register_operand" ""))]
4748   "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4749   "x86_emit_floatuns (operands); DONE;")
4750
4751 (define_expand "floatunsdisf2"
4752   [(use (match_operand:SF 0 "register_operand" ""))
4753    (use (match_operand:DI 1 "register_operand" ""))]
4754   "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4755   "x86_emit_floatuns (operands); DONE;")
4756
4757 (define_expand "floatunsdidf2"
4758   [(use (match_operand:DF 0 "register_operand" ""))
4759    (use (match_operand:DI 1 "register_operand" ""))]
4760   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4761   "x86_emit_floatuns (operands); DONE;")
4762 \f
4763 ;; SSE extract/set expanders
4764
4765 (define_expand "vec_setv2df"
4766   [(match_operand:V2DF 0 "register_operand" "")
4767    (match_operand:DF 1 "register_operand" "")
4768    (match_operand 2 "const_int_operand" "")]
4769   "TARGET_SSE2"
4770 {
4771   switch (INTVAL (operands[2]))
4772     {
4773     case 0:
4774       emit_insn (gen_sse2_movsd (operands[0], operands[0],
4775                                  simplify_gen_subreg (V2DFmode, operands[1],
4776                                                       DFmode, 0)));
4777       break;
4778     case 1:
4779       {
4780         rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4781
4782         emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4783       }
4784       break;
4785     default:
4786       abort ();
4787     }
4788   DONE;
4789 })
4790
4791 (define_expand "vec_extractv2df"
4792   [(match_operand:DF 0 "register_operand" "")
4793    (match_operand:V2DF 1 "register_operand" "")
4794    (match_operand 2 "const_int_operand" "")]
4795   "TARGET_SSE2"
4796 {
4797   switch (INTVAL (operands[2]))
4798     {
4799     case 0:
4800       emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4801       break;
4802     case 1:
4803       {
4804         rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4805
4806         emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4807       }
4808       break;
4809     default:
4810       abort ();
4811     }
4812   DONE;
4813 })
4814
4815 (define_expand "vec_initv2df"
4816   [(match_operand:V2DF 0 "register_operand" "")
4817    (match_operand 1 "" "")]
4818   "TARGET_SSE2"
4819 {
4820   ix86_expand_vector_init (operands[0], operands[1]);
4821   DONE;
4822 })
4823
4824 (define_expand "vec_setv4sf"
4825   [(match_operand:V4SF 0 "register_operand" "")
4826    (match_operand:SF 1 "register_operand" "")
4827    (match_operand 2 "const_int_operand" "")]
4828   "TARGET_SSE"
4829 {
4830   switch (INTVAL (operands[2]))
4831     {
4832     case 0:
4833       emit_insn (gen_sse_movss (operands[0], operands[0],
4834                                 simplify_gen_subreg (V4SFmode, operands[1],
4835                                                      SFmode, 0)));
4836       break;
4837     case 1:
4838       {
4839         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4840         rtx tmp = gen_reg_rtx (V4SFmode);
4841  
4842         emit_move_insn (tmp, operands[0]);
4843         emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4844         emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4845         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4846                                    GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4847       }
4848       break;
4849     case 2:
4850       {
4851         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4852         rtx tmp = gen_reg_rtx (V4SFmode);
4853
4854         emit_move_insn (tmp, operands[0]);
4855         emit_insn (gen_sse_movss (tmp, tmp, op1));
4856         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4857                                    GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4858       }
4859       break;
4860     case 3:
4861       {
4862         rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4863         rtx tmp = gen_reg_rtx (V4SFmode);
4864
4865         emit_move_insn (tmp, operands[0]);
4866         emit_insn (gen_sse_movss (tmp, tmp, op1));
4867         emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4868                                    GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4869       }
4870       break;
4871     default:
4872       abort ();
4873     }
4874   DONE;
4875 })
4876
4877 (define_expand "vec_extractv4sf"
4878   [(match_operand:SF 0 "register_operand" "")
4879    (match_operand:V4SF 1 "register_operand" "")
4880    (match_operand 2 "const_int_operand" "")]
4881   "TARGET_SSE"
4882 {
4883   switch (INTVAL (operands[2]))
4884     {
4885     case 0:
4886       emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4887       break;
4888     case 1:
4889       {
4890         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4891         rtx tmp = gen_reg_rtx (V4SFmode);
4892  
4893         emit_move_insn (tmp, operands[1]);
4894         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4895                                    const1_rtx));
4896       }
4897       break;
4898     case 2:
4899       {
4900         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4901         rtx tmp = gen_reg_rtx (V4SFmode);
4902  
4903         emit_move_insn (tmp, operands[1]);
4904         emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4905       }
4906       break;
4907     case 3:
4908       {
4909         rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4910         rtx tmp = gen_reg_rtx (V4SFmode);
4911  
4912         emit_move_insn (tmp, operands[1]);
4913         emit_insn (gen_sse_shufps (op0, tmp, tmp,
4914                                    GEN_INT (3)));
4915       }
4916       break;
4917     default:
4918       abort ();
4919     }
4920   DONE;
4921 })
4922
4923 (define_expand "vec_initv4sf"
4924   [(match_operand:V4SF 0 "register_operand" "")
4925    (match_operand 1 "" "")]
4926   "TARGET_SSE"
4927 {
4928   ix86_expand_vector_init (operands[0], operands[1]);
4929   DONE;
4930 })
4931 \f
4932 ;; Add instructions
4933
4934 ;; %%% splits for addsidi3
4935 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4936 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4937 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4938
4939 (define_expand "adddi3"
4940   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4941         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4942                  (match_operand:DI 2 "x86_64_general_operand" "")))
4943    (clobber (reg:CC FLAGS_REG))]
4944   ""
4945   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4946
4947 (define_insn "*adddi3_1"
4948   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4949         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4950                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4951    (clobber (reg:CC FLAGS_REG))]
4952   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4953   "#")
4954
4955 (define_split
4956   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4957         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4958                  (match_operand:DI 2 "general_operand" "")))
4959    (clobber (reg:CC FLAGS_REG))]
4960   "!TARGET_64BIT && reload_completed"
4961   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4962                                           UNSPEC_ADD_CARRY))
4963               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4964    (parallel [(set (match_dup 3)
4965                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4966                                      (match_dup 4))
4967                             (match_dup 5)))
4968               (clobber (reg:CC FLAGS_REG))])]
4969   "split_di (operands+0, 1, operands+0, operands+3);
4970    split_di (operands+1, 1, operands+1, operands+4);
4971    split_di (operands+2, 1, operands+2, operands+5);")
4972
4973 (define_insn "adddi3_carry_rex64"
4974   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4975           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4976                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4977                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4978    (clobber (reg:CC FLAGS_REG))]
4979   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4980   "adc{q}\t{%2, %0|%0, %2}"
4981   [(set_attr "type" "alu")
4982    (set_attr "pent_pair" "pu")
4983    (set_attr "mode" "DI")])
4984
4985 (define_insn "*adddi3_cc_rex64"
4986   [(set (reg:CC FLAGS_REG)
4987         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4988                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4989                    UNSPEC_ADD_CARRY))
4990    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4991         (plus:DI (match_dup 1) (match_dup 2)))]
4992   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4993   "add{q}\t{%2, %0|%0, %2}"
4994   [(set_attr "type" "alu")
4995    (set_attr "mode" "DI")])
4996
4997 (define_insn "addqi3_carry"
4998   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4999           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5000                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5001                    (match_operand:QI 2 "general_operand" "qi,qm")))
5002    (clobber (reg:CC FLAGS_REG))]
5003   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5004   "adc{b}\t{%2, %0|%0, %2}"
5005   [(set_attr "type" "alu")
5006    (set_attr "pent_pair" "pu")
5007    (set_attr "mode" "QI")])
5008
5009 (define_insn "addhi3_carry"
5010   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5011           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5012                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5013                    (match_operand:HI 2 "general_operand" "ri,rm")))
5014    (clobber (reg:CC FLAGS_REG))]
5015   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5016   "adc{w}\t{%2, %0|%0, %2}"
5017   [(set_attr "type" "alu")
5018    (set_attr "pent_pair" "pu")
5019    (set_attr "mode" "HI")])
5020
5021 (define_insn "addsi3_carry"
5022   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5023           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5024                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5025                    (match_operand:SI 2 "general_operand" "ri,rm")))
5026    (clobber (reg:CC FLAGS_REG))]
5027   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5028   "adc{l}\t{%2, %0|%0, %2}"
5029   [(set_attr "type" "alu")
5030    (set_attr "pent_pair" "pu")
5031    (set_attr "mode" "SI")])
5032
5033 (define_insn "*addsi3_carry_zext"
5034   [(set (match_operand:DI 0 "register_operand" "=r")
5035           (zero_extend:DI 
5036             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5037                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5038                      (match_operand:SI 2 "general_operand" "rim"))))
5039    (clobber (reg:CC FLAGS_REG))]
5040   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5041   "adc{l}\t{%2, %k0|%k0, %2}"
5042   [(set_attr "type" "alu")
5043    (set_attr "pent_pair" "pu")
5044    (set_attr "mode" "SI")])
5045
5046 (define_insn "*addsi3_cc"
5047   [(set (reg:CC FLAGS_REG)
5048         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5049                     (match_operand:SI 2 "general_operand" "ri,rm")]
5050                    UNSPEC_ADD_CARRY))
5051    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5052         (plus:SI (match_dup 1) (match_dup 2)))]
5053   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5054   "add{l}\t{%2, %0|%0, %2}"
5055   [(set_attr "type" "alu")
5056    (set_attr "mode" "SI")])
5057
5058 (define_insn "addqi3_cc"
5059   [(set (reg:CC FLAGS_REG)
5060         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5061                     (match_operand:QI 2 "general_operand" "qi,qm")]
5062                    UNSPEC_ADD_CARRY))
5063    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5064         (plus:QI (match_dup 1) (match_dup 2)))]
5065   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5066   "add{b}\t{%2, %0|%0, %2}"
5067   [(set_attr "type" "alu")
5068    (set_attr "mode" "QI")])
5069
5070 (define_expand "addsi3"
5071   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5072                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5073                             (match_operand:SI 2 "general_operand" "")))
5074               (clobber (reg:CC FLAGS_REG))])]
5075   ""
5076   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5077
5078 (define_insn "*lea_1"
5079   [(set (match_operand:SI 0 "register_operand" "=r")
5080         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5081   "!TARGET_64BIT"
5082   "lea{l}\t{%a1, %0|%0, %a1}"
5083   [(set_attr "type" "lea")
5084    (set_attr "mode" "SI")])
5085
5086 (define_insn "*lea_1_rex64"
5087   [(set (match_operand:SI 0 "register_operand" "=r")
5088         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5089   "TARGET_64BIT"
5090   "lea{l}\t{%a1, %0|%0, %a1}"
5091   [(set_attr "type" "lea")
5092    (set_attr "mode" "SI")])
5093
5094 (define_insn "*lea_1_zext"
5095   [(set (match_operand:DI 0 "register_operand" "=r")
5096         (zero_extend:DI
5097          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5098   "TARGET_64BIT"
5099   "lea{l}\t{%a1, %k0|%k0, %a1}"
5100   [(set_attr "type" "lea")
5101    (set_attr "mode" "SI")])
5102
5103 (define_insn "*lea_2_rex64"
5104   [(set (match_operand:DI 0 "register_operand" "=r")
5105         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5106   "TARGET_64BIT"
5107   "lea{q}\t{%a1, %0|%0, %a1}"
5108   [(set_attr "type" "lea")
5109    (set_attr "mode" "DI")])
5110
5111 ;; The lea patterns for non-Pmodes needs to be matched by several
5112 ;; insns converted to real lea by splitters.
5113
5114 (define_insn_and_split "*lea_general_1"
5115   [(set (match_operand 0 "register_operand" "=r")
5116         (plus (plus (match_operand 1 "index_register_operand" "r")
5117                     (match_operand 2 "register_operand" "r"))
5118               (match_operand 3 "immediate_operand" "i")))]
5119   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5120     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5121    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5122    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5123    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5124    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5125        || GET_MODE (operands[3]) == VOIDmode)"
5126   "#"
5127   "&& reload_completed"
5128   [(const_int 0)]
5129 {
5130   rtx pat;
5131   operands[0] = gen_lowpart (SImode, operands[0]);
5132   operands[1] = gen_lowpart (Pmode, operands[1]);
5133   operands[2] = gen_lowpart (Pmode, operands[2]);
5134   operands[3] = gen_lowpart (Pmode, operands[3]);
5135   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5136                       operands[3]);
5137   if (Pmode != SImode)
5138     pat = gen_rtx_SUBREG (SImode, pat, 0);
5139   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5140   DONE;
5141 }
5142   [(set_attr "type" "lea")
5143    (set_attr "mode" "SI")])
5144
5145 (define_insn_and_split "*lea_general_1_zext"
5146   [(set (match_operand:DI 0 "register_operand" "=r")
5147         (zero_extend:DI
5148           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5149                             (match_operand:SI 2 "register_operand" "r"))
5150                    (match_operand:SI 3 "immediate_operand" "i"))))]
5151   "TARGET_64BIT"
5152   "#"
5153   "&& reload_completed"
5154   [(set (match_dup 0)
5155         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5156                                                      (match_dup 2))
5157                                             (match_dup 3)) 0)))]
5158 {
5159   operands[1] = gen_lowpart (Pmode, operands[1]);
5160   operands[2] = gen_lowpart (Pmode, operands[2]);
5161   operands[3] = gen_lowpart (Pmode, operands[3]);
5162 }
5163   [(set_attr "type" "lea")
5164    (set_attr "mode" "SI")])
5165
5166 (define_insn_and_split "*lea_general_2"
5167   [(set (match_operand 0 "register_operand" "=r")
5168         (plus (mult (match_operand 1 "index_register_operand" "r")
5169                     (match_operand 2 "const248_operand" "i"))
5170               (match_operand 3 "nonmemory_operand" "ri")))]
5171   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5172     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5173    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5174    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5175    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5176        || GET_MODE (operands[3]) == VOIDmode)"
5177   "#"
5178   "&& reload_completed"
5179   [(const_int 0)]
5180 {
5181   rtx pat;
5182   operands[0] = gen_lowpart (SImode, operands[0]);
5183   operands[1] = gen_lowpart (Pmode, operands[1]);
5184   operands[3] = gen_lowpart (Pmode, operands[3]);
5185   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5186                       operands[3]);
5187   if (Pmode != SImode)
5188     pat = gen_rtx_SUBREG (SImode, pat, 0);
5189   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5190   DONE;
5191 }
5192   [(set_attr "type" "lea")
5193    (set_attr "mode" "SI")])
5194
5195 (define_insn_and_split "*lea_general_2_zext"
5196   [(set (match_operand:DI 0 "register_operand" "=r")
5197         (zero_extend:DI
5198           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5199                             (match_operand:SI 2 "const248_operand" "n"))
5200                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5201   "TARGET_64BIT"
5202   "#"
5203   "&& reload_completed"
5204   [(set (match_dup 0)
5205         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5206                                                      (match_dup 2))
5207                                             (match_dup 3)) 0)))]
5208 {
5209   operands[1] = gen_lowpart (Pmode, operands[1]);
5210   operands[3] = gen_lowpart (Pmode, operands[3]);
5211 }
5212   [(set_attr "type" "lea")
5213    (set_attr "mode" "SI")])
5214
5215 (define_insn_and_split "*lea_general_3"
5216   [(set (match_operand 0 "register_operand" "=r")
5217         (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5218                           (match_operand 2 "const248_operand" "i"))
5219                     (match_operand 3 "register_operand" "r"))
5220               (match_operand 4 "immediate_operand" "i")))]
5221   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5222     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5223    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5224    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5225    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5226   "#"
5227   "&& reload_completed"
5228   [(const_int 0)]
5229 {
5230   rtx pat;
5231   operands[0] = gen_lowpart (SImode, operands[0]);
5232   operands[1] = gen_lowpart (Pmode, operands[1]);
5233   operands[3] = gen_lowpart (Pmode, operands[3]);
5234   operands[4] = gen_lowpart (Pmode, operands[4]);
5235   pat = gen_rtx_PLUS (Pmode,
5236                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5237                                                          operands[2]),
5238                                     operands[3]),
5239                       operands[4]);
5240   if (Pmode != SImode)
5241     pat = gen_rtx_SUBREG (SImode, pat, 0);
5242   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5243   DONE;
5244 }
5245   [(set_attr "type" "lea")
5246    (set_attr "mode" "SI")])
5247
5248 (define_insn_and_split "*lea_general_3_zext"
5249   [(set (match_operand:DI 0 "register_operand" "=r")
5250         (zero_extend:DI
5251           (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5252                                      (match_operand:SI 2 "const248_operand" "n"))
5253                             (match_operand:SI 3 "register_operand" "r"))
5254                    (match_operand:SI 4 "immediate_operand" "i"))))]
5255   "TARGET_64BIT"
5256   "#"
5257   "&& reload_completed"
5258   [(set (match_dup 0)
5259         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5260                                                               (match_dup 2))
5261                                                      (match_dup 3))
5262                                             (match_dup 4)) 0)))]
5263 {
5264   operands[1] = gen_lowpart (Pmode, operands[1]);
5265   operands[3] = gen_lowpart (Pmode, operands[3]);
5266   operands[4] = gen_lowpart (Pmode, operands[4]);
5267 }
5268   [(set_attr "type" "lea")
5269    (set_attr "mode" "SI")])
5270
5271 (define_insn "*adddi_1_rex64"
5272   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5273         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5274                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5275    (clobber (reg:CC FLAGS_REG))]
5276   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5277 {
5278   switch (get_attr_type (insn))
5279     {
5280     case TYPE_LEA:
5281       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5282       return "lea{q}\t{%a2, %0|%0, %a2}";
5283
5284     case TYPE_INCDEC:
5285       if (! rtx_equal_p (operands[0], operands[1]))
5286         abort ();
5287       if (operands[2] == const1_rtx)
5288         return "inc{q}\t%0";
5289       else if (operands[2] == constm1_rtx)
5290         return "dec{q}\t%0";
5291       else
5292         abort ();
5293
5294     default:
5295       if (! rtx_equal_p (operands[0], operands[1]))
5296         abort ();
5297
5298       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5299          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5300       if (GET_CODE (operands[2]) == CONST_INT
5301           /* Avoid overflows.  */
5302           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5303           && (INTVAL (operands[2]) == 128
5304               || (INTVAL (operands[2]) < 0
5305                   && INTVAL (operands[2]) != -128)))
5306         {
5307           operands[2] = GEN_INT (-INTVAL (operands[2]));
5308           return "sub{q}\t{%2, %0|%0, %2}";
5309         }
5310       return "add{q}\t{%2, %0|%0, %2}";
5311     }
5312 }
5313   [(set (attr "type")
5314      (cond [(eq_attr "alternative" "2")
5315               (const_string "lea")
5316             ; Current assemblers are broken and do not allow @GOTOFF in
5317             ; ought but a memory context.
5318             (match_operand:DI 2 "pic_symbolic_operand" "")
5319               (const_string "lea")
5320             (match_operand:DI 2 "incdec_operand" "")
5321               (const_string "incdec")
5322            ]
5323            (const_string "alu")))
5324    (set_attr "mode" "DI")])
5325
5326 ;; Convert lea to the lea pattern to avoid flags dependency.
5327 (define_split
5328   [(set (match_operand:DI 0 "register_operand" "")
5329         (plus:DI (match_operand:DI 1 "register_operand" "")
5330                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5331    (clobber (reg:CC FLAGS_REG))]
5332   "TARGET_64BIT && reload_completed
5333    && true_regnum (operands[0]) != true_regnum (operands[1])"
5334   [(set (match_dup 0)
5335         (plus:DI (match_dup 1)
5336                  (match_dup 2)))]
5337   "")
5338
5339 (define_insn "*adddi_2_rex64"
5340   [(set (reg 17)
5341         (compare
5342           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5343                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5344           (const_int 0)))                       
5345    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5346         (plus:DI (match_dup 1) (match_dup 2)))]
5347   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5348    && ix86_binary_operator_ok (PLUS, DImode, operands)
5349    /* Current assemblers are broken and do not allow @GOTOFF in
5350       ought but a memory context.  */
5351    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5352 {
5353   switch (get_attr_type (insn))
5354     {
5355     case TYPE_INCDEC:
5356       if (! rtx_equal_p (operands[0], operands[1]))
5357         abort ();
5358       if (operands[2] == const1_rtx)
5359         return "inc{q}\t%0";
5360       else if (operands[2] == constm1_rtx)
5361         return "dec{q}\t%0";
5362       else
5363         abort ();
5364
5365     default:
5366       if (! rtx_equal_p (operands[0], operands[1]))
5367         abort ();
5368       /* ???? We ought to handle there the 32bit case too
5369          - do we need new constraint?  */
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      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5387         (const_string "incdec")
5388         (const_string "alu")))
5389    (set_attr "mode" "DI")])
5390
5391 (define_insn "*adddi_3_rex64"
5392   [(set (reg 17)
5393         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5394                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5395    (clobber (match_scratch:DI 0 "=r"))]
5396   "TARGET_64BIT
5397    && ix86_match_ccmode (insn, CCZmode)
5398    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5399    /* Current assemblers are broken and do not allow @GOTOFF in
5400       ought but a memory context.  */
5401    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5402 {
5403   switch (get_attr_type (insn))
5404     {
5405     case TYPE_INCDEC:
5406       if (! rtx_equal_p (operands[0], operands[1]))
5407         abort ();
5408       if (operands[2] == const1_rtx)
5409         return "inc{q}\t%0";
5410       else if (operands[2] == constm1_rtx)
5411         return "dec{q}\t%0";
5412       else
5413         abort ();
5414
5415     default:
5416       if (! rtx_equal_p (operands[0], operands[1]))
5417         abort ();
5418       /* ???? We ought to handle there the 32bit case too
5419          - do we need new constraint?  */
5420       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5421          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5422       if (GET_CODE (operands[2]) == CONST_INT
5423           /* Avoid overflows.  */
5424           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5425           && (INTVAL (operands[2]) == 128
5426               || (INTVAL (operands[2]) < 0
5427                   && INTVAL (operands[2]) != -128)))
5428         {
5429           operands[2] = GEN_INT (-INTVAL (operands[2]));
5430           return "sub{q}\t{%2, %0|%0, %2}";
5431         }
5432       return "add{q}\t{%2, %0|%0, %2}";
5433     }
5434 }
5435   [(set (attr "type")
5436      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5437         (const_string "incdec")
5438         (const_string "alu")))
5439    (set_attr "mode" "DI")])
5440
5441 ; For comparisons against 1, -1 and 128, we may generate better code
5442 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5443 ; is matched then.  We can't accept general immediate, because for
5444 ; case of overflows,  the result is messed up.
5445 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5446 ; when negated.
5447 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5448 ; only for comparisons not depending on it.
5449 (define_insn "*adddi_4_rex64"
5450   [(set (reg 17)
5451         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5452                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5453    (clobber (match_scratch:DI 0 "=rm"))]
5454   "TARGET_64BIT
5455    &&  ix86_match_ccmode (insn, CCGCmode)"
5456 {
5457   switch (get_attr_type (insn))
5458     {
5459     case TYPE_INCDEC:
5460       if (operands[2] == constm1_rtx)
5461         return "inc{q}\t%0";
5462       else if (operands[2] == const1_rtx)
5463         return "dec{q}\t%0";
5464       else
5465         abort();
5466
5467     default:
5468       if (! rtx_equal_p (operands[0], operands[1]))
5469         abort ();
5470       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5471          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5472       if ((INTVAL (operands[2]) == -128
5473            || (INTVAL (operands[2]) > 0
5474                && INTVAL (operands[2]) != 128))
5475           /* Avoid overflows.  */
5476           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5477         return "sub{q}\t{%2, %0|%0, %2}";
5478       operands[2] = GEN_INT (-INTVAL (operands[2]));
5479       return "add{q}\t{%2, %0|%0, %2}";
5480     }
5481 }
5482   [(set (attr "type")
5483      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5484         (const_string "incdec")
5485         (const_string "alu")))
5486    (set_attr "mode" "DI")])
5487
5488 (define_insn "*adddi_5_rex64"
5489   [(set (reg 17)
5490         (compare
5491           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5492                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5493           (const_int 0)))                       
5494    (clobber (match_scratch:DI 0 "=r"))]
5495   "TARGET_64BIT
5496    && ix86_match_ccmode (insn, CCGOCmode)
5497    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5498    /* Current assemblers are broken and do not allow @GOTOFF in
5499       ought but a memory context.  */
5500    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5501 {
5502   switch (get_attr_type (insn))
5503     {
5504     case TYPE_INCDEC:
5505       if (! rtx_equal_p (operands[0], operands[1]))
5506         abort ();
5507       if (operands[2] == const1_rtx)
5508         return "inc{q}\t%0";
5509       else if (operands[2] == constm1_rtx)
5510         return "dec{q}\t%0";
5511       else
5512         abort();
5513
5514     default:
5515       if (! rtx_equal_p (operands[0], operands[1]))
5516         abort ();
5517       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5518          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5519       if (GET_CODE (operands[2]) == CONST_INT
5520           /* Avoid overflows.  */
5521           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5522           && (INTVAL (operands[2]) == 128
5523               || (INTVAL (operands[2]) < 0
5524                   && INTVAL (operands[2]) != -128)))
5525         {
5526           operands[2] = GEN_INT (-INTVAL (operands[2]));
5527           return "sub{q}\t{%2, %0|%0, %2}";
5528         }
5529       return "add{q}\t{%2, %0|%0, %2}";
5530     }
5531 }
5532   [(set (attr "type")
5533      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5534         (const_string "incdec")
5535         (const_string "alu")))
5536    (set_attr "mode" "DI")])
5537
5538
5539 (define_insn "*addsi_1"
5540   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5541         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5542                  (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5543    (clobber (reg:CC FLAGS_REG))]
5544   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5545 {
5546   switch (get_attr_type (insn))
5547     {
5548     case TYPE_LEA:
5549       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5550       return "lea{l}\t{%a2, %0|%0, %a2}";
5551
5552     case TYPE_INCDEC:
5553       if (! rtx_equal_p (operands[0], operands[1]))
5554         abort ();
5555       if (operands[2] == const1_rtx)
5556         return "inc{l}\t%0";
5557       else if (operands[2] == constm1_rtx)
5558         return "dec{l}\t%0";
5559       else
5560         abort();
5561
5562     default:
5563       if (! rtx_equal_p (operands[0], operands[1]))
5564         abort ();
5565
5566       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5567          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5568       if (GET_CODE (operands[2]) == CONST_INT
5569           && (INTVAL (operands[2]) == 128
5570               || (INTVAL (operands[2]) < 0
5571                   && INTVAL (operands[2]) != -128)))
5572         {
5573           operands[2] = GEN_INT (-INTVAL (operands[2]));
5574           return "sub{l}\t{%2, %0|%0, %2}";
5575         }
5576       return "add{l}\t{%2, %0|%0, %2}";
5577     }
5578 }
5579   [(set (attr "type")
5580      (cond [(eq_attr "alternative" "2")
5581               (const_string "lea")
5582             ; Current assemblers are broken and do not allow @GOTOFF in
5583             ; ought but a memory context.
5584             (match_operand:SI 2 "pic_symbolic_operand" "")
5585               (const_string "lea")
5586             (match_operand:SI 2 "incdec_operand" "")
5587               (const_string "incdec")
5588            ]
5589            (const_string "alu")))
5590    (set_attr "mode" "SI")])
5591
5592 ;; Convert lea to the lea pattern to avoid flags dependency.
5593 (define_split
5594   [(set (match_operand 0 "register_operand" "")
5595         (plus (match_operand 1 "register_operand" "")
5596               (match_operand 2 "nonmemory_operand" "")))
5597    (clobber (reg:CC FLAGS_REG))]
5598   "reload_completed
5599    && true_regnum (operands[0]) != true_regnum (operands[1])"
5600   [(const_int 0)]
5601 {
5602   rtx pat;
5603   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5604      may confuse gen_lowpart.  */
5605   if (GET_MODE (operands[0]) != Pmode)
5606     {
5607       operands[1] = gen_lowpart (Pmode, operands[1]);
5608       operands[2] = gen_lowpart (Pmode, operands[2]);
5609     }
5610   operands[0] = gen_lowpart (SImode, operands[0]);
5611   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5612   if (Pmode != SImode)
5613     pat = gen_rtx_SUBREG (SImode, pat, 0);
5614   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5615   DONE;
5616 })
5617
5618 ;; It may seem that nonimmediate operand is proper one for operand 1.
5619 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5620 ;; we take care in ix86_binary_operator_ok to not allow two memory
5621 ;; operands so proper swapping will be done in reload.  This allow
5622 ;; patterns constructed from addsi_1 to match.
5623 (define_insn "addsi_1_zext"
5624   [(set (match_operand:DI 0 "register_operand" "=r,r")
5625         (zero_extend:DI
5626           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5627                    (match_operand:SI 2 "general_operand" "rmni,rni"))))
5628    (clobber (reg:CC FLAGS_REG))]
5629   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5630 {
5631   switch (get_attr_type (insn))
5632     {
5633     case TYPE_LEA:
5634       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5635       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5636
5637     case TYPE_INCDEC:
5638       if (operands[2] == const1_rtx)
5639         return "inc{l}\t%k0";
5640       else if (operands[2] == constm1_rtx)
5641         return "dec{l}\t%k0";
5642       else
5643         abort();
5644
5645     default:
5646       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5647          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5648       if (GET_CODE (operands[2]) == CONST_INT
5649           && (INTVAL (operands[2]) == 128
5650               || (INTVAL (operands[2]) < 0
5651                   && INTVAL (operands[2]) != -128)))
5652         {
5653           operands[2] = GEN_INT (-INTVAL (operands[2]));
5654           return "sub{l}\t{%2, %k0|%k0, %2}";
5655         }
5656       return "add{l}\t{%2, %k0|%k0, %2}";
5657     }
5658 }
5659   [(set (attr "type")
5660      (cond [(eq_attr "alternative" "1")
5661               (const_string "lea")
5662             ; Current assemblers are broken and do not allow @GOTOFF in
5663             ; ought but a memory context.
5664             (match_operand:SI 2 "pic_symbolic_operand" "")
5665               (const_string "lea")
5666             (match_operand:SI 2 "incdec_operand" "")
5667               (const_string "incdec")
5668            ]
5669            (const_string "alu")))
5670    (set_attr "mode" "SI")])
5671
5672 ;; Convert lea to the lea pattern to avoid flags dependency.
5673 (define_split
5674   [(set (match_operand:DI 0 "register_operand" "")
5675         (zero_extend:DI
5676           (plus:SI (match_operand:SI 1 "register_operand" "")
5677                    (match_operand:SI 2 "nonmemory_operand" ""))))
5678    (clobber (reg:CC FLAGS_REG))]
5679   "TARGET_64BIT && reload_completed
5680    && true_regnum (operands[0]) != true_regnum (operands[1])"
5681   [(set (match_dup 0)
5682         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5683 {
5684   operands[1] = gen_lowpart (Pmode, operands[1]);
5685   operands[2] = gen_lowpart (Pmode, operands[2]);
5686 })
5687
5688 (define_insn "*addsi_2"
5689   [(set (reg 17)
5690         (compare
5691           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5692                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5693           (const_int 0)))                       
5694    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5695         (plus:SI (match_dup 1) (match_dup 2)))]
5696   "ix86_match_ccmode (insn, CCGOCmode)
5697    && ix86_binary_operator_ok (PLUS, SImode, operands)
5698    /* Current assemblers are broken and do not allow @GOTOFF in
5699       ought but a memory context.  */
5700    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5701 {
5702   switch (get_attr_type (insn))
5703     {
5704     case TYPE_INCDEC:
5705       if (! rtx_equal_p (operands[0], operands[1]))
5706         abort ();
5707       if (operands[2] == const1_rtx)
5708         return "inc{l}\t%0";
5709       else if (operands[2] == constm1_rtx)
5710         return "dec{l}\t%0";
5711       else
5712         abort();
5713
5714     default:
5715       if (! rtx_equal_p (operands[0], operands[1]))
5716         abort ();
5717       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5718          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5719       if (GET_CODE (operands[2]) == CONST_INT
5720           && (INTVAL (operands[2]) == 128
5721               || (INTVAL (operands[2]) < 0
5722                   && INTVAL (operands[2]) != -128)))
5723         {
5724           operands[2] = GEN_INT (-INTVAL (operands[2]));
5725           return "sub{l}\t{%2, %0|%0, %2}";
5726         }
5727       return "add{l}\t{%2, %0|%0, %2}";
5728     }
5729 }
5730   [(set (attr "type")
5731      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5732         (const_string "incdec")
5733         (const_string "alu")))
5734    (set_attr "mode" "SI")])
5735
5736 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5737 (define_insn "*addsi_2_zext"
5738   [(set (reg 17)
5739         (compare
5740           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5741                    (match_operand:SI 2 "general_operand" "rmni"))
5742           (const_int 0)))                       
5743    (set (match_operand:DI 0 "register_operand" "=r")
5744         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5745   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5746    && ix86_binary_operator_ok (PLUS, SImode, operands)
5747    /* Current assemblers are broken and do not allow @GOTOFF in
5748       ought but a memory context.  */
5749    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5750 {
5751   switch (get_attr_type (insn))
5752     {
5753     case TYPE_INCDEC:
5754       if (operands[2] == const1_rtx)
5755         return "inc{l}\t%k0";
5756       else if (operands[2] == constm1_rtx)
5757         return "dec{l}\t%k0";
5758       else
5759         abort();
5760
5761     default:
5762       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5763          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5764       if (GET_CODE (operands[2]) == CONST_INT
5765           && (INTVAL (operands[2]) == 128
5766               || (INTVAL (operands[2]) < 0
5767                   && INTVAL (operands[2]) != -128)))
5768         {
5769           operands[2] = GEN_INT (-INTVAL (operands[2]));
5770           return "sub{l}\t{%2, %k0|%k0, %2}";
5771         }
5772       return "add{l}\t{%2, %k0|%k0, %2}";
5773     }
5774 }
5775   [(set (attr "type")
5776      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5777         (const_string "incdec")
5778         (const_string "alu")))
5779    (set_attr "mode" "SI")])
5780
5781 (define_insn "*addsi_3"
5782   [(set (reg 17)
5783         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5784                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5785    (clobber (match_scratch:SI 0 "=r"))]
5786   "ix86_match_ccmode (insn, CCZmode)
5787    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5788    /* Current assemblers are broken and do not allow @GOTOFF in
5789       ought but a memory context.  */
5790    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5791 {
5792   switch (get_attr_type (insn))
5793     {
5794     case TYPE_INCDEC:
5795       if (! rtx_equal_p (operands[0], operands[1]))
5796         abort ();
5797       if (operands[2] == const1_rtx)
5798         return "inc{l}\t%0";
5799       else if (operands[2] == constm1_rtx)
5800         return "dec{l}\t%0";
5801       else
5802         abort();
5803
5804     default:
5805       if (! rtx_equal_p (operands[0], operands[1]))
5806         abort ();
5807       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5808          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5809       if (GET_CODE (operands[2]) == CONST_INT
5810           && (INTVAL (operands[2]) == 128
5811               || (INTVAL (operands[2]) < 0
5812                   && INTVAL (operands[2]) != -128)))
5813         {
5814           operands[2] = GEN_INT (-INTVAL (operands[2]));
5815           return "sub{l}\t{%2, %0|%0, %2}";
5816         }
5817       return "add{l}\t{%2, %0|%0, %2}";
5818     }
5819 }
5820   [(set (attr "type")
5821      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5822         (const_string "incdec")
5823         (const_string "alu")))
5824    (set_attr "mode" "SI")])
5825
5826 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5827 (define_insn "*addsi_3_zext"
5828   [(set (reg 17)
5829         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5830                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5831    (set (match_operand:DI 0 "register_operand" "=r")
5832         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5833   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5834    && ix86_binary_operator_ok (PLUS, SImode, operands)
5835    /* Current assemblers are broken and do not allow @GOTOFF in
5836       ought but a memory context.  */
5837    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5838 {
5839   switch (get_attr_type (insn))
5840     {
5841     case TYPE_INCDEC:
5842       if (operands[2] == const1_rtx)
5843         return "inc{l}\t%k0";
5844       else if (operands[2] == constm1_rtx)
5845         return "dec{l}\t%k0";
5846       else
5847         abort();
5848
5849     default:
5850       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5851          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5852       if (GET_CODE (operands[2]) == CONST_INT
5853           && (INTVAL (operands[2]) == 128
5854               || (INTVAL (operands[2]) < 0
5855                   && INTVAL (operands[2]) != -128)))
5856         {
5857           operands[2] = GEN_INT (-INTVAL (operands[2]));
5858           return "sub{l}\t{%2, %k0|%k0, %2}";
5859         }
5860       return "add{l}\t{%2, %k0|%k0, %2}";
5861     }
5862 }
5863   [(set (attr "type")
5864      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5865         (const_string "incdec")
5866         (const_string "alu")))
5867    (set_attr "mode" "SI")])
5868
5869 ; For comparisons against 1, -1 and 128, we may generate better code
5870 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5871 ; is matched then.  We can't accept general immediate, because for
5872 ; case of overflows,  the result is messed up.
5873 ; This pattern also don't hold of 0x80000000, since the value overflows
5874 ; when negated.
5875 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5876 ; only for comparisons not depending on it.
5877 (define_insn "*addsi_4"
5878   [(set (reg 17)
5879         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5880                  (match_operand:SI 2 "const_int_operand" "n")))
5881    (clobber (match_scratch:SI 0 "=rm"))]
5882   "ix86_match_ccmode (insn, CCGCmode)
5883    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5884 {
5885   switch (get_attr_type (insn))
5886     {
5887     case TYPE_INCDEC:
5888       if (operands[2] == constm1_rtx)
5889         return "inc{l}\t%0";
5890       else if (operands[2] == const1_rtx)
5891         return "dec{l}\t%0";
5892       else
5893         abort();
5894
5895     default:
5896       if (! rtx_equal_p (operands[0], operands[1]))
5897         abort ();
5898       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5899          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5900       if ((INTVAL (operands[2]) == -128
5901            || (INTVAL (operands[2]) > 0
5902                && INTVAL (operands[2]) != 128)))
5903         return "sub{l}\t{%2, %0|%0, %2}";
5904       operands[2] = GEN_INT (-INTVAL (operands[2]));
5905       return "add{l}\t{%2, %0|%0, %2}";
5906     }
5907 }
5908   [(set (attr "type")
5909      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5910         (const_string "incdec")
5911         (const_string "alu")))
5912    (set_attr "mode" "SI")])
5913
5914 (define_insn "*addsi_5"
5915   [(set (reg 17)
5916         (compare
5917           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5918                    (match_operand:SI 2 "general_operand" "rmni"))
5919           (const_int 0)))                       
5920    (clobber (match_scratch:SI 0 "=r"))]
5921   "ix86_match_ccmode (insn, CCGOCmode)
5922    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5923    /* Current assemblers are broken and do not allow @GOTOFF in
5924       ought but a memory context.  */
5925    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5926 {
5927   switch (get_attr_type (insn))
5928     {
5929     case TYPE_INCDEC:
5930       if (! rtx_equal_p (operands[0], operands[1]))
5931         abort ();
5932       if (operands[2] == const1_rtx)
5933         return "inc{l}\t%0";
5934       else if (operands[2] == constm1_rtx)
5935         return "dec{l}\t%0";
5936       else
5937         abort();
5938
5939     default:
5940       if (! rtx_equal_p (operands[0], operands[1]))
5941         abort ();
5942       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5943          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5944       if (GET_CODE (operands[2]) == CONST_INT
5945           && (INTVAL (operands[2]) == 128
5946               || (INTVAL (operands[2]) < 0
5947                   && INTVAL (operands[2]) != -128)))
5948         {
5949           operands[2] = GEN_INT (-INTVAL (operands[2]));
5950           return "sub{l}\t{%2, %0|%0, %2}";
5951         }
5952       return "add{l}\t{%2, %0|%0, %2}";
5953     }
5954 }
5955   [(set (attr "type")
5956      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5957         (const_string "incdec")
5958         (const_string "alu")))
5959    (set_attr "mode" "SI")])
5960
5961 (define_expand "addhi3"
5962   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5963                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5964                             (match_operand:HI 2 "general_operand" "")))
5965               (clobber (reg:CC FLAGS_REG))])]
5966   "TARGET_HIMODE_MATH"
5967   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5968
5969 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5970 ;; type optimizations enabled by define-splits.  This is not important
5971 ;; for PII, and in fact harmful because of partial register stalls.
5972
5973 (define_insn "*addhi_1_lea"
5974   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5975         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5976                  (match_operand:HI 2 "general_operand" "ri,rm,rni")))
5977    (clobber (reg:CC FLAGS_REG))]
5978   "!TARGET_PARTIAL_REG_STALL
5979    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5980 {
5981   switch (get_attr_type (insn))
5982     {
5983     case TYPE_LEA:
5984       return "#";
5985     case TYPE_INCDEC:
5986       if (operands[2] == const1_rtx)
5987         return "inc{w}\t%0";
5988       else if (operands[2] == constm1_rtx)
5989         return "dec{w}\t%0";
5990       abort();
5991
5992     default:
5993       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5994          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5995       if (GET_CODE (operands[2]) == CONST_INT
5996           && (INTVAL (operands[2]) == 128
5997               || (INTVAL (operands[2]) < 0
5998                   && INTVAL (operands[2]) != -128)))
5999         {
6000           operands[2] = GEN_INT (-INTVAL (operands[2]));
6001           return "sub{w}\t{%2, %0|%0, %2}";
6002         }
6003       return "add{w}\t{%2, %0|%0, %2}";
6004     }
6005 }
6006   [(set (attr "type")
6007      (if_then_else (eq_attr "alternative" "2")
6008         (const_string "lea")
6009         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6010            (const_string "incdec")
6011            (const_string "alu"))))
6012    (set_attr "mode" "HI,HI,SI")])
6013
6014 (define_insn "*addhi_1"
6015   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6016         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6017                  (match_operand:HI 2 "general_operand" "ri,rm")))
6018    (clobber (reg:CC FLAGS_REG))]
6019   "TARGET_PARTIAL_REG_STALL
6020    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6021 {
6022   switch (get_attr_type (insn))
6023     {
6024     case TYPE_INCDEC:
6025       if (operands[2] == const1_rtx)
6026         return "inc{w}\t%0";
6027       else if (operands[2] == constm1_rtx)
6028         return "dec{w}\t%0";
6029       abort();
6030
6031     default:
6032       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6033          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6034       if (GET_CODE (operands[2]) == CONST_INT
6035           && (INTVAL (operands[2]) == 128
6036               || (INTVAL (operands[2]) < 0
6037                   && INTVAL (operands[2]) != -128)))
6038         {
6039           operands[2] = GEN_INT (-INTVAL (operands[2]));
6040           return "sub{w}\t{%2, %0|%0, %2}";
6041         }
6042       return "add{w}\t{%2, %0|%0, %2}";
6043     }
6044 }
6045   [(set (attr "type")
6046      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6047         (const_string "incdec")
6048         (const_string "alu")))
6049    (set_attr "mode" "HI")])
6050
6051 (define_insn "*addhi_2"
6052   [(set (reg 17)
6053         (compare
6054           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6055                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6056           (const_int 0)))                       
6057    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6058         (plus:HI (match_dup 1) (match_dup 2)))]
6059   "ix86_match_ccmode (insn, CCGOCmode)
6060    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6061 {
6062   switch (get_attr_type (insn))
6063     {
6064     case TYPE_INCDEC:
6065       if (operands[2] == const1_rtx)
6066         return "inc{w}\t%0";
6067       else if (operands[2] == constm1_rtx)
6068         return "dec{w}\t%0";
6069       abort();
6070
6071     default:
6072       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6073          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6074       if (GET_CODE (operands[2]) == CONST_INT
6075           && (INTVAL (operands[2]) == 128
6076               || (INTVAL (operands[2]) < 0
6077                   && INTVAL (operands[2]) != -128)))
6078         {
6079           operands[2] = GEN_INT (-INTVAL (operands[2]));
6080           return "sub{w}\t{%2, %0|%0, %2}";
6081         }
6082       return "add{w}\t{%2, %0|%0, %2}";
6083     }
6084 }
6085   [(set (attr "type")
6086      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6087         (const_string "incdec")
6088         (const_string "alu")))
6089    (set_attr "mode" "HI")])
6090
6091 (define_insn "*addhi_3"
6092   [(set (reg 17)
6093         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6094                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6095    (clobber (match_scratch:HI 0 "=r"))]
6096   "ix86_match_ccmode (insn, CCZmode)
6097    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6098 {
6099   switch (get_attr_type (insn))
6100     {
6101     case TYPE_INCDEC:
6102       if (operands[2] == const1_rtx)
6103         return "inc{w}\t%0";
6104       else if (operands[2] == constm1_rtx)
6105         return "dec{w}\t%0";
6106       abort();
6107
6108     default:
6109       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6110          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6111       if (GET_CODE (operands[2]) == CONST_INT
6112           && (INTVAL (operands[2]) == 128
6113               || (INTVAL (operands[2]) < 0
6114                   && INTVAL (operands[2]) != -128)))
6115         {
6116           operands[2] = GEN_INT (-INTVAL (operands[2]));
6117           return "sub{w}\t{%2, %0|%0, %2}";
6118         }
6119       return "add{w}\t{%2, %0|%0, %2}";
6120     }
6121 }
6122   [(set (attr "type")
6123      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6124         (const_string "incdec")
6125         (const_string "alu")))
6126    (set_attr "mode" "HI")])
6127
6128 ; See comments above addsi_3_imm for details.
6129 (define_insn "*addhi_4"
6130   [(set (reg 17)
6131         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6132                  (match_operand:HI 2 "const_int_operand" "n")))
6133    (clobber (match_scratch:HI 0 "=rm"))]
6134   "ix86_match_ccmode (insn, CCGCmode)
6135    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6136 {
6137   switch (get_attr_type (insn))
6138     {
6139     case TYPE_INCDEC:
6140       if (operands[2] == constm1_rtx)
6141         return "inc{w}\t%0";
6142       else if (operands[2] == const1_rtx)
6143         return "dec{w}\t%0";
6144       else
6145         abort();
6146
6147     default:
6148       if (! rtx_equal_p (operands[0], operands[1]))
6149         abort ();
6150       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6151          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6152       if ((INTVAL (operands[2]) == -128
6153            || (INTVAL (operands[2]) > 0
6154                && INTVAL (operands[2]) != 128)))
6155         return "sub{w}\t{%2, %0|%0, %2}";
6156       operands[2] = GEN_INT (-INTVAL (operands[2]));
6157       return "add{w}\t{%2, %0|%0, %2}";
6158     }
6159 }
6160   [(set (attr "type")
6161      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6162         (const_string "incdec")
6163         (const_string "alu")))
6164    (set_attr "mode" "SI")])
6165
6166
6167 (define_insn "*addhi_5"
6168   [(set (reg 17)
6169         (compare
6170           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6171                    (match_operand:HI 2 "general_operand" "rmni"))
6172           (const_int 0)))                       
6173    (clobber (match_scratch:HI 0 "=r"))]
6174   "ix86_match_ccmode (insn, CCGOCmode)
6175    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6176 {
6177   switch (get_attr_type (insn))
6178     {
6179     case TYPE_INCDEC:
6180       if (operands[2] == const1_rtx)
6181         return "inc{w}\t%0";
6182       else if (operands[2] == constm1_rtx)
6183         return "dec{w}\t%0";
6184       abort();
6185
6186     default:
6187       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6188          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6189       if (GET_CODE (operands[2]) == CONST_INT
6190           && (INTVAL (operands[2]) == 128
6191               || (INTVAL (operands[2]) < 0
6192                   && INTVAL (operands[2]) != -128)))
6193         {
6194           operands[2] = GEN_INT (-INTVAL (operands[2]));
6195           return "sub{w}\t{%2, %0|%0, %2}";
6196         }
6197       return "add{w}\t{%2, %0|%0, %2}";
6198     }
6199 }
6200   [(set (attr "type")
6201      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6202         (const_string "incdec")
6203         (const_string "alu")))
6204    (set_attr "mode" "HI")])
6205
6206 (define_expand "addqi3"
6207   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6208                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6209                             (match_operand:QI 2 "general_operand" "")))
6210               (clobber (reg:CC FLAGS_REG))])]
6211   "TARGET_QIMODE_MATH"
6212   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6213
6214 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6215 (define_insn "*addqi_1_lea"
6216   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6217         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6218                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6219    (clobber (reg:CC FLAGS_REG))]
6220   "!TARGET_PARTIAL_REG_STALL
6221    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6222 {
6223   int widen = (which_alternative == 2);
6224   switch (get_attr_type (insn))
6225     {
6226     case TYPE_LEA:
6227       return "#";
6228     case TYPE_INCDEC:
6229       if (operands[2] == const1_rtx)
6230         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6231       else if (operands[2] == constm1_rtx)
6232         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6233       abort();
6234
6235     default:
6236       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6237          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6238       if (GET_CODE (operands[2]) == CONST_INT
6239           && (INTVAL (operands[2]) == 128
6240               || (INTVAL (operands[2]) < 0
6241                   && INTVAL (operands[2]) != -128)))
6242         {
6243           operands[2] = GEN_INT (-INTVAL (operands[2]));
6244           if (widen)
6245             return "sub{l}\t{%2, %k0|%k0, %2}";
6246           else
6247             return "sub{b}\t{%2, %0|%0, %2}";
6248         }
6249       if (widen)
6250         return "add{l}\t{%k2, %k0|%k0, %k2}";
6251       else
6252         return "add{b}\t{%2, %0|%0, %2}";
6253     }
6254 }
6255   [(set (attr "type")
6256      (if_then_else (eq_attr "alternative" "3")
6257         (const_string "lea")
6258         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6259            (const_string "incdec")
6260            (const_string "alu"))))
6261    (set_attr "mode" "QI,QI,SI,SI")])
6262
6263 (define_insn "*addqi_1"
6264   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6265         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6266                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6267    (clobber (reg:CC FLAGS_REG))]
6268   "TARGET_PARTIAL_REG_STALL
6269    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6270 {
6271   int widen = (which_alternative == 2);
6272   switch (get_attr_type (insn))
6273     {
6274     case TYPE_INCDEC:
6275       if (operands[2] == const1_rtx)
6276         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6277       else if (operands[2] == constm1_rtx)
6278         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6279       abort();
6280
6281     default:
6282       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6283          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6284       if (GET_CODE (operands[2]) == CONST_INT
6285           && (INTVAL (operands[2]) == 128
6286               || (INTVAL (operands[2]) < 0
6287                   && INTVAL (operands[2]) != -128)))
6288         {
6289           operands[2] = GEN_INT (-INTVAL (operands[2]));
6290           if (widen)
6291             return "sub{l}\t{%2, %k0|%k0, %2}";
6292           else
6293             return "sub{b}\t{%2, %0|%0, %2}";
6294         }
6295       if (widen)
6296         return "add{l}\t{%k2, %k0|%k0, %k2}";
6297       else
6298         return "add{b}\t{%2, %0|%0, %2}";
6299     }
6300 }
6301   [(set (attr "type")
6302      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6303         (const_string "incdec")
6304         (const_string "alu")))
6305    (set_attr "mode" "QI,QI,SI")])
6306
6307 (define_insn "*addqi_1_slp"
6308   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6309         (plus:QI (match_dup 0)
6310                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6311    (clobber (reg:CC FLAGS_REG))]
6312   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6313    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6314 {
6315   switch (get_attr_type (insn))
6316     {
6317     case TYPE_INCDEC:
6318       if (operands[1] == const1_rtx)
6319         return "inc{b}\t%0";
6320       else if (operands[1] == constm1_rtx)
6321         return "dec{b}\t%0";
6322       abort();
6323
6324     default:
6325       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6326       if (GET_CODE (operands[1]) == CONST_INT
6327           && INTVAL (operands[1]) < 0)
6328         {
6329           operands[1] = GEN_INT (-INTVAL (operands[1]));
6330           return "sub{b}\t{%1, %0|%0, %1}";
6331         }
6332       return "add{b}\t{%1, %0|%0, %1}";
6333     }
6334 }
6335   [(set (attr "type")
6336      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6337         (const_string "incdec")
6338         (const_string "alu1")))
6339    (set_attr "mode" "QI")])
6340
6341 (define_insn "*addqi_2"
6342   [(set (reg 17)
6343         (compare
6344           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6345                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6346           (const_int 0)))
6347    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6348         (plus:QI (match_dup 1) (match_dup 2)))]
6349   "ix86_match_ccmode (insn, CCGOCmode)
6350    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6351 {
6352   switch (get_attr_type (insn))
6353     {
6354     case TYPE_INCDEC:
6355       if (operands[2] == const1_rtx)
6356         return "inc{b}\t%0";
6357       else if (operands[2] == constm1_rtx
6358                || (GET_CODE (operands[2]) == CONST_INT
6359                    && INTVAL (operands[2]) == 255))
6360         return "dec{b}\t%0";
6361       abort();
6362
6363     default:
6364       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6365       if (GET_CODE (operands[2]) == CONST_INT
6366           && INTVAL (operands[2]) < 0)
6367         {
6368           operands[2] = GEN_INT (-INTVAL (operands[2]));
6369           return "sub{b}\t{%2, %0|%0, %2}";
6370         }
6371       return "add{b}\t{%2, %0|%0, %2}";
6372     }
6373 }
6374   [(set (attr "type")
6375      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6376         (const_string "incdec")
6377         (const_string "alu")))
6378    (set_attr "mode" "QI")])
6379
6380 (define_insn "*addqi_3"
6381   [(set (reg 17)
6382         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6383                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6384    (clobber (match_scratch:QI 0 "=q"))]
6385   "ix86_match_ccmode (insn, CCZmode)
6386    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6387 {
6388   switch (get_attr_type (insn))
6389     {
6390     case TYPE_INCDEC:
6391       if (operands[2] == const1_rtx)
6392         return "inc{b}\t%0";
6393       else if (operands[2] == constm1_rtx
6394                || (GET_CODE (operands[2]) == CONST_INT
6395                    && INTVAL (operands[2]) == 255))
6396         return "dec{b}\t%0";
6397       abort();
6398
6399     default:
6400       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6401       if (GET_CODE (operands[2]) == CONST_INT
6402           && INTVAL (operands[2]) < 0)
6403         {
6404           operands[2] = GEN_INT (-INTVAL (operands[2]));
6405           return "sub{b}\t{%2, %0|%0, %2}";
6406         }
6407       return "add{b}\t{%2, %0|%0, %2}";
6408     }
6409 }
6410   [(set (attr "type")
6411      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6412         (const_string "incdec")
6413         (const_string "alu")))
6414    (set_attr "mode" "QI")])
6415
6416 ; See comments above addsi_3_imm for details.
6417 (define_insn "*addqi_4"
6418   [(set (reg 17)
6419         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6420                  (match_operand:QI 2 "const_int_operand" "n")))
6421    (clobber (match_scratch:QI 0 "=qm"))]
6422   "ix86_match_ccmode (insn, CCGCmode)
6423    && (INTVAL (operands[2]) & 0xff) != 0x80"
6424 {
6425   switch (get_attr_type (insn))
6426     {
6427     case TYPE_INCDEC:
6428       if (operands[2] == constm1_rtx
6429           || (GET_CODE (operands[2]) == CONST_INT
6430               && INTVAL (operands[2]) == 255))
6431         return "inc{b}\t%0";
6432       else if (operands[2] == const1_rtx)
6433         return "dec{b}\t%0";
6434       else
6435         abort();
6436
6437     default:
6438       if (! rtx_equal_p (operands[0], operands[1]))
6439         abort ();
6440       if (INTVAL (operands[2]) < 0)
6441         {
6442           operands[2] = GEN_INT (-INTVAL (operands[2]));
6443           return "add{b}\t{%2, %0|%0, %2}";
6444         }
6445       return "sub{b}\t{%2, %0|%0, %2}";
6446     }
6447 }
6448   [(set (attr "type")
6449      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6450         (const_string "incdec")
6451         (const_string "alu")))
6452    (set_attr "mode" "QI")])
6453
6454
6455 (define_insn "*addqi_5"
6456   [(set (reg 17)
6457         (compare
6458           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6459                    (match_operand:QI 2 "general_operand" "qmni"))
6460           (const_int 0)))
6461    (clobber (match_scratch:QI 0 "=q"))]
6462   "ix86_match_ccmode (insn, CCGOCmode)
6463    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6464 {
6465   switch (get_attr_type (insn))
6466     {
6467     case TYPE_INCDEC:
6468       if (operands[2] == const1_rtx)
6469         return "inc{b}\t%0";
6470       else if (operands[2] == constm1_rtx
6471                || (GET_CODE (operands[2]) == CONST_INT
6472                    && INTVAL (operands[2]) == 255))
6473         return "dec{b}\t%0";
6474       abort();
6475
6476     default:
6477       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6478       if (GET_CODE (operands[2]) == CONST_INT
6479           && INTVAL (operands[2]) < 0)
6480         {
6481           operands[2] = GEN_INT (-INTVAL (operands[2]));
6482           return "sub{b}\t{%2, %0|%0, %2}";
6483         }
6484       return "add{b}\t{%2, %0|%0, %2}";
6485     }
6486 }
6487   [(set (attr "type")
6488      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6489         (const_string "incdec")
6490         (const_string "alu")))
6491    (set_attr "mode" "QI")])
6492
6493
6494 (define_insn "addqi_ext_1"
6495   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6496                          (const_int 8)
6497                          (const_int 8))
6498         (plus:SI
6499           (zero_extract:SI
6500             (match_operand 1 "ext_register_operand" "0")
6501             (const_int 8)
6502             (const_int 8))
6503           (match_operand:QI 2 "general_operand" "Qmn")))
6504    (clobber (reg:CC FLAGS_REG))]
6505   "!TARGET_64BIT"
6506 {
6507   switch (get_attr_type (insn))
6508     {
6509     case TYPE_INCDEC:
6510       if (operands[2] == const1_rtx)
6511         return "inc{b}\t%h0";
6512       else if (operands[2] == constm1_rtx
6513                || (GET_CODE (operands[2]) == CONST_INT
6514                    && INTVAL (operands[2]) == 255))
6515         return "dec{b}\t%h0";
6516       abort();
6517
6518     default:
6519       return "add{b}\t{%2, %h0|%h0, %2}";
6520     }
6521 }
6522   [(set (attr "type")
6523      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6524         (const_string "incdec")
6525         (const_string "alu")))
6526    (set_attr "mode" "QI")])
6527
6528 (define_insn "*addqi_ext_1_rex64"
6529   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6530                          (const_int 8)
6531                          (const_int 8))
6532         (plus:SI
6533           (zero_extract:SI
6534             (match_operand 1 "ext_register_operand" "0")
6535             (const_int 8)
6536             (const_int 8))
6537           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6538    (clobber (reg:CC FLAGS_REG))]
6539   "TARGET_64BIT"
6540 {
6541   switch (get_attr_type (insn))
6542     {
6543     case TYPE_INCDEC:
6544       if (operands[2] == const1_rtx)
6545         return "inc{b}\t%h0";
6546       else if (operands[2] == constm1_rtx
6547                || (GET_CODE (operands[2]) == CONST_INT
6548                    && INTVAL (operands[2]) == 255))
6549         return "dec{b}\t%h0";
6550       abort();
6551
6552     default:
6553       return "add{b}\t{%2, %h0|%h0, %2}";
6554     }
6555 }
6556   [(set (attr "type")
6557      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6558         (const_string "incdec")
6559         (const_string "alu")))
6560    (set_attr "mode" "QI")])
6561
6562 (define_insn "*addqi_ext_2"
6563   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6564                          (const_int 8)
6565                          (const_int 8))
6566         (plus:SI
6567           (zero_extract:SI
6568             (match_operand 1 "ext_register_operand" "%0")
6569             (const_int 8)
6570             (const_int 8))
6571           (zero_extract:SI
6572             (match_operand 2 "ext_register_operand" "Q")
6573             (const_int 8)
6574             (const_int 8))))
6575    (clobber (reg:CC FLAGS_REG))]
6576   ""
6577   "add{b}\t{%h2, %h0|%h0, %h2}"
6578   [(set_attr "type" "alu")
6579    (set_attr "mode" "QI")])
6580
6581 ;; The patterns that match these are at the end of this file.
6582
6583 (define_expand "addxf3"
6584   [(set (match_operand:XF 0 "register_operand" "")
6585         (plus:XF (match_operand:XF 1 "register_operand" "")
6586                  (match_operand:XF 2 "register_operand" "")))]
6587   "TARGET_80387"
6588   "")
6589
6590 (define_expand "adddf3"
6591   [(set (match_operand:DF 0 "register_operand" "")
6592         (plus:DF (match_operand:DF 1 "register_operand" "")
6593                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6594   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6595   "")
6596
6597 (define_expand "addsf3"
6598   [(set (match_operand:SF 0 "register_operand" "")
6599         (plus:SF (match_operand:SF 1 "register_operand" "")
6600                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6601   "TARGET_80387 || TARGET_SSE_MATH"
6602   "")
6603 \f
6604 ;; Subtract instructions
6605
6606 ;; %%% splits for subsidi3
6607
6608 (define_expand "subdi3"
6609   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6610                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6611                              (match_operand:DI 2 "x86_64_general_operand" "")))
6612               (clobber (reg:CC FLAGS_REG))])]
6613   ""
6614   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6615
6616 (define_insn "*subdi3_1"
6617   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6618         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6619                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6620    (clobber (reg:CC FLAGS_REG))]
6621   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6622   "#")
6623
6624 (define_split
6625   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6626         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6627                   (match_operand:DI 2 "general_operand" "")))
6628    (clobber (reg:CC FLAGS_REG))]
6629   "!TARGET_64BIT && reload_completed"
6630   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6631               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6632    (parallel [(set (match_dup 3)
6633                    (minus:SI (match_dup 4)
6634                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6635                                       (match_dup 5))))
6636               (clobber (reg:CC FLAGS_REG))])]
6637   "split_di (operands+0, 1, operands+0, operands+3);
6638    split_di (operands+1, 1, operands+1, operands+4);
6639    split_di (operands+2, 1, operands+2, operands+5);")
6640
6641 (define_insn "subdi3_carry_rex64"
6642   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6643           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6644             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6645                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6646    (clobber (reg:CC FLAGS_REG))]
6647   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6648   "sbb{q}\t{%2, %0|%0, %2}"
6649   [(set_attr "type" "alu")
6650    (set_attr "pent_pair" "pu")
6651    (set_attr "mode" "DI")])
6652
6653 (define_insn "*subdi_1_rex64"
6654   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6655         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6656                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6657    (clobber (reg:CC FLAGS_REG))]
6658   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6659   "sub{q}\t{%2, %0|%0, %2}"
6660   [(set_attr "type" "alu")
6661    (set_attr "mode" "DI")])
6662
6663 (define_insn "*subdi_2_rex64"
6664   [(set (reg 17)
6665         (compare
6666           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6667                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6668           (const_int 0)))
6669    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6670         (minus:DI (match_dup 1) (match_dup 2)))]
6671   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6672    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6673   "sub{q}\t{%2, %0|%0, %2}"
6674   [(set_attr "type" "alu")
6675    (set_attr "mode" "DI")])
6676
6677 (define_insn "*subdi_3_rex63"
6678   [(set (reg 17)
6679         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6680                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6681    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6682         (minus:DI (match_dup 1) (match_dup 2)))]
6683   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6684    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6685   "sub{q}\t{%2, %0|%0, %2}"
6686   [(set_attr "type" "alu")
6687    (set_attr "mode" "DI")])
6688
6689 (define_insn "subqi3_carry"
6690   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6691           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6692             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6693                (match_operand:QI 2 "general_operand" "qi,qm"))))
6694    (clobber (reg:CC FLAGS_REG))]
6695   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6696   "sbb{b}\t{%2, %0|%0, %2}"
6697   [(set_attr "type" "alu")
6698    (set_attr "pent_pair" "pu")
6699    (set_attr "mode" "QI")])
6700
6701 (define_insn "subhi3_carry"
6702   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6703           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6704             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6705                (match_operand:HI 2 "general_operand" "ri,rm"))))
6706    (clobber (reg:CC FLAGS_REG))]
6707   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6708   "sbb{w}\t{%2, %0|%0, %2}"
6709   [(set_attr "type" "alu")
6710    (set_attr "pent_pair" "pu")
6711    (set_attr "mode" "HI")])
6712
6713 (define_insn "subsi3_carry"
6714   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6715           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6716             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6717                (match_operand:SI 2 "general_operand" "ri,rm"))))
6718    (clobber (reg:CC FLAGS_REG))]
6719   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6720   "sbb{l}\t{%2, %0|%0, %2}"
6721   [(set_attr "type" "alu")
6722    (set_attr "pent_pair" "pu")
6723    (set_attr "mode" "SI")])
6724
6725 (define_insn "subsi3_carry_zext"
6726   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6727           (zero_extend:DI
6728             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6729               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6730                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6731    (clobber (reg:CC FLAGS_REG))]
6732   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6733   "sbb{l}\t{%2, %k0|%k0, %2}"
6734   [(set_attr "type" "alu")
6735    (set_attr "pent_pair" "pu")
6736    (set_attr "mode" "SI")])
6737
6738 (define_expand "subsi3"
6739   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6740                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6741                              (match_operand:SI 2 "general_operand" "")))
6742               (clobber (reg:CC FLAGS_REG))])]
6743   ""
6744   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6745
6746 (define_insn "*subsi_1"
6747   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6748         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6749                   (match_operand:SI 2 "general_operand" "ri,rm")))
6750    (clobber (reg:CC FLAGS_REG))]
6751   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6752   "sub{l}\t{%2, %0|%0, %2}"
6753   [(set_attr "type" "alu")
6754    (set_attr "mode" "SI")])
6755
6756 (define_insn "*subsi_1_zext"
6757   [(set (match_operand:DI 0 "register_operand" "=r")
6758         (zero_extend:DI
6759           (minus:SI (match_operand:SI 1 "register_operand" "0")
6760                     (match_operand:SI 2 "general_operand" "rim"))))
6761    (clobber (reg:CC FLAGS_REG))]
6762   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6763   "sub{l}\t{%2, %k0|%k0, %2}"
6764   [(set_attr "type" "alu")
6765    (set_attr "mode" "SI")])
6766
6767 (define_insn "*subsi_2"
6768   [(set (reg 17)
6769         (compare
6770           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6771                     (match_operand:SI 2 "general_operand" "ri,rm"))
6772           (const_int 0)))
6773    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6774         (minus:SI (match_dup 1) (match_dup 2)))]
6775   "ix86_match_ccmode (insn, CCGOCmode)
6776    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6777   "sub{l}\t{%2, %0|%0, %2}"
6778   [(set_attr "type" "alu")
6779    (set_attr "mode" "SI")])
6780
6781 (define_insn "*subsi_2_zext"
6782   [(set (reg 17)
6783         (compare
6784           (minus:SI (match_operand:SI 1 "register_operand" "0")
6785                     (match_operand:SI 2 "general_operand" "rim"))
6786           (const_int 0)))
6787    (set (match_operand:DI 0 "register_operand" "=r")
6788         (zero_extend:DI
6789           (minus:SI (match_dup 1)
6790                     (match_dup 2))))]
6791   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6792    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6793   "sub{l}\t{%2, %k0|%k0, %2}"
6794   [(set_attr "type" "alu")
6795    (set_attr "mode" "SI")])
6796
6797 (define_insn "*subsi_3"
6798   [(set (reg 17)
6799         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6800                  (match_operand:SI 2 "general_operand" "ri,rm")))
6801    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6802         (minus:SI (match_dup 1) (match_dup 2)))]
6803   "ix86_match_ccmode (insn, CCmode)
6804    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6805   "sub{l}\t{%2, %0|%0, %2}"
6806   [(set_attr "type" "alu")
6807    (set_attr "mode" "SI")])
6808
6809 (define_insn "*subsi_3_zext"
6810   [(set (reg 17)
6811         (compare (match_operand:SI 1 "register_operand" "0")
6812                  (match_operand:SI 2 "general_operand" "rim")))
6813    (set (match_operand:DI 0 "register_operand" "=r")
6814         (zero_extend:DI
6815           (minus:SI (match_dup 1)
6816                     (match_dup 2))))]
6817   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6818    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6819   "sub{q}\t{%2, %0|%0, %2}"
6820   [(set_attr "type" "alu")
6821    (set_attr "mode" "DI")])
6822
6823 (define_expand "subhi3"
6824   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6825                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6826                              (match_operand:HI 2 "general_operand" "")))
6827               (clobber (reg:CC FLAGS_REG))])]
6828   "TARGET_HIMODE_MATH"
6829   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6830
6831 (define_insn "*subhi_1"
6832   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6833         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6834                   (match_operand:HI 2 "general_operand" "ri,rm")))
6835    (clobber (reg:CC FLAGS_REG))]
6836   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6837   "sub{w}\t{%2, %0|%0, %2}"
6838   [(set_attr "type" "alu")
6839    (set_attr "mode" "HI")])
6840
6841 (define_insn "*subhi_2"
6842   [(set (reg 17)
6843         (compare
6844           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6845                     (match_operand:HI 2 "general_operand" "ri,rm"))
6846           (const_int 0)))
6847    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6848         (minus:HI (match_dup 1) (match_dup 2)))]
6849   "ix86_match_ccmode (insn, CCGOCmode)
6850    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6851   "sub{w}\t{%2, %0|%0, %2}"
6852   [(set_attr "type" "alu")
6853    (set_attr "mode" "HI")])
6854
6855 (define_insn "*subhi_3"
6856   [(set (reg 17)
6857         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6858                  (match_operand:HI 2 "general_operand" "ri,rm")))
6859    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6860         (minus:HI (match_dup 1) (match_dup 2)))]
6861   "ix86_match_ccmode (insn, CCmode)
6862    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6863   "sub{w}\t{%2, %0|%0, %2}"
6864   [(set_attr "type" "alu")
6865    (set_attr "mode" "HI")])
6866
6867 (define_expand "subqi3"
6868   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6869                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6870                              (match_operand:QI 2 "general_operand" "")))
6871               (clobber (reg:CC FLAGS_REG))])]
6872   "TARGET_QIMODE_MATH"
6873   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6874
6875 (define_insn "*subqi_1"
6876   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6877         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6878                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6879    (clobber (reg:CC FLAGS_REG))]
6880   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6881   "sub{b}\t{%2, %0|%0, %2}"
6882   [(set_attr "type" "alu")
6883    (set_attr "mode" "QI")])
6884
6885 (define_insn "*subqi_1_slp"
6886   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6887         (minus:QI (match_dup 0)
6888                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6889    (clobber (reg:CC FLAGS_REG))]
6890   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6891    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6892   "sub{b}\t{%1, %0|%0, %1}"
6893   [(set_attr "type" "alu1")
6894    (set_attr "mode" "QI")])
6895
6896 (define_insn "*subqi_2"
6897   [(set (reg 17)
6898         (compare
6899           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6900                     (match_operand:QI 2 "general_operand" "qi,qm"))
6901           (const_int 0)))
6902    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6903         (minus:HI (match_dup 1) (match_dup 2)))]
6904   "ix86_match_ccmode (insn, CCGOCmode)
6905    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6906   "sub{b}\t{%2, %0|%0, %2}"
6907   [(set_attr "type" "alu")
6908    (set_attr "mode" "QI")])
6909
6910 (define_insn "*subqi_3"
6911   [(set (reg 17)
6912         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6913                  (match_operand:QI 2 "general_operand" "qi,qm")))
6914    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6915         (minus:HI (match_dup 1) (match_dup 2)))]
6916   "ix86_match_ccmode (insn, CCmode)
6917    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6918   "sub{b}\t{%2, %0|%0, %2}"
6919   [(set_attr "type" "alu")
6920    (set_attr "mode" "QI")])
6921
6922 ;; The patterns that match these are at the end of this file.
6923
6924 (define_expand "subxf3"
6925   [(set (match_operand:XF 0 "register_operand" "")
6926         (minus:XF (match_operand:XF 1 "register_operand" "")
6927                   (match_operand:XF 2 "register_operand" "")))]
6928   "TARGET_80387"
6929   "")
6930
6931 (define_expand "subdf3"
6932   [(set (match_operand:DF 0 "register_operand" "")
6933         (minus:DF (match_operand:DF 1 "register_operand" "")
6934                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6935   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6936   "")
6937
6938 (define_expand "subsf3"
6939   [(set (match_operand:SF 0 "register_operand" "")
6940         (minus:SF (match_operand:SF 1 "register_operand" "")
6941                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6942   "TARGET_80387 || TARGET_SSE_MATH"
6943   "")
6944 \f
6945 ;; Multiply instructions
6946
6947 (define_expand "muldi3"
6948   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6949                    (mult:DI (match_operand:DI 1 "register_operand" "")
6950                             (match_operand:DI 2 "x86_64_general_operand" "")))
6951               (clobber (reg:CC FLAGS_REG))])]
6952   "TARGET_64BIT"
6953   "")
6954
6955 (define_insn "*muldi3_1_rex64"
6956   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6957         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6958                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6959    (clobber (reg:CC FLAGS_REG))]
6960   "TARGET_64BIT
6961    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6962   "@
6963    imul{q}\t{%2, %1, %0|%0, %1, %2}
6964    imul{q}\t{%2, %1, %0|%0, %1, %2}
6965    imul{q}\t{%2, %0|%0, %2}"
6966   [(set_attr "type" "imul")
6967    (set_attr "prefix_0f" "0,0,1")
6968    (set (attr "athlon_decode")
6969         (cond [(eq_attr "cpu" "athlon")
6970                   (const_string "vector")
6971                (eq_attr "alternative" "1")
6972                   (const_string "vector")
6973                (and (eq_attr "alternative" "2")
6974                     (match_operand 1 "memory_operand" ""))
6975                   (const_string "vector")]
6976               (const_string "direct")))
6977    (set_attr "mode" "DI")])
6978
6979 (define_expand "mulsi3"
6980   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6981                    (mult:SI (match_operand:SI 1 "register_operand" "")
6982                             (match_operand:SI 2 "general_operand" "")))
6983               (clobber (reg:CC FLAGS_REG))])]
6984   ""
6985   "")
6986
6987 (define_insn "*mulsi3_1"
6988   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6989         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6990                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6991    (clobber (reg:CC FLAGS_REG))]
6992   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6993   "@
6994    imul{l}\t{%2, %1, %0|%0, %1, %2}
6995    imul{l}\t{%2, %1, %0|%0, %1, %2}
6996    imul{l}\t{%2, %0|%0, %2}"
6997   [(set_attr "type" "imul")
6998    (set_attr "prefix_0f" "0,0,1")
6999    (set (attr "athlon_decode")
7000         (cond [(eq_attr "cpu" "athlon")
7001                   (const_string "vector")
7002                (eq_attr "alternative" "1")
7003                   (const_string "vector")
7004                (and (eq_attr "alternative" "2")
7005                     (match_operand 1 "memory_operand" ""))
7006                   (const_string "vector")]
7007               (const_string "direct")))
7008    (set_attr "mode" "SI")])
7009
7010 (define_insn "*mulsi3_1_zext"
7011   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7012         (zero_extend:DI
7013           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7014                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7015    (clobber (reg:CC FLAGS_REG))]
7016   "TARGET_64BIT
7017    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7018   "@
7019    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7020    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7021    imul{l}\t{%2, %k0|%k0, %2}"
7022   [(set_attr "type" "imul")
7023    (set_attr "prefix_0f" "0,0,1")
7024    (set (attr "athlon_decode")
7025         (cond [(eq_attr "cpu" "athlon")
7026                   (const_string "vector")
7027                (eq_attr "alternative" "1")
7028                   (const_string "vector")
7029                (and (eq_attr "alternative" "2")
7030                     (match_operand 1 "memory_operand" ""))
7031                   (const_string "vector")]
7032               (const_string "direct")))
7033    (set_attr "mode" "SI")])
7034
7035 (define_expand "mulhi3"
7036   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7037                    (mult:HI (match_operand:HI 1 "register_operand" "")
7038                             (match_operand:HI 2 "general_operand" "")))
7039               (clobber (reg:CC FLAGS_REG))])]
7040   "TARGET_HIMODE_MATH"
7041   "")
7042
7043 (define_insn "*mulhi3_1"
7044   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7045         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7046                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7047    (clobber (reg:CC FLAGS_REG))]
7048   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7049   "@
7050    imul{w}\t{%2, %1, %0|%0, %1, %2}
7051    imul{w}\t{%2, %1, %0|%0, %1, %2}
7052    imul{w}\t{%2, %0|%0, %2}"
7053   [(set_attr "type" "imul")
7054    (set_attr "prefix_0f" "0,0,1")
7055    (set (attr "athlon_decode")
7056         (cond [(eq_attr "cpu" "athlon")
7057                   (const_string "vector")
7058                (eq_attr "alternative" "1,2")
7059                   (const_string "vector")]
7060               (const_string "direct")))
7061    (set_attr "mode" "HI")])
7062
7063 (define_expand "mulqi3"
7064   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7065                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7066                             (match_operand:QI 2 "register_operand" "")))
7067               (clobber (reg:CC FLAGS_REG))])]
7068   "TARGET_QIMODE_MATH"
7069   "")
7070
7071 (define_insn "*mulqi3_1"
7072   [(set (match_operand:QI 0 "register_operand" "=a")
7073         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7074                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7075    (clobber (reg:CC FLAGS_REG))]
7076   "TARGET_QIMODE_MATH
7077    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7078   "mul{b}\t%2"
7079   [(set_attr "type" "imul")
7080    (set_attr "length_immediate" "0")
7081    (set (attr "athlon_decode")
7082      (if_then_else (eq_attr "cpu" "athlon")
7083         (const_string "vector")
7084         (const_string "direct")))
7085    (set_attr "mode" "QI")])
7086
7087 (define_expand "umulqihi3"
7088   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7089                    (mult:HI (zero_extend:HI
7090                               (match_operand:QI 1 "nonimmediate_operand" ""))
7091                             (zero_extend:HI
7092                               (match_operand:QI 2 "register_operand" ""))))
7093               (clobber (reg:CC FLAGS_REG))])]
7094   "TARGET_QIMODE_MATH"
7095   "")
7096
7097 (define_insn "*umulqihi3_1"
7098   [(set (match_operand:HI 0 "register_operand" "=a")
7099         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7100                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7101    (clobber (reg:CC FLAGS_REG))]
7102   "TARGET_QIMODE_MATH
7103    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7104   "mul{b}\t%2"
7105   [(set_attr "type" "imul")
7106    (set_attr "length_immediate" "0")
7107    (set (attr "athlon_decode")
7108      (if_then_else (eq_attr "cpu" "athlon")
7109         (const_string "vector")
7110         (const_string "direct")))
7111    (set_attr "mode" "QI")])
7112
7113 (define_expand "mulqihi3"
7114   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7115                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7116                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7117               (clobber (reg:CC FLAGS_REG))])]
7118   "TARGET_QIMODE_MATH"
7119   "")
7120
7121 (define_insn "*mulqihi3_insn"
7122   [(set (match_operand:HI 0 "register_operand" "=a")
7123         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7124                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7125    (clobber (reg:CC FLAGS_REG))]
7126   "TARGET_QIMODE_MATH
7127    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7128   "imul{b}\t%2"
7129   [(set_attr "type" "imul")
7130    (set_attr "length_immediate" "0")
7131    (set (attr "athlon_decode")
7132      (if_then_else (eq_attr "cpu" "athlon")
7133         (const_string "vector")
7134         (const_string "direct")))
7135    (set_attr "mode" "QI")])
7136
7137 (define_expand "umulditi3"
7138   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7139                    (mult:TI (zero_extend:TI
7140                               (match_operand:DI 1 "nonimmediate_operand" ""))
7141                             (zero_extend:TI
7142                               (match_operand:DI 2 "register_operand" ""))))
7143               (clobber (reg:CC FLAGS_REG))])]
7144   "TARGET_64BIT"
7145   "")
7146
7147 (define_insn "*umulditi3_insn"
7148   [(set (match_operand:TI 0 "register_operand" "=A")
7149         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7150                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7151    (clobber (reg:CC FLAGS_REG))]
7152   "TARGET_64BIT
7153    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7154   "mul{q}\t%2"
7155   [(set_attr "type" "imul")
7156    (set_attr "length_immediate" "0")
7157    (set (attr "athlon_decode")
7158      (if_then_else (eq_attr "cpu" "athlon")
7159         (const_string "vector")
7160         (const_string "double")))
7161    (set_attr "mode" "DI")])
7162
7163 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7164 (define_expand "umulsidi3"
7165   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7166                    (mult:DI (zero_extend:DI
7167                               (match_operand:SI 1 "nonimmediate_operand" ""))
7168                             (zero_extend:DI
7169                               (match_operand:SI 2 "register_operand" ""))))
7170               (clobber (reg:CC FLAGS_REG))])]
7171   "!TARGET_64BIT"
7172   "")
7173
7174 (define_insn "*umulsidi3_insn"
7175   [(set (match_operand:DI 0 "register_operand" "=A")
7176         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7177                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7178    (clobber (reg:CC FLAGS_REG))]
7179   "!TARGET_64BIT
7180    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7181   "mul{l}\t%2"
7182   [(set_attr "type" "imul")
7183    (set_attr "length_immediate" "0")
7184    (set (attr "athlon_decode")
7185      (if_then_else (eq_attr "cpu" "athlon")
7186         (const_string "vector")
7187         (const_string "double")))
7188    (set_attr "mode" "SI")])
7189
7190 (define_expand "mulditi3"
7191   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7192                    (mult:TI (sign_extend:TI
7193                               (match_operand:DI 1 "nonimmediate_operand" ""))
7194                             (sign_extend:TI
7195                               (match_operand:DI 2 "register_operand" ""))))
7196               (clobber (reg:CC FLAGS_REG))])]
7197   "TARGET_64BIT"
7198   "")
7199
7200 (define_insn "*mulditi3_insn"
7201   [(set (match_operand:TI 0 "register_operand" "=A")
7202         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7203                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7204    (clobber (reg:CC FLAGS_REG))]
7205   "TARGET_64BIT
7206    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7207   "imul{q}\t%2"
7208   [(set_attr "type" "imul")
7209    (set_attr "length_immediate" "0")
7210    (set (attr "athlon_decode")
7211      (if_then_else (eq_attr "cpu" "athlon")
7212         (const_string "vector")
7213         (const_string "double")))
7214    (set_attr "mode" "DI")])
7215
7216 (define_expand "mulsidi3"
7217   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7218                    (mult:DI (sign_extend:DI
7219                               (match_operand:SI 1 "nonimmediate_operand" ""))
7220                             (sign_extend:DI
7221                               (match_operand:SI 2 "register_operand" ""))))
7222               (clobber (reg:CC FLAGS_REG))])]
7223   "!TARGET_64BIT"
7224   "")
7225
7226 (define_insn "*mulsidi3_insn"
7227   [(set (match_operand:DI 0 "register_operand" "=A")
7228         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7229                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7230    (clobber (reg:CC FLAGS_REG))]
7231   "!TARGET_64BIT
7232    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7233   "imul{l}\t%2"
7234   [(set_attr "type" "imul")
7235    (set_attr "length_immediate" "0")
7236    (set (attr "athlon_decode")
7237      (if_then_else (eq_attr "cpu" "athlon")
7238         (const_string "vector")
7239         (const_string "double")))
7240    (set_attr "mode" "SI")])
7241
7242 (define_expand "umuldi3_highpart"
7243   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7244                    (truncate:DI
7245                      (lshiftrt:TI
7246                        (mult:TI (zero_extend:TI
7247                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7248                                 (zero_extend:TI
7249                                   (match_operand:DI 2 "register_operand" "")))
7250                        (const_int 64))))
7251               (clobber (match_scratch:DI 3 ""))
7252               (clobber (reg:CC FLAGS_REG))])]
7253   "TARGET_64BIT"
7254   "")
7255
7256 (define_insn "*umuldi3_highpart_rex64"
7257   [(set (match_operand:DI 0 "register_operand" "=d")
7258         (truncate:DI
7259           (lshiftrt:TI
7260             (mult:TI (zero_extend:TI
7261                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7262                      (zero_extend:TI
7263                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7264             (const_int 64))))
7265    (clobber (match_scratch:DI 3 "=1"))
7266    (clobber (reg:CC FLAGS_REG))]
7267   "TARGET_64BIT
7268    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7269   "mul{q}\t%2"
7270   [(set_attr "type" "imul")
7271    (set_attr "length_immediate" "0")
7272    (set (attr "athlon_decode")
7273      (if_then_else (eq_attr "cpu" "athlon")
7274         (const_string "vector")
7275         (const_string "double")))
7276    (set_attr "mode" "DI")])
7277
7278 (define_expand "umulsi3_highpart"
7279   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7280                    (truncate:SI
7281                      (lshiftrt:DI
7282                        (mult:DI (zero_extend:DI
7283                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7284                                 (zero_extend:DI
7285                                   (match_operand:SI 2 "register_operand" "")))
7286                        (const_int 32))))
7287               (clobber (match_scratch:SI 3 ""))
7288               (clobber (reg:CC FLAGS_REG))])]
7289   ""
7290   "")
7291
7292 (define_insn "*umulsi3_highpart_insn"
7293   [(set (match_operand:SI 0 "register_operand" "=d")
7294         (truncate:SI
7295           (lshiftrt:DI
7296             (mult:DI (zero_extend:DI
7297                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7298                      (zero_extend:DI
7299                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7300             (const_int 32))))
7301    (clobber (match_scratch:SI 3 "=1"))
7302    (clobber (reg:CC FLAGS_REG))]
7303   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7304   "mul{l}\t%2"
7305   [(set_attr "type" "imul")
7306    (set_attr "length_immediate" "0")
7307    (set (attr "athlon_decode")
7308      (if_then_else (eq_attr "cpu" "athlon")
7309         (const_string "vector")
7310         (const_string "double")))
7311    (set_attr "mode" "SI")])
7312
7313 (define_insn "*umulsi3_highpart_zext"
7314   [(set (match_operand:DI 0 "register_operand" "=d")
7315         (zero_extend:DI (truncate:SI
7316           (lshiftrt:DI
7317             (mult:DI (zero_extend:DI
7318                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7319                      (zero_extend:DI
7320                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7321             (const_int 32)))))
7322    (clobber (match_scratch:SI 3 "=1"))
7323    (clobber (reg:CC FLAGS_REG))]
7324   "TARGET_64BIT
7325    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7326   "mul{l}\t%2"
7327   [(set_attr "type" "imul")
7328    (set_attr "length_immediate" "0")
7329    (set (attr "athlon_decode")
7330      (if_then_else (eq_attr "cpu" "athlon")
7331         (const_string "vector")
7332         (const_string "double")))
7333    (set_attr "mode" "SI")])
7334
7335 (define_expand "smuldi3_highpart"
7336   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7337                    (truncate:DI
7338                      (lshiftrt:TI
7339                        (mult:TI (sign_extend:TI
7340                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7341                                 (sign_extend:TI
7342                                   (match_operand:DI 2 "register_operand" "")))
7343                        (const_int 64))))
7344               (clobber (match_scratch:DI 3 ""))
7345               (clobber (reg:CC FLAGS_REG))])]
7346   "TARGET_64BIT"
7347   "")
7348
7349 (define_insn "*smuldi3_highpart_rex64"
7350   [(set (match_operand:DI 0 "register_operand" "=d")
7351         (truncate:DI
7352           (lshiftrt:TI
7353             (mult:TI (sign_extend:TI
7354                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7355                      (sign_extend:TI
7356                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7357             (const_int 64))))
7358    (clobber (match_scratch:DI 3 "=1"))
7359    (clobber (reg:CC FLAGS_REG))]
7360   "TARGET_64BIT
7361    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7362   "imul{q}\t%2"
7363   [(set_attr "type" "imul")
7364    (set (attr "athlon_decode")
7365      (if_then_else (eq_attr "cpu" "athlon")
7366         (const_string "vector")
7367         (const_string "double")))
7368    (set_attr "mode" "DI")])
7369
7370 (define_expand "smulsi3_highpart"
7371   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7372                    (truncate:SI
7373                      (lshiftrt:DI
7374                        (mult:DI (sign_extend:DI
7375                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7376                                 (sign_extend:DI
7377                                   (match_operand:SI 2 "register_operand" "")))
7378                        (const_int 32))))
7379               (clobber (match_scratch:SI 3 ""))
7380               (clobber (reg:CC FLAGS_REG))])]
7381   ""
7382   "")
7383
7384 (define_insn "*smulsi3_highpart_insn"
7385   [(set (match_operand:SI 0 "register_operand" "=d")
7386         (truncate:SI
7387           (lshiftrt:DI
7388             (mult:DI (sign_extend:DI
7389                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7390                      (sign_extend:DI
7391                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7392             (const_int 32))))
7393    (clobber (match_scratch:SI 3 "=1"))
7394    (clobber (reg:CC FLAGS_REG))]
7395   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7396   "imul{l}\t%2"
7397   [(set_attr "type" "imul")
7398    (set (attr "athlon_decode")
7399      (if_then_else (eq_attr "cpu" "athlon")
7400         (const_string "vector")
7401         (const_string "double")))
7402    (set_attr "mode" "SI")])
7403
7404 (define_insn "*smulsi3_highpart_zext"
7405   [(set (match_operand:DI 0 "register_operand" "=d")
7406         (zero_extend:DI (truncate:SI
7407           (lshiftrt:DI
7408             (mult:DI (sign_extend:DI
7409                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7410                      (sign_extend:DI
7411                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7412             (const_int 32)))))
7413    (clobber (match_scratch:SI 3 "=1"))
7414    (clobber (reg:CC FLAGS_REG))]
7415   "TARGET_64BIT
7416    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7417   "imul{l}\t%2"
7418   [(set_attr "type" "imul")
7419    (set (attr "athlon_decode")
7420      (if_then_else (eq_attr "cpu" "athlon")
7421         (const_string "vector")
7422         (const_string "double")))
7423    (set_attr "mode" "SI")])
7424
7425 ;; The patterns that match these are at the end of this file.
7426
7427 (define_expand "mulxf3"
7428   [(set (match_operand:XF 0 "register_operand" "")
7429         (mult:XF (match_operand:XF 1 "register_operand" "")
7430                  (match_operand:XF 2 "register_operand" "")))]
7431   "TARGET_80387"
7432   "")
7433
7434 (define_expand "muldf3"
7435   [(set (match_operand:DF 0 "register_operand" "")
7436         (mult:DF (match_operand:DF 1 "register_operand" "")
7437                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7438   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7439   "")
7440
7441 (define_expand "mulsf3"
7442   [(set (match_operand:SF 0 "register_operand" "")
7443         (mult:SF (match_operand:SF 1 "register_operand" "")
7444                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7445   "TARGET_80387 || TARGET_SSE_MATH"
7446   "")
7447 \f
7448 ;; Divide instructions
7449
7450 (define_insn "divqi3"
7451   [(set (match_operand:QI 0 "register_operand" "=a")
7452         (div:QI (match_operand:HI 1 "register_operand" "0")
7453                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7454    (clobber (reg:CC FLAGS_REG))]
7455   "TARGET_QIMODE_MATH"
7456   "idiv{b}\t%2"
7457   [(set_attr "type" "idiv")
7458    (set_attr "mode" "QI")])
7459
7460 (define_insn "udivqi3"
7461   [(set (match_operand:QI 0 "register_operand" "=a")
7462         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7463                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7464    (clobber (reg:CC FLAGS_REG))]
7465   "TARGET_QIMODE_MATH"
7466   "div{b}\t%2"
7467   [(set_attr "type" "idiv")
7468    (set_attr "mode" "QI")])
7469
7470 ;; The patterns that match these are at the end of this file.
7471
7472 (define_expand "divxf3"
7473   [(set (match_operand:XF 0 "register_operand" "")
7474         (div:XF (match_operand:XF 1 "register_operand" "")
7475                 (match_operand:XF 2 "register_operand" "")))]
7476   "TARGET_80387"
7477   "")
7478
7479 (define_expand "divdf3"
7480   [(set (match_operand:DF 0 "register_operand" "")
7481         (div:DF (match_operand:DF 1 "register_operand" "")
7482                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7483    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7484    "")
7485  
7486 (define_expand "divsf3"
7487   [(set (match_operand:SF 0 "register_operand" "")
7488         (div:SF (match_operand:SF 1 "register_operand" "")
7489                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7490   "TARGET_80387 || TARGET_SSE_MATH"
7491   "")
7492 \f
7493 ;; Remainder instructions.
7494
7495 (define_expand "divmoddi4"
7496   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7497                    (div:DI (match_operand:DI 1 "register_operand" "")
7498                            (match_operand:DI 2 "nonimmediate_operand" "")))
7499               (set (match_operand:DI 3 "register_operand" "")
7500                    (mod:DI (match_dup 1) (match_dup 2)))
7501               (clobber (reg:CC FLAGS_REG))])]
7502   "TARGET_64BIT"
7503   "")
7504
7505 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7506 ;; Penalize eax case slightly because it results in worse scheduling
7507 ;; of code.
7508 (define_insn "*divmoddi4_nocltd_rex64"
7509   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7510         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7511                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7512    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7513         (mod:DI (match_dup 2) (match_dup 3)))
7514    (clobber (reg:CC FLAGS_REG))]
7515   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7516   "#"
7517   [(set_attr "type" "multi")])
7518
7519 (define_insn "*divmoddi4_cltd_rex64"
7520   [(set (match_operand:DI 0 "register_operand" "=a")
7521         (div:DI (match_operand:DI 2 "register_operand" "a")
7522                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7523    (set (match_operand:DI 1 "register_operand" "=&d")
7524         (mod:DI (match_dup 2) (match_dup 3)))
7525    (clobber (reg:CC FLAGS_REG))]
7526   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7527   "#"
7528   [(set_attr "type" "multi")])
7529
7530 (define_insn "*divmoddi_noext_rex64"
7531   [(set (match_operand:DI 0 "register_operand" "=a")
7532         (div:DI (match_operand:DI 1 "register_operand" "0")
7533                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7534    (set (match_operand:DI 3 "register_operand" "=d")
7535         (mod:DI (match_dup 1) (match_dup 2)))
7536    (use (match_operand:DI 4 "register_operand" "3"))
7537    (clobber (reg:CC FLAGS_REG))]
7538   "TARGET_64BIT"
7539   "idiv{q}\t%2"
7540   [(set_attr "type" "idiv")
7541    (set_attr "mode" "DI")])
7542
7543 (define_split
7544   [(set (match_operand:DI 0 "register_operand" "")
7545         (div:DI (match_operand:DI 1 "register_operand" "")
7546                 (match_operand:DI 2 "nonimmediate_operand" "")))
7547    (set (match_operand:DI 3 "register_operand" "")
7548         (mod:DI (match_dup 1) (match_dup 2)))
7549    (clobber (reg:CC FLAGS_REG))]
7550   "TARGET_64BIT && reload_completed"
7551   [(parallel [(set (match_dup 3)
7552                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7553               (clobber (reg:CC FLAGS_REG))])
7554    (parallel [(set (match_dup 0)
7555                    (div:DI (reg:DI 0) (match_dup 2)))
7556               (set (match_dup 3)
7557                    (mod:DI (reg:DI 0) (match_dup 2)))
7558               (use (match_dup 3))
7559               (clobber (reg:CC FLAGS_REG))])]
7560 {
7561   /* Avoid use of cltd in favor of a mov+shift.  */
7562   if (!TARGET_USE_CLTD && !optimize_size)
7563     {
7564       if (true_regnum (operands[1]))
7565         emit_move_insn (operands[0], operands[1]);
7566       else
7567         emit_move_insn (operands[3], operands[1]);
7568       operands[4] = operands[3];
7569     }
7570   else
7571     {
7572       if (true_regnum (operands[1]))
7573         abort();
7574       operands[4] = operands[1];
7575     }
7576 })
7577
7578
7579 (define_expand "divmodsi4"
7580   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7581                    (div:SI (match_operand:SI 1 "register_operand" "")
7582                            (match_operand:SI 2 "nonimmediate_operand" "")))
7583               (set (match_operand:SI 3 "register_operand" "")
7584                    (mod:SI (match_dup 1) (match_dup 2)))
7585               (clobber (reg:CC FLAGS_REG))])]
7586   ""
7587   "")
7588
7589 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7590 ;; Penalize eax case slightly because it results in worse scheduling
7591 ;; of code.
7592 (define_insn "*divmodsi4_nocltd"
7593   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7594         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7595                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7596    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7597         (mod:SI (match_dup 2) (match_dup 3)))
7598    (clobber (reg:CC FLAGS_REG))]
7599   "!optimize_size && !TARGET_USE_CLTD"
7600   "#"
7601   [(set_attr "type" "multi")])
7602
7603 (define_insn "*divmodsi4_cltd"
7604   [(set (match_operand:SI 0 "register_operand" "=a")
7605         (div:SI (match_operand:SI 2 "register_operand" "a")
7606                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7607    (set (match_operand:SI 1 "register_operand" "=&d")
7608         (mod:SI (match_dup 2) (match_dup 3)))
7609    (clobber (reg:CC FLAGS_REG))]
7610   "optimize_size || TARGET_USE_CLTD"
7611   "#"
7612   [(set_attr "type" "multi")])
7613
7614 (define_insn "*divmodsi_noext"
7615   [(set (match_operand:SI 0 "register_operand" "=a")
7616         (div:SI (match_operand:SI 1 "register_operand" "0")
7617                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7618    (set (match_operand:SI 3 "register_operand" "=d")
7619         (mod:SI (match_dup 1) (match_dup 2)))
7620    (use (match_operand:SI 4 "register_operand" "3"))
7621    (clobber (reg:CC FLAGS_REG))]
7622   ""
7623   "idiv{l}\t%2"
7624   [(set_attr "type" "idiv")
7625    (set_attr "mode" "SI")])
7626
7627 (define_split
7628   [(set (match_operand:SI 0 "register_operand" "")
7629         (div:SI (match_operand:SI 1 "register_operand" "")
7630                 (match_operand:SI 2 "nonimmediate_operand" "")))
7631    (set (match_operand:SI 3 "register_operand" "")
7632         (mod:SI (match_dup 1) (match_dup 2)))
7633    (clobber (reg:CC FLAGS_REG))]
7634   "reload_completed"
7635   [(parallel [(set (match_dup 3)
7636                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7637               (clobber (reg:CC FLAGS_REG))])
7638    (parallel [(set (match_dup 0)
7639                    (div:SI (reg:SI 0) (match_dup 2)))
7640               (set (match_dup 3)
7641                    (mod:SI (reg:SI 0) (match_dup 2)))
7642               (use (match_dup 3))
7643               (clobber (reg:CC FLAGS_REG))])]
7644 {
7645   /* Avoid use of cltd in favor of a mov+shift.  */
7646   if (!TARGET_USE_CLTD && !optimize_size)
7647     {
7648       if (true_regnum (operands[1]))
7649         emit_move_insn (operands[0], operands[1]);
7650       else
7651         emit_move_insn (operands[3], operands[1]);
7652       operands[4] = operands[3];
7653     }
7654   else
7655     {
7656       if (true_regnum (operands[1]))
7657         abort();
7658       operands[4] = operands[1];
7659     }
7660 })
7661 ;; %%% Split me.
7662 (define_insn "divmodhi4"
7663   [(set (match_operand:HI 0 "register_operand" "=a")
7664         (div:HI (match_operand:HI 1 "register_operand" "0")
7665                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7666    (set (match_operand:HI 3 "register_operand" "=&d")
7667         (mod:HI (match_dup 1) (match_dup 2)))
7668    (clobber (reg:CC FLAGS_REG))]
7669   "TARGET_HIMODE_MATH"
7670   "cwtd\;idiv{w}\t%2"
7671   [(set_attr "type" "multi")
7672    (set_attr "length_immediate" "0")
7673    (set_attr "mode" "SI")])
7674
7675 (define_insn "udivmoddi4"
7676   [(set (match_operand:DI 0 "register_operand" "=a")
7677         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7678                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7679    (set (match_operand:DI 3 "register_operand" "=&d")
7680         (umod:DI (match_dup 1) (match_dup 2)))
7681    (clobber (reg:CC FLAGS_REG))]
7682   "TARGET_64BIT"
7683   "xor{q}\t%3, %3\;div{q}\t%2"
7684   [(set_attr "type" "multi")
7685    (set_attr "length_immediate" "0")
7686    (set_attr "mode" "DI")])
7687
7688 (define_insn "*udivmoddi4_noext"
7689   [(set (match_operand:DI 0 "register_operand" "=a")
7690         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7691                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7692    (set (match_operand:DI 3 "register_operand" "=d")
7693         (umod:DI (match_dup 1) (match_dup 2)))
7694    (use (match_dup 3))
7695    (clobber (reg:CC FLAGS_REG))]
7696   "TARGET_64BIT"
7697   "div{q}\t%2"
7698   [(set_attr "type" "idiv")
7699    (set_attr "mode" "DI")])
7700
7701 (define_split
7702   [(set (match_operand:DI 0 "register_operand" "")
7703         (udiv:DI (match_operand:DI 1 "register_operand" "")
7704                  (match_operand:DI 2 "nonimmediate_operand" "")))
7705    (set (match_operand:DI 3 "register_operand" "")
7706         (umod:DI (match_dup 1) (match_dup 2)))
7707    (clobber (reg:CC FLAGS_REG))]
7708   "TARGET_64BIT && reload_completed"
7709   [(set (match_dup 3) (const_int 0))
7710    (parallel [(set (match_dup 0)
7711                    (udiv:DI (match_dup 1) (match_dup 2)))
7712               (set (match_dup 3)
7713                    (umod:DI (match_dup 1) (match_dup 2)))
7714               (use (match_dup 3))
7715               (clobber (reg:CC FLAGS_REG))])]
7716   "")
7717
7718 (define_insn "udivmodsi4"
7719   [(set (match_operand:SI 0 "register_operand" "=a")
7720         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7721                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7722    (set (match_operand:SI 3 "register_operand" "=&d")
7723         (umod:SI (match_dup 1) (match_dup 2)))
7724    (clobber (reg:CC FLAGS_REG))]
7725   ""
7726   "xor{l}\t%3, %3\;div{l}\t%2"
7727   [(set_attr "type" "multi")
7728    (set_attr "length_immediate" "0")
7729    (set_attr "mode" "SI")])
7730
7731 (define_insn "*udivmodsi4_noext"
7732   [(set (match_operand:SI 0 "register_operand" "=a")
7733         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7734                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7735    (set (match_operand:SI 3 "register_operand" "=d")
7736         (umod:SI (match_dup 1) (match_dup 2)))
7737    (use (match_dup 3))
7738    (clobber (reg:CC FLAGS_REG))]
7739   ""
7740   "div{l}\t%2"
7741   [(set_attr "type" "idiv")
7742    (set_attr "mode" "SI")])
7743
7744 (define_split
7745   [(set (match_operand:SI 0 "register_operand" "")
7746         (udiv:SI (match_operand:SI 1 "register_operand" "")
7747                  (match_operand:SI 2 "nonimmediate_operand" "")))
7748    (set (match_operand:SI 3 "register_operand" "")
7749         (umod:SI (match_dup 1) (match_dup 2)))
7750    (clobber (reg:CC FLAGS_REG))]
7751   "reload_completed"
7752   [(set (match_dup 3) (const_int 0))
7753    (parallel [(set (match_dup 0)
7754                    (udiv:SI (match_dup 1) (match_dup 2)))
7755               (set (match_dup 3)
7756                    (umod:SI (match_dup 1) (match_dup 2)))
7757               (use (match_dup 3))
7758               (clobber (reg:CC FLAGS_REG))])]
7759   "")
7760
7761 (define_expand "udivmodhi4"
7762   [(set (match_dup 4) (const_int 0))
7763    (parallel [(set (match_operand:HI 0 "register_operand" "")
7764                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7765                             (match_operand:HI 2 "nonimmediate_operand" "")))
7766               (set (match_operand:HI 3 "register_operand" "")
7767                    (umod:HI (match_dup 1) (match_dup 2)))
7768               (use (match_dup 4))
7769               (clobber (reg:CC FLAGS_REG))])]
7770   "TARGET_HIMODE_MATH"
7771   "operands[4] = gen_reg_rtx (HImode);")
7772
7773 (define_insn "*udivmodhi_noext"
7774   [(set (match_operand:HI 0 "register_operand" "=a")
7775         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7776                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7777    (set (match_operand:HI 3 "register_operand" "=d")
7778         (umod:HI (match_dup 1) (match_dup 2)))
7779    (use (match_operand:HI 4 "register_operand" "3"))
7780    (clobber (reg:CC FLAGS_REG))]
7781   ""
7782   "div{w}\t%2"
7783   [(set_attr "type" "idiv")
7784    (set_attr "mode" "HI")])
7785
7786 ;; We can not use div/idiv for double division, because it causes
7787 ;; "division by zero" on the overflow and that's not what we expect
7788 ;; from truncate.  Because true (non truncating) double division is
7789 ;; never generated, we can't create this insn anyway.
7790 ;
7791 ;(define_insn ""
7792 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7793 ;       (truncate:SI
7794 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7795 ;                  (zero_extend:DI
7796 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7797 ;   (set (match_operand:SI 3 "register_operand" "=d")
7798 ;       (truncate:SI
7799 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7800 ;   (clobber (reg:CC FLAGS_REG))]
7801 ;  ""
7802 ;  "div{l}\t{%2, %0|%0, %2}"
7803 ;  [(set_attr "type" "idiv")])
7804 \f
7805 ;;- Logical AND instructions
7806
7807 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7808 ;; Note that this excludes ah.
7809
7810 (define_insn "*testdi_1_rex64"
7811   [(set (reg 17)
7812         (compare
7813           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7814                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7815           (const_int 0)))]
7816   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7817    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7818   "@
7819    test{l}\t{%k1, %k0|%k0, %k1}
7820    test{l}\t{%k1, %k0|%k0, %k1}
7821    test{q}\t{%1, %0|%0, %1}
7822    test{q}\t{%1, %0|%0, %1}
7823    test{q}\t{%1, %0|%0, %1}"
7824   [(set_attr "type" "test")
7825    (set_attr "modrm" "0,1,0,1,1")
7826    (set_attr "mode" "SI,SI,DI,DI,DI")
7827    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7828
7829 (define_insn "testsi_1"
7830   [(set (reg 17)
7831         (compare
7832           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7833                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7834           (const_int 0)))]
7835   "ix86_match_ccmode (insn, CCNOmode)
7836    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7837   "test{l}\t{%1, %0|%0, %1}"
7838   [(set_attr "type" "test")
7839    (set_attr "modrm" "0,1,1")
7840    (set_attr "mode" "SI")
7841    (set_attr "pent_pair" "uv,np,uv")])
7842
7843 (define_expand "testsi_ccno_1"
7844   [(set (reg:CCNO FLAGS_REG)
7845         (compare:CCNO
7846           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7847                   (match_operand:SI 1 "nonmemory_operand" ""))
7848           (const_int 0)))]
7849   ""
7850   "")
7851
7852 (define_insn "*testhi_1"
7853   [(set (reg 17)
7854         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7855                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7856                  (const_int 0)))]
7857   "ix86_match_ccmode (insn, CCNOmode)
7858    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7859   "test{w}\t{%1, %0|%0, %1}"
7860   [(set_attr "type" "test")
7861    (set_attr "modrm" "0,1,1")
7862    (set_attr "mode" "HI")
7863    (set_attr "pent_pair" "uv,np,uv")])
7864
7865 (define_expand "testqi_ccz_1"
7866   [(set (reg:CCZ FLAGS_REG)
7867         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7868                              (match_operand:QI 1 "nonmemory_operand" ""))
7869                  (const_int 0)))]
7870   ""
7871   "")
7872
7873 (define_insn "*testqi_1"
7874   [(set (reg 17)
7875         (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7876                          (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7877                  (const_int 0)))]
7878   "ix86_match_ccmode (insn, CCNOmode)
7879    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7880 {
7881   if (which_alternative == 3)
7882     {
7883       if (GET_CODE (operands[1]) == CONST_INT
7884           && (INTVAL (operands[1]) & 0xffffff00))
7885         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7886       return "test{l}\t{%1, %k0|%k0, %1}";
7887     }
7888   return "test{b}\t{%1, %0|%0, %1}";
7889 }
7890   [(set_attr "type" "test")
7891    (set_attr "modrm" "0,1,1,1")
7892    (set_attr "mode" "QI,QI,QI,SI")
7893    (set_attr "pent_pair" "uv,np,uv,np")])
7894
7895 (define_expand "testqi_ext_ccno_0"
7896   [(set (reg:CCNO FLAGS_REG)
7897         (compare:CCNO
7898           (and:SI
7899             (zero_extract:SI
7900               (match_operand 0 "ext_register_operand" "")
7901               (const_int 8)
7902               (const_int 8))
7903             (match_operand 1 "const_int_operand" ""))
7904           (const_int 0)))]
7905   ""
7906   "")
7907
7908 (define_insn "*testqi_ext_0"
7909   [(set (reg 17)
7910         (compare
7911           (and:SI
7912             (zero_extract:SI
7913               (match_operand 0 "ext_register_operand" "Q")
7914               (const_int 8)
7915               (const_int 8))
7916             (match_operand 1 "const_int_operand" "n"))
7917           (const_int 0)))]
7918   "ix86_match_ccmode (insn, CCNOmode)"
7919   "test{b}\t{%1, %h0|%h0, %1}"
7920   [(set_attr "type" "test")
7921    (set_attr "mode" "QI")
7922    (set_attr "length_immediate" "1")
7923    (set_attr "pent_pair" "np")])
7924
7925 (define_insn "*testqi_ext_1"
7926   [(set (reg 17)
7927         (compare
7928           (and:SI
7929             (zero_extract:SI
7930               (match_operand 0 "ext_register_operand" "Q")
7931               (const_int 8)
7932               (const_int 8))
7933             (zero_extend:SI
7934               (match_operand:QI 1 "general_operand" "Qm")))
7935           (const_int 0)))]
7936   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7937    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7938   "test{b}\t{%1, %h0|%h0, %1}"
7939   [(set_attr "type" "test")
7940    (set_attr "mode" "QI")])
7941
7942 (define_insn "*testqi_ext_1_rex64"
7943   [(set (reg 17)
7944         (compare
7945           (and:SI
7946             (zero_extract:SI
7947               (match_operand 0 "ext_register_operand" "Q")
7948               (const_int 8)
7949               (const_int 8))
7950             (zero_extend:SI
7951               (match_operand:QI 1 "register_operand" "Q")))
7952           (const_int 0)))]
7953   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7954   "test{b}\t{%1, %h0|%h0, %1}"
7955   [(set_attr "type" "test")
7956    (set_attr "mode" "QI")])
7957
7958 (define_insn "*testqi_ext_2"
7959   [(set (reg 17)
7960         (compare
7961           (and:SI
7962             (zero_extract:SI
7963               (match_operand 0 "ext_register_operand" "Q")
7964               (const_int 8)
7965               (const_int 8))
7966             (zero_extract:SI
7967               (match_operand 1 "ext_register_operand" "Q")
7968               (const_int 8)
7969               (const_int 8)))
7970           (const_int 0)))]
7971   "ix86_match_ccmode (insn, CCNOmode)"
7972   "test{b}\t{%h1, %h0|%h0, %h1}"
7973   [(set_attr "type" "test")
7974    (set_attr "mode" "QI")])
7975
7976 ;; Combine likes to form bit extractions for some tests.  Humor it.
7977 (define_insn "*testqi_ext_3"
7978   [(set (reg 17)
7979         (compare (zero_extract:SI
7980                    (match_operand 0 "nonimmediate_operand" "rm")
7981                    (match_operand:SI 1 "const_int_operand" "")
7982                    (match_operand:SI 2 "const_int_operand" ""))
7983                  (const_int 0)))]
7984   "ix86_match_ccmode (insn, CCNOmode)
7985    && (GET_MODE (operands[0]) == SImode
7986        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7987        || GET_MODE (operands[0]) == HImode
7988        || GET_MODE (operands[0]) == QImode)"
7989   "#")
7990
7991 (define_insn "*testqi_ext_3_rex64"
7992   [(set (reg 17)
7993         (compare (zero_extract:DI
7994                    (match_operand 0 "nonimmediate_operand" "rm")
7995                    (match_operand:DI 1 "const_int_operand" "")
7996                    (match_operand:DI 2 "const_int_operand" ""))
7997                  (const_int 0)))]
7998   "TARGET_64BIT
7999    && ix86_match_ccmode (insn, CCNOmode)
8000    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
8001    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8002    /* Ensure that resulting mask is zero or sign extended operand.  */
8003    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8004        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8005            && INTVAL (operands[1]) > 32))
8006    && (GET_MODE (operands[0]) == SImode
8007        || GET_MODE (operands[0]) == DImode
8008        || GET_MODE (operands[0]) == HImode
8009        || GET_MODE (operands[0]) == QImode)"
8010   "#")
8011
8012 (define_split
8013   [(set (reg 17)
8014         (compare (zero_extract
8015                    (match_operand 0 "nonimmediate_operand" "")
8016                    (match_operand 1 "const_int_operand" "")
8017                    (match_operand 2 "const_int_operand" ""))
8018                  (const_int 0)))]
8019   "ix86_match_ccmode (insn, CCNOmode)"
8020   [(set (reg:CCNO FLAGS_REG) (compare:CCNO (match_dup 3) (const_int 0)))]
8021 {
8022   HOST_WIDE_INT len = INTVAL (operands[1]);
8023   HOST_WIDE_INT pos = INTVAL (operands[2]);
8024   HOST_WIDE_INT mask;
8025   enum machine_mode mode, submode;
8026
8027   mode = GET_MODE (operands[0]);
8028   if (GET_CODE (operands[0]) == MEM)
8029     {
8030       /* ??? Combine likes to put non-volatile mem extractions in QImode
8031          no matter the size of the test.  So find a mode that works.  */
8032       if (! MEM_VOLATILE_P (operands[0]))
8033         {
8034           mode = smallest_mode_for_size (pos + len, MODE_INT);
8035           operands[0] = adjust_address (operands[0], mode, 0);
8036         }
8037     }
8038   else if (GET_CODE (operands[0]) == SUBREG
8039            && (submode = GET_MODE (SUBREG_REG (operands[0])),
8040                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8041            && pos + len <= GET_MODE_BITSIZE (submode))
8042     {
8043       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8044       mode = submode;
8045       operands[0] = SUBREG_REG (operands[0]);
8046     }
8047   else if (mode == HImode && pos + len <= 8)
8048     {
8049       /* Small HImode tests can be converted to QImode.  */
8050       mode = QImode;
8051       operands[0] = gen_lowpart (QImode, operands[0]);
8052     }
8053
8054   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8055   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8056
8057   operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8058 })
8059
8060 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8061 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8062 ;; this is relatively important trick.
8063 ;; Do the conversion only post-reload to avoid limiting of the register class
8064 ;; to QI regs.
8065 (define_split
8066   [(set (reg 17)
8067         (compare
8068           (and (match_operand 0 "register_operand" "")
8069                (match_operand 1 "const_int_operand" ""))
8070           (const_int 0)))]
8071    "reload_completed
8072     && QI_REG_P (operands[0])
8073     && ((ix86_match_ccmode (insn, CCZmode)
8074          && !(INTVAL (operands[1]) & ~(255 << 8)))
8075         || (ix86_match_ccmode (insn, CCNOmode)
8076             && !(INTVAL (operands[1]) & ~(127 << 8))))
8077     && GET_MODE (operands[0]) != QImode"
8078   [(set (reg:CCNO FLAGS_REG)
8079         (compare:CCNO
8080           (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8081                   (match_dup 1))
8082           (const_int 0)))]
8083   "operands[0] = gen_lowpart (SImode, operands[0]);
8084    operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8085
8086 (define_split
8087   [(set (reg 17)
8088         (compare
8089           (and (match_operand 0 "nonimmediate_operand" "")
8090                (match_operand 1 "const_int_operand" ""))
8091           (const_int 0)))]
8092    "reload_completed
8093     && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8094     && ((ix86_match_ccmode (insn, CCZmode)
8095          && !(INTVAL (operands[1]) & ~255))
8096         || (ix86_match_ccmode (insn, CCNOmode)
8097             && !(INTVAL (operands[1]) & ~127)))
8098     && GET_MODE (operands[0]) != QImode"
8099   [(set (reg:CCNO FLAGS_REG)
8100         (compare:CCNO
8101           (and:QI (match_dup 0)
8102                   (match_dup 1))
8103           (const_int 0)))]
8104   "operands[0] = gen_lowpart (QImode, operands[0]);
8105    operands[1] = gen_lowpart (QImode, operands[1]);")
8106
8107
8108 ;; %%% This used to optimize known byte-wide and operations to memory,
8109 ;; and sometimes to QImode registers.  If this is considered useful,
8110 ;; it should be done with splitters.
8111
8112 (define_expand "anddi3"
8113   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8114         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8115                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8116    (clobber (reg:CC FLAGS_REG))]
8117   "TARGET_64BIT"
8118   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8119
8120 (define_insn "*anddi_1_rex64"
8121   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8122         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8123                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8124    (clobber (reg:CC FLAGS_REG))]
8125   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8126 {
8127   switch (get_attr_type (insn))
8128     {
8129     case TYPE_IMOVX:
8130       {
8131         enum machine_mode mode;
8132
8133         if (GET_CODE (operands[2]) != CONST_INT)
8134           abort ();
8135         if (INTVAL (operands[2]) == 0xff)
8136           mode = QImode;
8137         else if (INTVAL (operands[2]) == 0xffff)
8138           mode = HImode;
8139         else
8140           abort ();
8141         
8142         operands[1] = gen_lowpart (mode, operands[1]);
8143         if (mode == QImode)
8144           return "movz{bq|x}\t{%1,%0|%0, %1}";
8145         else
8146           return "movz{wq|x}\t{%1,%0|%0, %1}";
8147       }
8148
8149     default:
8150       if (! rtx_equal_p (operands[0], operands[1]))
8151         abort ();
8152       if (get_attr_mode (insn) == MODE_SI)
8153         return "and{l}\t{%k2, %k0|%k0, %k2}";
8154       else
8155         return "and{q}\t{%2, %0|%0, %2}";
8156     }
8157 }
8158   [(set_attr "type" "alu,alu,alu,imovx")
8159    (set_attr "length_immediate" "*,*,*,0")
8160    (set_attr "mode" "SI,DI,DI,DI")])
8161
8162 (define_insn "*anddi_2"
8163   [(set (reg 17)
8164         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8165                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8166                  (const_int 0)))
8167    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8168         (and:DI (match_dup 1) (match_dup 2)))]
8169   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8170    && ix86_binary_operator_ok (AND, DImode, operands)"
8171   "@
8172    and{l}\t{%k2, %k0|%k0, %k2}
8173    and{q}\t{%2, %0|%0, %2}
8174    and{q}\t{%2, %0|%0, %2}"
8175   [(set_attr "type" "alu")
8176    (set_attr "mode" "SI,DI,DI")])
8177
8178 (define_expand "andsi3"
8179   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8180         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8181                 (match_operand:SI 2 "general_operand" "")))
8182    (clobber (reg:CC FLAGS_REG))]
8183   ""
8184   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8185
8186 (define_insn "*andsi_1"
8187   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8188         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8189                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8190    (clobber (reg:CC FLAGS_REG))]
8191   "ix86_binary_operator_ok (AND, SImode, operands)"
8192 {
8193   switch (get_attr_type (insn))
8194     {
8195     case TYPE_IMOVX:
8196       {
8197         enum machine_mode mode;
8198
8199         if (GET_CODE (operands[2]) != CONST_INT)
8200           abort ();
8201         if (INTVAL (operands[2]) == 0xff)
8202           mode = QImode;
8203         else if (INTVAL (operands[2]) == 0xffff)
8204           mode = HImode;
8205         else
8206           abort ();
8207         
8208         operands[1] = gen_lowpart (mode, operands[1]);
8209         if (mode == QImode)
8210           return "movz{bl|x}\t{%1,%0|%0, %1}";
8211         else
8212           return "movz{wl|x}\t{%1,%0|%0, %1}";
8213       }
8214
8215     default:
8216       if (! rtx_equal_p (operands[0], operands[1]))
8217         abort ();
8218       return "and{l}\t{%2, %0|%0, %2}";
8219     }
8220 }
8221   [(set_attr "type" "alu,alu,imovx")
8222    (set_attr "length_immediate" "*,*,0")
8223    (set_attr "mode" "SI")])
8224
8225 (define_split
8226   [(set (match_operand 0 "register_operand" "")
8227         (and (match_dup 0)
8228              (const_int -65536)))
8229    (clobber (reg:CC FLAGS_REG))]
8230   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8231   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8232   "operands[1] = gen_lowpart (HImode, operands[0]);")
8233
8234 (define_split
8235   [(set (match_operand 0 "ext_register_operand" "")
8236         (and (match_dup 0)
8237              (const_int -256)))
8238    (clobber (reg:CC FLAGS_REG))]
8239   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8240   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8241   "operands[1] = gen_lowpart (QImode, operands[0]);")
8242
8243 (define_split
8244   [(set (match_operand 0 "ext_register_operand" "")
8245         (and (match_dup 0)
8246              (const_int -65281)))
8247    (clobber (reg:CC FLAGS_REG))]
8248   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8249   [(parallel [(set (zero_extract:SI (match_dup 0)
8250                                     (const_int 8)
8251                                     (const_int 8))
8252                    (xor:SI 
8253                      (zero_extract:SI (match_dup 0)
8254                                       (const_int 8)
8255                                       (const_int 8))
8256                      (zero_extract:SI (match_dup 0)
8257                                       (const_int 8)
8258                                       (const_int 8))))
8259               (clobber (reg:CC FLAGS_REG))])]
8260   "operands[0] = gen_lowpart (SImode, operands[0]);")
8261
8262 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8263 (define_insn "*andsi_1_zext"
8264   [(set (match_operand:DI 0 "register_operand" "=r")
8265         (zero_extend:DI
8266           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8267                   (match_operand:SI 2 "general_operand" "rim"))))
8268    (clobber (reg:CC FLAGS_REG))]
8269   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8270   "and{l}\t{%2, %k0|%k0, %2}"
8271   [(set_attr "type" "alu")
8272    (set_attr "mode" "SI")])
8273
8274 (define_insn "*andsi_2"
8275   [(set (reg 17)
8276         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8277                          (match_operand:SI 2 "general_operand" "rim,ri"))
8278                  (const_int 0)))
8279    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8280         (and:SI (match_dup 1) (match_dup 2)))]
8281   "ix86_match_ccmode (insn, CCNOmode)
8282    && ix86_binary_operator_ok (AND, SImode, operands)"
8283   "and{l}\t{%2, %0|%0, %2}"
8284   [(set_attr "type" "alu")
8285    (set_attr "mode" "SI")])
8286
8287 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8288 (define_insn "*andsi_2_zext"
8289   [(set (reg 17)
8290         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8291                          (match_operand:SI 2 "general_operand" "rim"))
8292                  (const_int 0)))
8293    (set (match_operand:DI 0 "register_operand" "=r")
8294         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8295   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8296    && ix86_binary_operator_ok (AND, SImode, operands)"
8297   "and{l}\t{%2, %k0|%k0, %2}"
8298   [(set_attr "type" "alu")
8299    (set_attr "mode" "SI")])
8300
8301 (define_expand "andhi3"
8302   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8303         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8304                 (match_operand:HI 2 "general_operand" "")))
8305    (clobber (reg:CC FLAGS_REG))]
8306   "TARGET_HIMODE_MATH"
8307   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8308
8309 (define_insn "*andhi_1"
8310   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8311         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8312                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8313    (clobber (reg:CC FLAGS_REG))]
8314   "ix86_binary_operator_ok (AND, HImode, operands)"
8315 {
8316   switch (get_attr_type (insn))
8317     {
8318     case TYPE_IMOVX:
8319       if (GET_CODE (operands[2]) != CONST_INT)
8320         abort ();
8321       if (INTVAL (operands[2]) == 0xff)
8322         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8323       abort ();
8324
8325     default:
8326       if (! rtx_equal_p (operands[0], operands[1]))
8327         abort ();
8328
8329       return "and{w}\t{%2, %0|%0, %2}";
8330     }
8331 }
8332   [(set_attr "type" "alu,alu,imovx")
8333    (set_attr "length_immediate" "*,*,0")
8334    (set_attr "mode" "HI,HI,SI")])
8335
8336 (define_insn "*andhi_2"
8337   [(set (reg 17)
8338         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8339                          (match_operand:HI 2 "general_operand" "rim,ri"))
8340                  (const_int 0)))
8341    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8342         (and:HI (match_dup 1) (match_dup 2)))]
8343   "ix86_match_ccmode (insn, CCNOmode)
8344    && ix86_binary_operator_ok (AND, HImode, operands)"
8345   "and{w}\t{%2, %0|%0, %2}"
8346   [(set_attr "type" "alu")
8347    (set_attr "mode" "HI")])
8348
8349 (define_expand "andqi3"
8350   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8351         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8352                 (match_operand:QI 2 "general_operand" "")))
8353    (clobber (reg:CC FLAGS_REG))]
8354   "TARGET_QIMODE_MATH"
8355   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8356
8357 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8358 (define_insn "*andqi_1"
8359   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8360         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8361                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8362    (clobber (reg:CC FLAGS_REG))]
8363   "ix86_binary_operator_ok (AND, QImode, operands)"
8364   "@
8365    and{b}\t{%2, %0|%0, %2}
8366    and{b}\t{%2, %0|%0, %2}
8367    and{l}\t{%k2, %k0|%k0, %k2}"
8368   [(set_attr "type" "alu")
8369    (set_attr "mode" "QI,QI,SI")])
8370
8371 (define_insn "*andqi_1_slp"
8372   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8373         (and:QI (match_dup 0)
8374                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8375    (clobber (reg:CC FLAGS_REG))]
8376   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8377    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8378   "and{b}\t{%1, %0|%0, %1}"
8379   [(set_attr "type" "alu1")
8380    (set_attr "mode" "QI")])
8381
8382 (define_insn "*andqi_2"
8383   [(set (reg 17)
8384         (compare (and:QI
8385                    (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8386                    (match_operand:QI 2 "general_operand" "qim,qi,i"))
8387                  (const_int 0)))
8388    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8389         (and:QI (match_dup 1) (match_dup 2)))]
8390   "ix86_match_ccmode (insn, CCNOmode)
8391    && ix86_binary_operator_ok (AND, QImode, operands)"
8392 {
8393   if (which_alternative == 2)
8394     {
8395       if (GET_CODE (operands[2]) == CONST_INT
8396           && (INTVAL (operands[2]) & 0xffffff00))
8397         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8398       return "and{l}\t{%2, %k0|%k0, %2}";
8399     }
8400   return "and{b}\t{%2, %0|%0, %2}";
8401 }
8402   [(set_attr "type" "alu")
8403    (set_attr "mode" "QI,QI,SI")])
8404
8405 (define_insn "*andqi_2_slp"
8406   [(set (reg 17)
8407         (compare (and:QI
8408                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8409                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8410                  (const_int 0)))
8411    (set (strict_low_part (match_dup 0))
8412         (and:QI (match_dup 0) (match_dup 1)))]
8413   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8414    && ix86_match_ccmode (insn, CCNOmode)
8415    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8416   "and{b}\t{%1, %0|%0, %1}"
8417   [(set_attr "type" "alu1")
8418    (set_attr "mode" "QI")])
8419
8420 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8421 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8422 ;; for a QImode operand, which of course failed.
8423
8424 (define_insn "andqi_ext_0"
8425   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8426                          (const_int 8)
8427                          (const_int 8))
8428         (and:SI 
8429           (zero_extract:SI
8430             (match_operand 1 "ext_register_operand" "0")
8431             (const_int 8)
8432             (const_int 8))
8433           (match_operand 2 "const_int_operand" "n")))
8434    (clobber (reg:CC FLAGS_REG))]
8435   ""
8436   "and{b}\t{%2, %h0|%h0, %2}"
8437   [(set_attr "type" "alu")
8438    (set_attr "length_immediate" "1")
8439    (set_attr "mode" "QI")])
8440
8441 ;; Generated by peephole translating test to and.  This shows up
8442 ;; often in fp comparisons.
8443
8444 (define_insn "*andqi_ext_0_cc"
8445   [(set (reg 17)
8446         (compare
8447           (and:SI
8448             (zero_extract:SI
8449               (match_operand 1 "ext_register_operand" "0")
8450               (const_int 8)
8451               (const_int 8))
8452             (match_operand 2 "const_int_operand" "n"))
8453           (const_int 0)))
8454    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8455                          (const_int 8)
8456                          (const_int 8))
8457         (and:SI 
8458           (zero_extract:SI
8459             (match_dup 1)
8460             (const_int 8)
8461             (const_int 8))
8462           (match_dup 2)))]
8463   "ix86_match_ccmode (insn, CCNOmode)"
8464   "and{b}\t{%2, %h0|%h0, %2}"
8465   [(set_attr "type" "alu")
8466    (set_attr "length_immediate" "1")
8467    (set_attr "mode" "QI")])
8468
8469 (define_insn "*andqi_ext_1"
8470   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8471                          (const_int 8)
8472                          (const_int 8))
8473         (and:SI 
8474           (zero_extract:SI
8475             (match_operand 1 "ext_register_operand" "0")
8476             (const_int 8)
8477             (const_int 8))
8478           (zero_extend:SI
8479             (match_operand:QI 2 "general_operand" "Qm"))))
8480    (clobber (reg:CC FLAGS_REG))]
8481   "!TARGET_64BIT"
8482   "and{b}\t{%2, %h0|%h0, %2}"
8483   [(set_attr "type" "alu")
8484    (set_attr "length_immediate" "0")
8485    (set_attr "mode" "QI")])
8486
8487 (define_insn "*andqi_ext_1_rex64"
8488   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8489                          (const_int 8)
8490                          (const_int 8))
8491         (and:SI 
8492           (zero_extract:SI
8493             (match_operand 1 "ext_register_operand" "0")
8494             (const_int 8)
8495             (const_int 8))
8496           (zero_extend:SI
8497             (match_operand 2 "ext_register_operand" "Q"))))
8498    (clobber (reg:CC FLAGS_REG))]
8499   "TARGET_64BIT"
8500   "and{b}\t{%2, %h0|%h0, %2}"
8501   [(set_attr "type" "alu")
8502    (set_attr "length_immediate" "0")
8503    (set_attr "mode" "QI")])
8504
8505 (define_insn "*andqi_ext_2"
8506   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8507                          (const_int 8)
8508                          (const_int 8))
8509         (and:SI
8510           (zero_extract:SI
8511             (match_operand 1 "ext_register_operand" "%0")
8512             (const_int 8)
8513             (const_int 8))
8514           (zero_extract:SI
8515             (match_operand 2 "ext_register_operand" "Q")
8516             (const_int 8)
8517             (const_int 8))))
8518    (clobber (reg:CC FLAGS_REG))]
8519   ""
8520   "and{b}\t{%h2, %h0|%h0, %h2}"
8521   [(set_attr "type" "alu")
8522    (set_attr "length_immediate" "0")
8523    (set_attr "mode" "QI")])
8524
8525 ;; Convert wide AND instructions with immediate operand to shorter QImode
8526 ;; equivalents when possible.
8527 ;; Don't do the splitting with memory operands, since it introduces risk
8528 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8529 ;; for size, but that can (should?) be handled by generic code instead.
8530 (define_split
8531   [(set (match_operand 0 "register_operand" "")
8532         (and (match_operand 1 "register_operand" "")
8533              (match_operand 2 "const_int_operand" "")))
8534    (clobber (reg:CC FLAGS_REG))]
8535    "reload_completed
8536     && QI_REG_P (operands[0])
8537     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8538     && !(~INTVAL (operands[2]) & ~(255 << 8))
8539     && GET_MODE (operands[0]) != QImode"
8540   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8541                    (and:SI (zero_extract:SI (match_dup 1)
8542                                             (const_int 8) (const_int 8))
8543                            (match_dup 2)))
8544               (clobber (reg:CC FLAGS_REG))])]
8545   "operands[0] = gen_lowpart (SImode, operands[0]);
8546    operands[1] = gen_lowpart (SImode, operands[1]);
8547    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8548
8549 ;; Since AND can be encoded with sign extended immediate, this is only
8550 ;; profitable when 7th bit is not set.
8551 (define_split
8552   [(set (match_operand 0 "register_operand" "")
8553         (and (match_operand 1 "general_operand" "")
8554              (match_operand 2 "const_int_operand" "")))
8555    (clobber (reg:CC FLAGS_REG))]
8556    "reload_completed
8557     && ANY_QI_REG_P (operands[0])
8558     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8559     && !(~INTVAL (operands[2]) & ~255)
8560     && !(INTVAL (operands[2]) & 128)
8561     && GET_MODE (operands[0]) != QImode"
8562   [(parallel [(set (strict_low_part (match_dup 0))
8563                    (and:QI (match_dup 1)
8564                            (match_dup 2)))
8565               (clobber (reg:CC FLAGS_REG))])]
8566   "operands[0] = gen_lowpart (QImode, operands[0]);
8567    operands[1] = gen_lowpart (QImode, operands[1]);
8568    operands[2] = gen_lowpart (QImode, operands[2]);")
8569 \f
8570 ;; Logical inclusive OR instructions
8571
8572 ;; %%% This used to optimize known byte-wide and operations to memory.
8573 ;; If this is considered useful, it should be done with splitters.
8574
8575 (define_expand "iordi3"
8576   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8577         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8578                 (match_operand:DI 2 "x86_64_general_operand" "")))
8579    (clobber (reg:CC FLAGS_REG))]
8580   "TARGET_64BIT"
8581   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8582
8583 (define_insn "*iordi_1_rex64"
8584   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8585         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8586                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8587    (clobber (reg:CC FLAGS_REG))]
8588   "TARGET_64BIT
8589    && ix86_binary_operator_ok (IOR, DImode, operands)"
8590   "or{q}\t{%2, %0|%0, %2}"
8591   [(set_attr "type" "alu")
8592    (set_attr "mode" "DI")])
8593
8594 (define_insn "*iordi_2_rex64"
8595   [(set (reg 17)
8596         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8597                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8598                  (const_int 0)))
8599    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8600         (ior:DI (match_dup 1) (match_dup 2)))]
8601   "TARGET_64BIT
8602    && ix86_match_ccmode (insn, CCNOmode)
8603    && ix86_binary_operator_ok (IOR, DImode, operands)"
8604   "or{q}\t{%2, %0|%0, %2}"
8605   [(set_attr "type" "alu")
8606    (set_attr "mode" "DI")])
8607
8608 (define_insn "*iordi_3_rex64"
8609   [(set (reg 17)
8610         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8611                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8612                  (const_int 0)))
8613    (clobber (match_scratch:DI 0 "=r"))]
8614   "TARGET_64BIT
8615    && ix86_match_ccmode (insn, CCNOmode)
8616    && ix86_binary_operator_ok (IOR, DImode, operands)"
8617   "or{q}\t{%2, %0|%0, %2}"
8618   [(set_attr "type" "alu")
8619    (set_attr "mode" "DI")])
8620
8621
8622 (define_expand "iorsi3"
8623   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8624         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8625                 (match_operand:SI 2 "general_operand" "")))
8626    (clobber (reg:CC FLAGS_REG))]
8627   ""
8628   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8629
8630 (define_insn "*iorsi_1"
8631   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8632         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8633                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8634    (clobber (reg:CC FLAGS_REG))]
8635   "ix86_binary_operator_ok (IOR, SImode, operands)"
8636   "or{l}\t{%2, %0|%0, %2}"
8637   [(set_attr "type" "alu")
8638    (set_attr "mode" "SI")])
8639
8640 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8641 (define_insn "*iorsi_1_zext"
8642   [(set (match_operand:DI 0 "register_operand" "=rm")
8643         (zero_extend:DI
8644           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8645                   (match_operand:SI 2 "general_operand" "rim"))))
8646    (clobber (reg:CC FLAGS_REG))]
8647   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8648   "or{l}\t{%2, %k0|%k0, %2}"
8649   [(set_attr "type" "alu")
8650    (set_attr "mode" "SI")])
8651
8652 (define_insn "*iorsi_1_zext_imm"
8653   [(set (match_operand:DI 0 "register_operand" "=rm")
8654         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8655                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8656    (clobber (reg:CC FLAGS_REG))]
8657   "TARGET_64BIT"
8658   "or{l}\t{%2, %k0|%k0, %2}"
8659   [(set_attr "type" "alu")
8660    (set_attr "mode" "SI")])
8661
8662 (define_insn "*iorsi_2"
8663   [(set (reg 17)
8664         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8665                          (match_operand:SI 2 "general_operand" "rim,ri"))
8666                  (const_int 0)))
8667    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8668         (ior:SI (match_dup 1) (match_dup 2)))]
8669   "ix86_match_ccmode (insn, CCNOmode)
8670    && ix86_binary_operator_ok (IOR, SImode, operands)"
8671   "or{l}\t{%2, %0|%0, %2}"
8672   [(set_attr "type" "alu")
8673    (set_attr "mode" "SI")])
8674
8675 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8676 ;; ??? Special case for immediate operand is missing - it is tricky.
8677 (define_insn "*iorsi_2_zext"
8678   [(set (reg 17)
8679         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8680                          (match_operand:SI 2 "general_operand" "rim"))
8681                  (const_int 0)))
8682    (set (match_operand:DI 0 "register_operand" "=r")
8683         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8684   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8685    && ix86_binary_operator_ok (IOR, SImode, operands)"
8686   "or{l}\t{%2, %k0|%k0, %2}"
8687   [(set_attr "type" "alu")
8688    (set_attr "mode" "SI")])
8689
8690 (define_insn "*iorsi_2_zext_imm"
8691   [(set (reg 17)
8692         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8693                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8694                  (const_int 0)))
8695    (set (match_operand:DI 0 "register_operand" "=r")
8696         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8697   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8698    && ix86_binary_operator_ok (IOR, SImode, operands)"
8699   "or{l}\t{%2, %k0|%k0, %2}"
8700   [(set_attr "type" "alu")
8701    (set_attr "mode" "SI")])
8702
8703 (define_insn "*iorsi_3"
8704   [(set (reg 17)
8705         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8706                          (match_operand:SI 2 "general_operand" "rim"))
8707                  (const_int 0)))
8708    (clobber (match_scratch:SI 0 "=r"))]
8709   "ix86_match_ccmode (insn, CCNOmode)
8710    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8711   "or{l}\t{%2, %0|%0, %2}"
8712   [(set_attr "type" "alu")
8713    (set_attr "mode" "SI")])
8714
8715 (define_expand "iorhi3"
8716   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8717         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8718                 (match_operand:HI 2 "general_operand" "")))
8719    (clobber (reg:CC FLAGS_REG))]
8720   "TARGET_HIMODE_MATH"
8721   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8722
8723 (define_insn "*iorhi_1"
8724   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8725         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8726                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8727    (clobber (reg:CC FLAGS_REG))]
8728   "ix86_binary_operator_ok (IOR, HImode, operands)"
8729   "or{w}\t{%2, %0|%0, %2}"
8730   [(set_attr "type" "alu")
8731    (set_attr "mode" "HI")])
8732
8733 (define_insn "*iorhi_2"
8734   [(set (reg 17)
8735         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8736                          (match_operand:HI 2 "general_operand" "rim,ri"))
8737                  (const_int 0)))
8738    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8739         (ior:HI (match_dup 1) (match_dup 2)))]
8740   "ix86_match_ccmode (insn, CCNOmode)
8741    && ix86_binary_operator_ok (IOR, HImode, operands)"
8742   "or{w}\t{%2, %0|%0, %2}"
8743   [(set_attr "type" "alu")
8744    (set_attr "mode" "HI")])
8745
8746 (define_insn "*iorhi_3"
8747   [(set (reg 17)
8748         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8749                          (match_operand:HI 2 "general_operand" "rim"))
8750                  (const_int 0)))
8751    (clobber (match_scratch:HI 0 "=r"))]
8752   "ix86_match_ccmode (insn, CCNOmode)
8753    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8754   "or{w}\t{%2, %0|%0, %2}"
8755   [(set_attr "type" "alu")
8756    (set_attr "mode" "HI")])
8757
8758 (define_expand "iorqi3"
8759   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8760         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8761                 (match_operand:QI 2 "general_operand" "")))
8762    (clobber (reg:CC FLAGS_REG))]
8763   "TARGET_QIMODE_MATH"
8764   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8765
8766 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8767 (define_insn "*iorqi_1"
8768   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8769         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8770                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8771    (clobber (reg:CC FLAGS_REG))]
8772   "ix86_binary_operator_ok (IOR, QImode, operands)"
8773   "@
8774    or{b}\t{%2, %0|%0, %2}
8775    or{b}\t{%2, %0|%0, %2}
8776    or{l}\t{%k2, %k0|%k0, %k2}"
8777   [(set_attr "type" "alu")
8778    (set_attr "mode" "QI,QI,SI")])
8779
8780 (define_insn "*iorqi_1_slp"
8781   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8782         (ior:QI (match_dup 0)
8783                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8784    (clobber (reg:CC FLAGS_REG))]
8785   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8786    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8787   "or{b}\t{%1, %0|%0, %1}"
8788   [(set_attr "type" "alu1")
8789    (set_attr "mode" "QI")])
8790
8791 (define_insn "*iorqi_2"
8792   [(set (reg 17)
8793         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8794                          (match_operand:QI 2 "general_operand" "qim,qi"))
8795                  (const_int 0)))
8796    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8797         (ior:QI (match_dup 1) (match_dup 2)))]
8798   "ix86_match_ccmode (insn, CCNOmode)
8799    && ix86_binary_operator_ok (IOR, QImode, operands)"
8800   "or{b}\t{%2, %0|%0, %2}"
8801   [(set_attr "type" "alu")
8802    (set_attr "mode" "QI")])
8803
8804 (define_insn "*iorqi_2_slp"
8805   [(set (reg 17)
8806         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8807                          (match_operand:QI 1 "general_operand" "qim,qi"))
8808                  (const_int 0)))
8809    (set (strict_low_part (match_dup 0))
8810         (ior:QI (match_dup 0) (match_dup 1)))]
8811   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8812    && ix86_match_ccmode (insn, CCNOmode)
8813    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8814   "or{b}\t{%1, %0|%0, %1}"
8815   [(set_attr "type" "alu1")
8816    (set_attr "mode" "QI")])
8817
8818 (define_insn "*iorqi_3"
8819   [(set (reg 17)
8820         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8821                          (match_operand:QI 2 "general_operand" "qim"))
8822                  (const_int 0)))
8823    (clobber (match_scratch:QI 0 "=q"))]
8824   "ix86_match_ccmode (insn, CCNOmode)
8825    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8826   "or{b}\t{%2, %0|%0, %2}"
8827   [(set_attr "type" "alu")
8828    (set_attr "mode" "QI")])
8829
8830 (define_insn "iorqi_ext_0"
8831   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8832                          (const_int 8)
8833                          (const_int 8))
8834         (ior:SI 
8835           (zero_extract:SI
8836             (match_operand 1 "ext_register_operand" "0")
8837             (const_int 8)
8838             (const_int 8))
8839           (match_operand 2 "const_int_operand" "n")))
8840    (clobber (reg:CC FLAGS_REG))]
8841   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8842   "or{b}\t{%2, %h0|%h0, %2}"
8843   [(set_attr "type" "alu")
8844    (set_attr "length_immediate" "1")
8845    (set_attr "mode" "QI")])
8846
8847 (define_insn "*iorqi_ext_1"
8848   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8849                          (const_int 8)
8850                          (const_int 8))
8851         (ior:SI 
8852           (zero_extract:SI
8853             (match_operand 1 "ext_register_operand" "0")
8854             (const_int 8)
8855             (const_int 8))
8856           (zero_extend:SI
8857             (match_operand:QI 2 "general_operand" "Qm"))))
8858    (clobber (reg:CC FLAGS_REG))]
8859   "!TARGET_64BIT
8860    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8861   "or{b}\t{%2, %h0|%h0, %2}"
8862   [(set_attr "type" "alu")
8863    (set_attr "length_immediate" "0")
8864    (set_attr "mode" "QI")])
8865
8866 (define_insn "*iorqi_ext_1_rex64"
8867   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8868                          (const_int 8)
8869                          (const_int 8))
8870         (ior:SI 
8871           (zero_extract:SI
8872             (match_operand 1 "ext_register_operand" "0")
8873             (const_int 8)
8874             (const_int 8))
8875           (zero_extend:SI
8876             (match_operand 2 "ext_register_operand" "Q"))))
8877    (clobber (reg:CC FLAGS_REG))]
8878   "TARGET_64BIT
8879    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8880   "or{b}\t{%2, %h0|%h0, %2}"
8881   [(set_attr "type" "alu")
8882    (set_attr "length_immediate" "0")
8883    (set_attr "mode" "QI")])
8884
8885 (define_insn "*iorqi_ext_2"
8886   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8887                          (const_int 8)
8888                          (const_int 8))
8889         (ior:SI 
8890           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8891                            (const_int 8)
8892                            (const_int 8))
8893           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8894                            (const_int 8)
8895                            (const_int 8))))
8896    (clobber (reg:CC FLAGS_REG))]
8897   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8898   "ior{b}\t{%h2, %h0|%h0, %h2}"
8899   [(set_attr "type" "alu")
8900    (set_attr "length_immediate" "0")
8901    (set_attr "mode" "QI")])
8902
8903 (define_split
8904   [(set (match_operand 0 "register_operand" "")
8905         (ior (match_operand 1 "register_operand" "")
8906              (match_operand 2 "const_int_operand" "")))
8907    (clobber (reg:CC FLAGS_REG))]
8908    "reload_completed
8909     && QI_REG_P (operands[0])
8910     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8911     && !(INTVAL (operands[2]) & ~(255 << 8))
8912     && GET_MODE (operands[0]) != QImode"
8913   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8914                    (ior:SI (zero_extract:SI (match_dup 1)
8915                                             (const_int 8) (const_int 8))
8916                            (match_dup 2)))
8917               (clobber (reg:CC FLAGS_REG))])]
8918   "operands[0] = gen_lowpart (SImode, operands[0]);
8919    operands[1] = gen_lowpart (SImode, operands[1]);
8920    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8921
8922 ;; Since OR can be encoded with sign extended immediate, this is only
8923 ;; profitable when 7th bit is set.
8924 (define_split
8925   [(set (match_operand 0 "register_operand" "")
8926         (ior (match_operand 1 "general_operand" "")
8927              (match_operand 2 "const_int_operand" "")))
8928    (clobber (reg:CC FLAGS_REG))]
8929    "reload_completed
8930     && ANY_QI_REG_P (operands[0])
8931     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8932     && !(INTVAL (operands[2]) & ~255)
8933     && (INTVAL (operands[2]) & 128)
8934     && GET_MODE (operands[0]) != QImode"
8935   [(parallel [(set (strict_low_part (match_dup 0))
8936                    (ior:QI (match_dup 1)
8937                            (match_dup 2)))
8938               (clobber (reg:CC FLAGS_REG))])]
8939   "operands[0] = gen_lowpart (QImode, operands[0]);
8940    operands[1] = gen_lowpart (QImode, operands[1]);
8941    operands[2] = gen_lowpart (QImode, operands[2]);")
8942 \f
8943 ;; Logical XOR instructions
8944
8945 ;; %%% This used to optimize known byte-wide and operations to memory.
8946 ;; If this is considered useful, it should be done with splitters.
8947
8948 (define_expand "xordi3"
8949   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8950         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8951                 (match_operand:DI 2 "x86_64_general_operand" "")))
8952    (clobber (reg:CC FLAGS_REG))]
8953   "TARGET_64BIT"
8954   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8955
8956 (define_insn "*xordi_1_rex64"
8957   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8958         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8959                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8960    (clobber (reg:CC FLAGS_REG))]
8961   "TARGET_64BIT
8962    && ix86_binary_operator_ok (XOR, DImode, operands)"
8963   "@
8964    xor{q}\t{%2, %0|%0, %2}
8965    xor{q}\t{%2, %0|%0, %2}"
8966   [(set_attr "type" "alu")
8967    (set_attr "mode" "DI,DI")])
8968
8969 (define_insn "*xordi_2_rex64"
8970   [(set (reg 17)
8971         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8972                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8973                  (const_int 0)))
8974    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8975         (xor:DI (match_dup 1) (match_dup 2)))]
8976   "TARGET_64BIT
8977    && ix86_match_ccmode (insn, CCNOmode)
8978    && ix86_binary_operator_ok (XOR, DImode, operands)"
8979   "@
8980    xor{q}\t{%2, %0|%0, %2}
8981    xor{q}\t{%2, %0|%0, %2}"
8982   [(set_attr "type" "alu")
8983    (set_attr "mode" "DI,DI")])
8984
8985 (define_insn "*xordi_3_rex64"
8986   [(set (reg 17)
8987         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8988                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8989                  (const_int 0)))
8990    (clobber (match_scratch:DI 0 "=r"))]
8991   "TARGET_64BIT
8992    && ix86_match_ccmode (insn, CCNOmode)
8993    && ix86_binary_operator_ok (XOR, DImode, operands)"
8994   "xor{q}\t{%2, %0|%0, %2}"
8995   [(set_attr "type" "alu")
8996    (set_attr "mode" "DI")])
8997
8998 (define_expand "xorsi3"
8999   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9000         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9001                 (match_operand:SI 2 "general_operand" "")))
9002    (clobber (reg:CC FLAGS_REG))]
9003   ""
9004   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9005
9006 (define_insn "*xorsi_1"
9007   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9008         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9009                 (match_operand:SI 2 "general_operand" "ri,rm")))
9010    (clobber (reg:CC FLAGS_REG))]
9011   "ix86_binary_operator_ok (XOR, SImode, operands)"
9012   "xor{l}\t{%2, %0|%0, %2}"
9013   [(set_attr "type" "alu")
9014    (set_attr "mode" "SI")])
9015
9016 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9017 ;; Add speccase for immediates
9018 (define_insn "*xorsi_1_zext"
9019   [(set (match_operand:DI 0 "register_operand" "=r")
9020         (zero_extend:DI
9021           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9022                   (match_operand:SI 2 "general_operand" "rim"))))
9023    (clobber (reg:CC FLAGS_REG))]
9024   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9025   "xor{l}\t{%2, %k0|%k0, %2}"
9026   [(set_attr "type" "alu")
9027    (set_attr "mode" "SI")])
9028
9029 (define_insn "*xorsi_1_zext_imm"
9030   [(set (match_operand:DI 0 "register_operand" "=r")
9031         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9032                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9033    (clobber (reg:CC FLAGS_REG))]
9034   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9035   "xor{l}\t{%2, %k0|%k0, %2}"
9036   [(set_attr "type" "alu")
9037    (set_attr "mode" "SI")])
9038
9039 (define_insn "*xorsi_2"
9040   [(set (reg 17)
9041         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9042                          (match_operand:SI 2 "general_operand" "rim,ri"))
9043                  (const_int 0)))
9044    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9045         (xor:SI (match_dup 1) (match_dup 2)))]
9046   "ix86_match_ccmode (insn, CCNOmode)
9047    && ix86_binary_operator_ok (XOR, SImode, operands)"
9048   "xor{l}\t{%2, %0|%0, %2}"
9049   [(set_attr "type" "alu")
9050    (set_attr "mode" "SI")])
9051
9052 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9053 ;; ??? Special case for immediate operand is missing - it is tricky.
9054 (define_insn "*xorsi_2_zext"
9055   [(set (reg 17)
9056         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9057                          (match_operand:SI 2 "general_operand" "rim"))
9058                  (const_int 0)))
9059    (set (match_operand:DI 0 "register_operand" "=r")
9060         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9061   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9062    && ix86_binary_operator_ok (XOR, SImode, operands)"
9063   "xor{l}\t{%2, %k0|%k0, %2}"
9064   [(set_attr "type" "alu")
9065    (set_attr "mode" "SI")])
9066
9067 (define_insn "*xorsi_2_zext_imm"
9068   [(set (reg 17)
9069         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9070                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9071                  (const_int 0)))
9072    (set (match_operand:DI 0 "register_operand" "=r")
9073         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9074   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9075    && ix86_binary_operator_ok (XOR, SImode, operands)"
9076   "xor{l}\t{%2, %k0|%k0, %2}"
9077   [(set_attr "type" "alu")
9078    (set_attr "mode" "SI")])
9079
9080 (define_insn "*xorsi_3"
9081   [(set (reg 17)
9082         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9083                          (match_operand:SI 2 "general_operand" "rim"))
9084                  (const_int 0)))
9085    (clobber (match_scratch:SI 0 "=r"))]
9086   "ix86_match_ccmode (insn, CCNOmode)
9087    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9088   "xor{l}\t{%2, %0|%0, %2}"
9089   [(set_attr "type" "alu")
9090    (set_attr "mode" "SI")])
9091
9092 (define_expand "xorhi3"
9093   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9094         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9095                 (match_operand:HI 2 "general_operand" "")))
9096    (clobber (reg:CC FLAGS_REG))]
9097   "TARGET_HIMODE_MATH"
9098   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9099
9100 (define_insn "*xorhi_1"
9101   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9102         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9103                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9104    (clobber (reg:CC FLAGS_REG))]
9105   "ix86_binary_operator_ok (XOR, HImode, operands)"
9106   "xor{w}\t{%2, %0|%0, %2}"
9107   [(set_attr "type" "alu")
9108    (set_attr "mode" "HI")])
9109
9110 (define_insn "*xorhi_2"
9111   [(set (reg 17)
9112         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9113                          (match_operand:HI 2 "general_operand" "rim,ri"))
9114                  (const_int 0)))
9115    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9116         (xor:HI (match_dup 1) (match_dup 2)))]
9117   "ix86_match_ccmode (insn, CCNOmode)
9118    && ix86_binary_operator_ok (XOR, HImode, operands)"
9119   "xor{w}\t{%2, %0|%0, %2}"
9120   [(set_attr "type" "alu")
9121    (set_attr "mode" "HI")])
9122
9123 (define_insn "*xorhi_3"
9124   [(set (reg 17)
9125         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9126                          (match_operand:HI 2 "general_operand" "rim"))
9127                  (const_int 0)))
9128    (clobber (match_scratch:HI 0 "=r"))]
9129   "ix86_match_ccmode (insn, CCNOmode)
9130    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9131   "xor{w}\t{%2, %0|%0, %2}"
9132   [(set_attr "type" "alu")
9133    (set_attr "mode" "HI")])
9134
9135 (define_expand "xorqi3"
9136   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9137         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9138                 (match_operand:QI 2 "general_operand" "")))
9139    (clobber (reg:CC FLAGS_REG))]
9140   "TARGET_QIMODE_MATH"
9141   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9142
9143 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9144 (define_insn "*xorqi_1"
9145   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9146         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9147                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9148    (clobber (reg:CC FLAGS_REG))]
9149   "ix86_binary_operator_ok (XOR, QImode, operands)"
9150   "@
9151    xor{b}\t{%2, %0|%0, %2}
9152    xor{b}\t{%2, %0|%0, %2}
9153    xor{l}\t{%k2, %k0|%k0, %k2}"
9154   [(set_attr "type" "alu")
9155    (set_attr "mode" "QI,QI,SI")])
9156
9157 (define_insn "*xorqi_1_slp"
9158   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9159         (xor:QI (match_dup 0)
9160                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9161    (clobber (reg:CC FLAGS_REG))]
9162   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9163    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9164   "xor{b}\t{%1, %0|%0, %1}"
9165   [(set_attr "type" "alu1")
9166    (set_attr "mode" "QI")])
9167
9168 (define_insn "xorqi_ext_0"
9169   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9170                          (const_int 8)
9171                          (const_int 8))
9172         (xor:SI 
9173           (zero_extract:SI
9174             (match_operand 1 "ext_register_operand" "0")
9175             (const_int 8)
9176             (const_int 8))
9177           (match_operand 2 "const_int_operand" "n")))
9178    (clobber (reg:CC FLAGS_REG))]
9179   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9180   "xor{b}\t{%2, %h0|%h0, %2}"
9181   [(set_attr "type" "alu")
9182    (set_attr "length_immediate" "1")
9183    (set_attr "mode" "QI")])
9184
9185 (define_insn "*xorqi_ext_1"
9186   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9187                          (const_int 8)
9188                          (const_int 8))
9189         (xor:SI 
9190           (zero_extract:SI
9191             (match_operand 1 "ext_register_operand" "0")
9192             (const_int 8)
9193             (const_int 8))
9194           (zero_extend:SI
9195             (match_operand:QI 2 "general_operand" "Qm"))))
9196    (clobber (reg:CC FLAGS_REG))]
9197   "!TARGET_64BIT
9198    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9199   "xor{b}\t{%2, %h0|%h0, %2}"
9200   [(set_attr "type" "alu")
9201    (set_attr "length_immediate" "0")
9202    (set_attr "mode" "QI")])
9203
9204 (define_insn "*xorqi_ext_1_rex64"
9205   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9206                          (const_int 8)
9207                          (const_int 8))
9208         (xor:SI 
9209           (zero_extract:SI
9210             (match_operand 1 "ext_register_operand" "0")
9211             (const_int 8)
9212             (const_int 8))
9213           (zero_extend:SI
9214             (match_operand 2 "ext_register_operand" "Q"))))
9215    (clobber (reg:CC FLAGS_REG))]
9216   "TARGET_64BIT
9217    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9218   "xor{b}\t{%2, %h0|%h0, %2}"
9219   [(set_attr "type" "alu")
9220    (set_attr "length_immediate" "0")
9221    (set_attr "mode" "QI")])
9222
9223 (define_insn "*xorqi_ext_2"
9224   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9225                          (const_int 8)
9226                          (const_int 8))
9227         (xor:SI 
9228           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9229                            (const_int 8)
9230                            (const_int 8))
9231           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9232                            (const_int 8)
9233                            (const_int 8))))
9234    (clobber (reg:CC FLAGS_REG))]
9235   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9236   "xor{b}\t{%h2, %h0|%h0, %h2}"
9237   [(set_attr "type" "alu")
9238    (set_attr "length_immediate" "0")
9239    (set_attr "mode" "QI")])
9240
9241 (define_insn "*xorqi_cc_1"
9242   [(set (reg 17)
9243         (compare
9244           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9245                   (match_operand:QI 2 "general_operand" "qim,qi"))
9246           (const_int 0)))
9247    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9248         (xor:QI (match_dup 1) (match_dup 2)))]
9249   "ix86_match_ccmode (insn, CCNOmode)
9250    && ix86_binary_operator_ok (XOR, QImode, operands)"
9251   "xor{b}\t{%2, %0|%0, %2}"
9252   [(set_attr "type" "alu")
9253    (set_attr "mode" "QI")])
9254
9255 (define_insn "*xorqi_2_slp"
9256   [(set (reg 17)
9257         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9258                          (match_operand:QI 1 "general_operand" "qim,qi"))
9259                  (const_int 0)))
9260    (set (strict_low_part (match_dup 0))
9261         (xor:QI (match_dup 0) (match_dup 1)))]
9262   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9263    && ix86_match_ccmode (insn, CCNOmode)
9264    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9265   "xor{b}\t{%1, %0|%0, %1}"
9266   [(set_attr "type" "alu1")
9267    (set_attr "mode" "QI")])
9268
9269 (define_insn "*xorqi_cc_2"
9270   [(set (reg 17)
9271         (compare
9272           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9273                   (match_operand:QI 2 "general_operand" "qim"))
9274           (const_int 0)))
9275    (clobber (match_scratch:QI 0 "=q"))]
9276   "ix86_match_ccmode (insn, CCNOmode)
9277    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9278   "xor{b}\t{%2, %0|%0, %2}"
9279   [(set_attr "type" "alu")
9280    (set_attr "mode" "QI")])
9281
9282 (define_insn "*xorqi_cc_ext_1"
9283   [(set (reg 17)
9284         (compare
9285           (xor:SI
9286             (zero_extract:SI
9287               (match_operand 1 "ext_register_operand" "0")
9288               (const_int 8)
9289               (const_int 8))
9290             (match_operand:QI 2 "general_operand" "qmn"))
9291           (const_int 0)))
9292    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9293                          (const_int 8)
9294                          (const_int 8))
9295         (xor:SI 
9296           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9297           (match_dup 2)))]
9298   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9299   "xor{b}\t{%2, %h0|%h0, %2}"
9300   [(set_attr "type" "alu")
9301    (set_attr "mode" "QI")])
9302
9303 (define_insn "*xorqi_cc_ext_1_rex64"
9304   [(set (reg 17)
9305         (compare
9306           (xor:SI
9307             (zero_extract:SI
9308               (match_operand 1 "ext_register_operand" "0")
9309               (const_int 8)
9310               (const_int 8))
9311             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9312           (const_int 0)))
9313    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9314                          (const_int 8)
9315                          (const_int 8))
9316         (xor:SI 
9317           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9318           (match_dup 2)))]
9319   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9320   "xor{b}\t{%2, %h0|%h0, %2}"
9321   [(set_attr "type" "alu")
9322    (set_attr "mode" "QI")])
9323
9324 (define_expand "xorqi_cc_ext_1"
9325   [(parallel [
9326      (set (reg:CCNO FLAGS_REG)
9327           (compare:CCNO
9328             (xor:SI
9329               (zero_extract:SI
9330                 (match_operand 1 "ext_register_operand" "")
9331                 (const_int 8)
9332                 (const_int 8))
9333               (match_operand:QI 2 "general_operand" ""))
9334             (const_int 0)))
9335      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9336                            (const_int 8)
9337                            (const_int 8))
9338           (xor:SI 
9339             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9340             (match_dup 2)))])]
9341   ""
9342   "")
9343
9344 (define_split
9345   [(set (match_operand 0 "register_operand" "")
9346         (xor (match_operand 1 "register_operand" "")
9347              (match_operand 2 "const_int_operand" "")))
9348    (clobber (reg:CC FLAGS_REG))]
9349    "reload_completed
9350     && QI_REG_P (operands[0])
9351     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9352     && !(INTVAL (operands[2]) & ~(255 << 8))
9353     && GET_MODE (operands[0]) != QImode"
9354   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9355                    (xor:SI (zero_extract:SI (match_dup 1)
9356                                             (const_int 8) (const_int 8))
9357                            (match_dup 2)))
9358               (clobber (reg:CC FLAGS_REG))])]
9359   "operands[0] = gen_lowpart (SImode, operands[0]);
9360    operands[1] = gen_lowpart (SImode, operands[1]);
9361    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9362
9363 ;; Since XOR can be encoded with sign extended immediate, this is only
9364 ;; profitable when 7th bit is set.
9365 (define_split
9366   [(set (match_operand 0 "register_operand" "")
9367         (xor (match_operand 1 "general_operand" "")
9368              (match_operand 2 "const_int_operand" "")))
9369    (clobber (reg:CC FLAGS_REG))]
9370    "reload_completed
9371     && ANY_QI_REG_P (operands[0])
9372     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9373     && !(INTVAL (operands[2]) & ~255)
9374     && (INTVAL (operands[2]) & 128)
9375     && GET_MODE (operands[0]) != QImode"
9376   [(parallel [(set (strict_low_part (match_dup 0))
9377                    (xor:QI (match_dup 1)
9378                            (match_dup 2)))
9379               (clobber (reg:CC FLAGS_REG))])]
9380   "operands[0] = gen_lowpart (QImode, operands[0]);
9381    operands[1] = gen_lowpart (QImode, operands[1]);
9382    operands[2] = gen_lowpart (QImode, operands[2]);")
9383 \f
9384 ;; Negation instructions
9385
9386 (define_expand "negdi2"
9387   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9388                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9389               (clobber (reg:CC FLAGS_REG))])]
9390   ""
9391   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9392
9393 (define_insn "*negdi2_1"
9394   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9395         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9396    (clobber (reg:CC FLAGS_REG))]
9397   "!TARGET_64BIT
9398    && ix86_unary_operator_ok (NEG, DImode, operands)"
9399   "#")
9400
9401 (define_split
9402   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9403         (neg:DI (match_operand:DI 1 "general_operand" "")))
9404    (clobber (reg:CC FLAGS_REG))]
9405   "!TARGET_64BIT && reload_completed"
9406   [(parallel
9407     [(set (reg:CCZ FLAGS_REG)
9408           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9409      (set (match_dup 0) (neg:SI (match_dup 2)))])
9410    (parallel
9411     [(set (match_dup 1)
9412           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9413                             (match_dup 3))
9414                    (const_int 0)))
9415      (clobber (reg:CC FLAGS_REG))])
9416    (parallel
9417     [(set (match_dup 1)
9418           (neg:SI (match_dup 1)))
9419      (clobber (reg:CC FLAGS_REG))])]
9420   "split_di (operands+1, 1, operands+2, operands+3);
9421    split_di (operands+0, 1, operands+0, operands+1);")
9422
9423 (define_insn "*negdi2_1_rex64"
9424   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9425         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9426    (clobber (reg:CC FLAGS_REG))]
9427   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9428   "neg{q}\t%0"
9429   [(set_attr "type" "negnot")
9430    (set_attr "mode" "DI")])
9431
9432 ;; The problem with neg is that it does not perform (compare x 0),
9433 ;; it really performs (compare 0 x), which leaves us with the zero
9434 ;; flag being the only useful item.
9435
9436 (define_insn "*negdi2_cmpz_rex64"
9437   [(set (reg:CCZ FLAGS_REG)
9438         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9439                      (const_int 0)))
9440    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9441         (neg:DI (match_dup 1)))]
9442   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9443   "neg{q}\t%0"
9444   [(set_attr "type" "negnot")
9445    (set_attr "mode" "DI")])
9446
9447
9448 (define_expand "negsi2"
9449   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9450                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9451               (clobber (reg:CC FLAGS_REG))])]
9452   ""
9453   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9454
9455 (define_insn "*negsi2_1"
9456   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9457         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9458    (clobber (reg:CC FLAGS_REG))]
9459   "ix86_unary_operator_ok (NEG, SImode, operands)"
9460   "neg{l}\t%0"
9461   [(set_attr "type" "negnot")
9462    (set_attr "mode" "SI")])
9463
9464 ;; Combine is quite creative about this pattern.
9465 (define_insn "*negsi2_1_zext"
9466   [(set (match_operand:DI 0 "register_operand" "=r")
9467         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9468                                         (const_int 32)))
9469                      (const_int 32)))
9470    (clobber (reg:CC FLAGS_REG))]
9471   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9472   "neg{l}\t%k0"
9473   [(set_attr "type" "negnot")
9474    (set_attr "mode" "SI")])
9475
9476 ;; The problem with neg is that it does not perform (compare x 0),
9477 ;; it really performs (compare 0 x), which leaves us with the zero
9478 ;; flag being the only useful item.
9479
9480 (define_insn "*negsi2_cmpz"
9481   [(set (reg:CCZ FLAGS_REG)
9482         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9483                      (const_int 0)))
9484    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9485         (neg:SI (match_dup 1)))]
9486   "ix86_unary_operator_ok (NEG, SImode, operands)"
9487   "neg{l}\t%0"
9488   [(set_attr "type" "negnot")
9489    (set_attr "mode" "SI")])
9490
9491 (define_insn "*negsi2_cmpz_zext"
9492   [(set (reg:CCZ FLAGS_REG)
9493         (compare:CCZ (lshiftrt:DI
9494                        (neg:DI (ashift:DI
9495                                  (match_operand:DI 1 "register_operand" "0")
9496                                  (const_int 32)))
9497                        (const_int 32))
9498                      (const_int 0)))
9499    (set (match_operand:DI 0 "register_operand" "=r")
9500         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9501                                         (const_int 32)))
9502                      (const_int 32)))]
9503   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9504   "neg{l}\t%k0"
9505   [(set_attr "type" "negnot")
9506    (set_attr "mode" "SI")])
9507
9508 (define_expand "neghi2"
9509   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9510                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9511               (clobber (reg:CC FLAGS_REG))])]
9512   "TARGET_HIMODE_MATH"
9513   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9514
9515 (define_insn "*neghi2_1"
9516   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9517         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9518    (clobber (reg:CC FLAGS_REG))]
9519   "ix86_unary_operator_ok (NEG, HImode, operands)"
9520   "neg{w}\t%0"
9521   [(set_attr "type" "negnot")
9522    (set_attr "mode" "HI")])
9523
9524 (define_insn "*neghi2_cmpz"
9525   [(set (reg:CCZ FLAGS_REG)
9526         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9527                      (const_int 0)))
9528    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9529         (neg:HI (match_dup 1)))]
9530   "ix86_unary_operator_ok (NEG, HImode, operands)"
9531   "neg{w}\t%0"
9532   [(set_attr "type" "negnot")
9533    (set_attr "mode" "HI")])
9534
9535 (define_expand "negqi2"
9536   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9537                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9538               (clobber (reg:CC FLAGS_REG))])]
9539   "TARGET_QIMODE_MATH"
9540   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9541
9542 (define_insn "*negqi2_1"
9543   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9544         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9545    (clobber (reg:CC FLAGS_REG))]
9546   "ix86_unary_operator_ok (NEG, QImode, operands)"
9547   "neg{b}\t%0"
9548   [(set_attr "type" "negnot")
9549    (set_attr "mode" "QI")])
9550
9551 (define_insn "*negqi2_cmpz"
9552   [(set (reg:CCZ FLAGS_REG)
9553         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9554                      (const_int 0)))
9555    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9556         (neg:QI (match_dup 1)))]
9557   "ix86_unary_operator_ok (NEG, QImode, operands)"
9558   "neg{b}\t%0"
9559   [(set_attr "type" "negnot")
9560    (set_attr "mode" "QI")])
9561
9562 ;; Changing of sign for FP values is doable using integer unit too.
9563
9564 (define_expand "negsf2"
9565   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9566                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9567               (clobber (reg:CC FLAGS_REG))])]
9568   "TARGET_80387"
9569   "if (TARGET_SSE)
9570      {
9571        /* In case operand is in memory,  we will not use SSE.  */
9572        if (memory_operand (operands[0], VOIDmode)
9573            && rtx_equal_p (operands[0], operands[1]))
9574          emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9575        else
9576         {
9577           /* Using SSE is tricky, since we need bitwise negation of -0
9578              in register.  */
9579           rtx reg = gen_reg_rtx (SFmode);
9580           rtx dest = operands[0];
9581           rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9582
9583           operands[1] = force_reg (SFmode, operands[1]);
9584           operands[0] = force_reg (SFmode, operands[0]);
9585           reg = force_reg (V4SFmode,
9586                            gen_rtx_CONST_VECTOR (V4SFmode,
9587                              gen_rtvec (4, imm, CONST0_RTX (SFmode),
9588                                         CONST0_RTX (SFmode),
9589                                         CONST0_RTX (SFmode))));
9590           emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9591           if (dest != operands[0])
9592             emit_move_insn (dest, operands[0]);
9593         }
9594        DONE;
9595      }
9596    ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9597
9598 (define_insn "negsf2_memory"
9599   [(set (match_operand:SF 0 "memory_operand" "=m")
9600         (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9601    (clobber (reg:CC FLAGS_REG))]
9602   "ix86_unary_operator_ok (NEG, SFmode, operands)"
9603   "#")
9604
9605 (define_insn "negsf2_ifs"
9606   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9607         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9608    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9609    (clobber (reg:CC FLAGS_REG))]
9610   "TARGET_SSE
9611    && (reload_in_progress || reload_completed
9612        || (register_operand (operands[0], VOIDmode)
9613            && register_operand (operands[1], VOIDmode)))"
9614   "#")
9615
9616 (define_split
9617   [(set (match_operand:SF 0 "memory_operand" "")
9618         (neg:SF (match_operand:SF 1 "memory_operand" "")))
9619    (use (match_operand:SF 2 "" ""))
9620    (clobber (reg:CC FLAGS_REG))]
9621   ""
9622   [(parallel [(set (match_dup 0)
9623                    (neg:SF (match_dup 1)))
9624               (clobber (reg:CC FLAGS_REG))])])
9625
9626 (define_split
9627   [(set (match_operand:SF 0 "register_operand" "")
9628         (neg:SF (match_operand:SF 1 "register_operand" "")))
9629    (use (match_operand:V4SF 2 "" ""))
9630    (clobber (reg:CC FLAGS_REG))]
9631   "reload_completed && !SSE_REG_P (operands[0])"
9632   [(parallel [(set (match_dup 0)
9633                    (neg:SF (match_dup 1)))
9634               (clobber (reg:CC FLAGS_REG))])])
9635
9636 (define_split
9637   [(set (match_operand:SF 0 "register_operand" "")
9638         (neg:SF (match_operand:SF 1 "register_operand" "")))
9639    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9640    (clobber (reg:CC FLAGS_REG))]
9641   "reload_completed && SSE_REG_P (operands[0])"
9642   [(set (match_dup 0)
9643         (xor:V4SF (match_dup 1)
9644                   (match_dup 2)))]
9645 {
9646   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
9647   operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
9648   if (operands_match_p (operands[0], operands[2]))
9649     {
9650       rtx tmp;
9651       tmp = operands[1];
9652       operands[1] = operands[2];
9653       operands[2] = tmp;
9654     }
9655 })
9656
9657
9658 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9659 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9660 ;; to itself.
9661 (define_insn "*negsf2_if"
9662   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9663         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9664    (clobber (reg:CC FLAGS_REG))]
9665   "TARGET_80387 && !TARGET_SSE
9666    && ix86_unary_operator_ok (NEG, SFmode, operands)"
9667   "#")
9668
9669 (define_split
9670   [(set (match_operand:SF 0 "fp_register_operand" "")
9671         (neg:SF (match_operand:SF 1 "register_operand" "")))
9672    (clobber (reg:CC FLAGS_REG))]
9673   "TARGET_80387 && reload_completed"
9674   [(set (match_dup 0)
9675         (neg:SF (match_dup 1)))]
9676   "")
9677
9678 (define_split
9679   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9680         (neg:SF (match_operand:SF 1 "register_operand" "")))
9681    (clobber (reg:CC FLAGS_REG))]
9682   "TARGET_80387 && reload_completed"
9683   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9684               (clobber (reg:CC FLAGS_REG))])]
9685   "operands[1] = gen_int_mode (0x80000000, SImode);
9686    operands[0] = gen_lowpart (SImode, operands[0]);")
9687
9688 (define_split
9689   [(set (match_operand 0 "memory_operand" "")
9690         (neg (match_operand 1 "memory_operand" "")))
9691    (clobber (reg:CC FLAGS_REG))]
9692   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9693   [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9694               (clobber (reg:CC FLAGS_REG))])]
9695 {
9696   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9697
9698   if (GET_MODE (operands[1]) == XFmode)
9699     size = 10;
9700   operands[0] = adjust_address (operands[0], QImode, size - 1);
9701   operands[1] = gen_int_mode (0x80, QImode);
9702 })
9703
9704 (define_expand "negdf2"
9705   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9706                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9707               (clobber (reg:CC FLAGS_REG))])]
9708   "TARGET_80387"
9709   "if (TARGET_SSE2)
9710      {
9711        /* In case operand is in memory,  we will not use SSE.  */
9712        if (memory_operand (operands[0], VOIDmode)
9713            && rtx_equal_p (operands[0], operands[1]))
9714          emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9715        else
9716         {
9717           /* Using SSE is tricky, since we need bitwise negation of -0
9718              in register.  */
9719           rtx reg;
9720 #if HOST_BITS_PER_WIDE_INT >= 64
9721           rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9722 #else
9723           rtx imm = immed_double_const (0, 0x80000000, DImode);
9724 #endif
9725           rtx dest = operands[0];
9726
9727           operands[1] = force_reg (DFmode, operands[1]);
9728           operands[0] = force_reg (DFmode, operands[0]);
9729           imm = gen_lowpart (DFmode, imm);
9730           reg = force_reg (V2DFmode,
9731                            gen_rtx_CONST_VECTOR (V2DFmode,
9732                              gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9733           emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9734           if (dest != operands[0])
9735             emit_move_insn (dest, operands[0]);
9736         }
9737        DONE;
9738      }
9739    ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9740
9741 (define_insn "negdf2_memory"
9742   [(set (match_operand:DF 0 "memory_operand" "=m")
9743         (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9744    (clobber (reg:CC FLAGS_REG))]
9745   "ix86_unary_operator_ok (NEG, DFmode, operands)"
9746   "#")
9747
9748 (define_insn "negdf2_ifs"
9749   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9750         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9751    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9752    (clobber (reg:CC FLAGS_REG))]
9753   "!TARGET_64BIT && TARGET_SSE2
9754    && (reload_in_progress || reload_completed
9755        || (register_operand (operands[0], VOIDmode)
9756            && register_operand (operands[1], VOIDmode)))"
9757   "#")
9758
9759 (define_insn "*negdf2_ifs_rex64"
9760   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9761         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9762    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9763    (clobber (reg:CC FLAGS_REG))]
9764   "TARGET_64BIT && TARGET_SSE2
9765    && (reload_in_progress || reload_completed
9766        || (register_operand (operands[0], VOIDmode)
9767            && register_operand (operands[1], VOIDmode)))"
9768   "#")
9769
9770 (define_split
9771   [(set (match_operand:DF 0 "memory_operand" "")
9772         (neg:DF (match_operand:DF 1 "memory_operand" "")))
9773    (use (match_operand:V2DF 2 "" ""))
9774    (clobber (reg:CC FLAGS_REG))]
9775   ""
9776   [(parallel [(set (match_dup 0)
9777                    (neg:DF (match_dup 1)))
9778               (clobber (reg:CC FLAGS_REG))])])
9779
9780 (define_split
9781   [(set (match_operand:DF 0 "register_operand" "")
9782         (neg:DF (match_operand:DF 1 "register_operand" "")))
9783    (use (match_operand:V2DF 2 "" ""))
9784    (clobber (reg:CC FLAGS_REG))]
9785   "reload_completed && !SSE_REG_P (operands[0])
9786    && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9787   [(parallel [(set (match_dup 0)
9788                    (neg:DF (match_dup 1)))
9789               (clobber (reg:CC FLAGS_REG))])])
9790
9791 (define_split
9792   [(set (match_operand:DF 0 "register_operand" "")
9793         (neg:DF (match_operand:DF 1 "register_operand" "")))
9794    (use (match_operand:V2DF 2 "" ""))
9795    (clobber (reg:CC FLAGS_REG))]
9796   "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9797   [(parallel [(set (match_dup 0)
9798                    (xor:DI (match_dup 1) (match_dup 2)))
9799               (clobber (reg:CC FLAGS_REG))])]
9800    "operands[0] = gen_lowpart (DImode, operands[0]);
9801     operands[1] = gen_lowpart (DImode, operands[1]);
9802     operands[2] = gen_lowpart (DImode, operands[2]);")
9803
9804 (define_split
9805   [(set (match_operand:DF 0 "register_operand" "")
9806         (neg:DF (match_operand:DF 1 "register_operand" "")))
9807    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9808    (clobber (reg:CC FLAGS_REG))]
9809   "reload_completed && SSE_REG_P (operands[0])"
9810   [(set (match_dup 0)
9811         (xor:V2DF (match_dup 1)
9812                   (match_dup 2)))]
9813 {
9814   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9815   operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
9816   /* Avoid possible reformatting on the operands.  */
9817   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9818     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9819   if (operands_match_p (operands[0], operands[2]))
9820     {
9821       rtx tmp;
9822       tmp = operands[1];
9823       operands[1] = operands[2];
9824       operands[2] = tmp;
9825     }
9826 })
9827
9828 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9829 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9830 ;; to itself.
9831 (define_insn "*negdf2_if"
9832   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9833         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9834    (clobber (reg:CC FLAGS_REG))]
9835   "!TARGET_64BIT && TARGET_80387
9836    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9837   "#")
9838
9839 ;; FIXME: We should to allow integer registers here.  Problem is that
9840 ;; we need another scratch register to get constant from.
9841 ;; Forcing constant to mem if no register available in peep2 should be
9842 ;; safe even for PIC mode, because of RIP relative addressing.
9843 (define_insn "*negdf2_if_rex64"
9844   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9845         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9846    (clobber (reg:CC FLAGS_REG))]
9847   "TARGET_64BIT && TARGET_80387
9848    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9849   "#")
9850
9851 (define_split
9852   [(set (match_operand:DF 0 "fp_register_operand" "")
9853         (neg:DF (match_operand:DF 1 "register_operand" "")))
9854    (clobber (reg:CC FLAGS_REG))]
9855   "TARGET_80387 && reload_completed"
9856   [(set (match_dup 0)
9857         (neg:DF (match_dup 1)))]
9858   "")
9859
9860 (define_split
9861   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9862         (neg:DF (match_operand:DF 1 "register_operand" "")))
9863    (clobber (reg:CC FLAGS_REG))]
9864   "!TARGET_64BIT && TARGET_80387 && reload_completed"
9865   [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9866               (clobber (reg:CC FLAGS_REG))])]
9867   "operands[4] = gen_int_mode (0x80000000, SImode);
9868    split_di (operands+0, 1, operands+2, operands+3);")
9869
9870 (define_expand "negxf2"
9871   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9872                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9873               (clobber (reg:CC FLAGS_REG))])]
9874   "TARGET_80387"
9875   "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9876
9877 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9878 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9879 ;; to itself.
9880 (define_insn "*negxf2_if"
9881   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9882         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9883    (clobber (reg:CC FLAGS_REG))]
9884   "TARGET_80387
9885    && ix86_unary_operator_ok (NEG, XFmode, operands)"
9886   "#")
9887
9888 (define_split
9889   [(set (match_operand:XF 0 "fp_register_operand" "")
9890         (neg:XF (match_operand:XF 1 "register_operand" "")))
9891    (clobber (reg:CC FLAGS_REG))]
9892   "TARGET_80387 && reload_completed"
9893   [(set (match_dup 0)
9894         (neg:XF (match_dup 1)))]
9895   "")
9896
9897 (define_split
9898   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9899         (neg:XF (match_operand:XF 1 "register_operand" "")))
9900    (clobber (reg:CC FLAGS_REG))]
9901   "TARGET_80387 && reload_completed"
9902   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9903               (clobber (reg:CC FLAGS_REG))])]
9904   "operands[1] = GEN_INT (0x8000);
9905    operands[0] = gen_rtx_REG (SImode,
9906                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9907
9908 ;; Conditionalize these after reload. If they matches before reload, we 
9909 ;; lose the clobber and ability to use integer instructions.
9910
9911 (define_insn "*negsf2_1"
9912   [(set (match_operand:SF 0 "register_operand" "=f")
9913         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9914   "TARGET_80387 && reload_completed"
9915   "fchs"
9916   [(set_attr "type" "fsgn")
9917    (set_attr "mode" "SF")])
9918
9919 (define_insn "*negdf2_1"
9920   [(set (match_operand:DF 0 "register_operand" "=f")
9921         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9922   "TARGET_80387 && reload_completed"
9923   "fchs"
9924   [(set_attr "type" "fsgn")
9925    (set_attr "mode" "DF")])
9926
9927 (define_insn "*negextendsfdf2"
9928   [(set (match_operand:DF 0 "register_operand" "=f")
9929         (neg:DF (float_extend:DF
9930                   (match_operand:SF 1 "register_operand" "0"))))]
9931   "TARGET_80387"
9932   "fchs"
9933   [(set_attr "type" "fsgn")
9934    (set_attr "mode" "DF")])
9935
9936 (define_insn "*negxf2_1"
9937   [(set (match_operand:XF 0 "register_operand" "=f")
9938         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9939   "TARGET_80387 && reload_completed"
9940   "fchs"
9941   [(set_attr "type" "fsgn")
9942    (set_attr "mode" "XF")])
9943
9944 (define_insn "*negextenddfxf2"
9945   [(set (match_operand:XF 0 "register_operand" "=f")
9946         (neg:XF (float_extend:XF
9947                   (match_operand:DF 1 "register_operand" "0"))))]
9948   "TARGET_80387"
9949   "fchs"
9950   [(set_attr "type" "fsgn")
9951    (set_attr "mode" "XF")])
9952
9953 (define_insn "*negextendsfxf2"
9954   [(set (match_operand:XF 0 "register_operand" "=f")
9955         (neg:XF (float_extend:XF
9956                   (match_operand:SF 1 "register_operand" "0"))))]
9957   "TARGET_80387"
9958   "fchs"
9959   [(set_attr "type" "fsgn")
9960    (set_attr "mode" "XF")])
9961 \f
9962 ;; Absolute value instructions
9963
9964 (define_expand "abssf2"
9965   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9966                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9967               (clobber (reg:CC FLAGS_REG))])]
9968   "TARGET_80387"
9969   "if (TARGET_SSE)
9970      {
9971        /* In case operand is in memory,  we will not use SSE.  */
9972        if (memory_operand (operands[0], VOIDmode)
9973            && rtx_equal_p (operands[0], operands[1]))
9974          emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9975        else
9976         {
9977           /* Using SSE is tricky, since we need bitwise negation of -0
9978              in register.  */
9979           rtx reg = gen_reg_rtx (V4SFmode);
9980           rtx dest = operands[0];
9981           rtx imm;
9982
9983           operands[1] = force_reg (SFmode, operands[1]);
9984           operands[0] = force_reg (SFmode, operands[0]);
9985           imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
9986           reg = force_reg (V4SFmode,
9987                            gen_rtx_CONST_VECTOR (V4SFmode,
9988                            gen_rtvec (4, imm, CONST0_RTX (SFmode),
9989                                       CONST0_RTX (SFmode),
9990                                       CONST0_RTX (SFmode))));
9991           emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
9992           if (dest != operands[0])
9993             emit_move_insn (dest, operands[0]);
9994         }
9995        DONE;
9996      }
9997    ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
9998
9999 (define_insn "abssf2_memory"
10000   [(set (match_operand:SF 0 "memory_operand" "=m")
10001         (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10002    (clobber (reg:CC FLAGS_REG))]
10003   "ix86_unary_operator_ok (ABS, SFmode, operands)"
10004   "#")
10005
10006 (define_insn "abssf2_ifs"
10007   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10008         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10009    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10010    (clobber (reg:CC FLAGS_REG))]
10011   "TARGET_SSE
10012    && (reload_in_progress || reload_completed
10013        || (register_operand (operands[0], VOIDmode)
10014             && register_operand (operands[1], VOIDmode)))"
10015   "#")
10016
10017 (define_split
10018   [(set (match_operand:SF 0 "memory_operand" "")
10019         (abs:SF (match_operand:SF 1 "memory_operand" "")))
10020    (use (match_operand:V4SF 2 "" ""))
10021    (clobber (reg:CC FLAGS_REG))]
10022   ""
10023   [(parallel [(set (match_dup 0)
10024                    (abs:SF (match_dup 1)))
10025               (clobber (reg:CC FLAGS_REG))])])
10026
10027 (define_split
10028   [(set (match_operand:SF 0 "register_operand" "")
10029         (abs:SF (match_operand:SF 1 "register_operand" "")))
10030    (use (match_operand:V4SF 2 "" ""))
10031    (clobber (reg:CC FLAGS_REG))]
10032   "reload_completed && !SSE_REG_P (operands[0])"
10033   [(parallel [(set (match_dup 0)
10034                    (abs:SF (match_dup 1)))
10035               (clobber (reg:CC FLAGS_REG))])])
10036
10037 (define_split
10038   [(set (match_operand:SF 0 "register_operand" "")
10039         (abs:SF (match_operand:SF 1 "register_operand" "")))
10040    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10041    (clobber (reg:CC FLAGS_REG))]
10042   "reload_completed && SSE_REG_P (operands[0])"
10043   [(set (match_dup 0)
10044         (and:V4SF (match_dup 1)
10045                   (match_dup 2)))]
10046 {
10047   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
10048   operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
10049   if (operands_match_p (operands[0], operands[2]))
10050     {
10051       rtx tmp;
10052       tmp = operands[1];
10053       operands[1] = operands[2];
10054       operands[2] = tmp;
10055     }
10056 })
10057
10058 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10059 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10060 ;; to itself.
10061 (define_insn "*abssf2_if"
10062   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10063         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10064    (clobber (reg:CC FLAGS_REG))]
10065   "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10066   "#")
10067
10068 (define_split
10069   [(set (match_operand:SF 0 "fp_register_operand" "")
10070         (abs:SF (match_operand:SF 1 "register_operand" "")))
10071    (clobber (reg:CC FLAGS_REG))]
10072   "TARGET_80387 && reload_completed"
10073   [(set (match_dup 0)
10074         (abs:SF (match_dup 1)))]
10075   "")
10076
10077 (define_split
10078   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10079         (abs:SF (match_operand:SF 1 "register_operand" "")))
10080    (clobber (reg:CC FLAGS_REG))]
10081   "TARGET_80387 && reload_completed"
10082   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10083               (clobber (reg:CC FLAGS_REG))])]
10084   "operands[1] = gen_int_mode (~0x80000000, SImode);
10085    operands[0] = gen_lowpart (SImode, operands[0]);")
10086
10087 (define_split
10088   [(set (match_operand 0 "memory_operand" "")
10089         (abs (match_operand 1 "memory_operand" "")))
10090    (clobber (reg:CC FLAGS_REG))]
10091   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10092   [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10093               (clobber (reg:CC FLAGS_REG))])]
10094 {
10095   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10096
10097   if (GET_MODE (operands[1]) == XFmode)
10098     size = 10;
10099   operands[0] = adjust_address (operands[0], QImode, size - 1);
10100   operands[1] = gen_int_mode (~0x80, QImode);
10101 })
10102
10103 (define_expand "absdf2"
10104   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10105                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10106               (clobber (reg:CC FLAGS_REG))])]
10107   "TARGET_80387"
10108   "if (TARGET_SSE2)
10109      {
10110        /* In case operand is in memory,  we will not use SSE.  */
10111        if (memory_operand (operands[0], VOIDmode)
10112            && rtx_equal_p (operands[0], operands[1]))
10113          emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10114        else
10115         {
10116           /* Using SSE is tricky, since we need bitwise negation of -0
10117              in register.  */
10118           rtx reg = gen_reg_rtx (V2DFmode);
10119 #if HOST_BITS_PER_WIDE_INT >= 64
10120           rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10121 #else
10122           rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10123 #endif
10124           rtx dest = operands[0];
10125
10126           operands[1] = force_reg (DFmode, operands[1]);
10127           operands[0] = force_reg (DFmode, operands[0]);
10128
10129           /* Produce LONG_DOUBLE with the proper immediate argument.  */
10130           imm = gen_lowpart (DFmode, imm);
10131           reg = force_reg (V2DFmode,
10132                            gen_rtx_CONST_VECTOR (V2DFmode,
10133                            gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10134           emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10135           if (dest != operands[0])
10136             emit_move_insn (dest, operands[0]);
10137         }
10138        DONE;
10139      }
10140    ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10141
10142 (define_insn "absdf2_memory"
10143   [(set (match_operand:DF 0 "memory_operand" "=m")
10144         (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10145    (clobber (reg:CC FLAGS_REG))]
10146   "ix86_unary_operator_ok (ABS, DFmode, operands)"
10147   "#")
10148
10149 (define_insn "absdf2_ifs"
10150   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10151         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10152    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10153    (clobber (reg:CC FLAGS_REG))]
10154   "!TARGET_64BIT && TARGET_SSE2
10155    && (reload_in_progress || reload_completed
10156        || (register_operand (operands[0], VOIDmode)
10157            && register_operand (operands[1], VOIDmode)))"
10158   "#")
10159
10160 (define_insn "*absdf2_ifs_rex64"
10161   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10162         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10163    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10164    (clobber (reg:CC FLAGS_REG))]
10165   "TARGET_64BIT && TARGET_SSE2
10166    && (reload_in_progress || reload_completed
10167        || (register_operand (operands[0], VOIDmode)
10168            && register_operand (operands[1], VOIDmode)))"
10169   "#")
10170
10171 (define_split
10172   [(set (match_operand:DF 0 "memory_operand" "")
10173         (abs:DF (match_operand:DF 1 "memory_operand" "")))
10174    (use (match_operand:V2DF 2 "" ""))
10175    (clobber (reg:CC FLAGS_REG))]
10176   ""
10177   [(parallel [(set (match_dup 0)
10178                    (abs:DF (match_dup 1)))
10179               (clobber (reg:CC FLAGS_REG))])])
10180
10181 (define_split
10182   [(set (match_operand:DF 0 "register_operand" "")
10183         (abs:DF (match_operand:DF 1 "register_operand" "")))
10184    (use (match_operand:V2DF 2 "" ""))
10185    (clobber (reg:CC FLAGS_REG))]
10186   "reload_completed && !SSE_REG_P (operands[0])"
10187   [(parallel [(set (match_dup 0)
10188                    (abs:DF (match_dup 1)))
10189               (clobber (reg:CC FLAGS_REG))])])
10190
10191 (define_split
10192   [(set (match_operand:DF 0 "register_operand" "")
10193         (abs:DF (match_operand:DF 1 "register_operand" "")))
10194    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10195    (clobber (reg:CC FLAGS_REG))]
10196   "reload_completed && SSE_REG_P (operands[0])"
10197   [(set (match_dup 0)
10198         (and:V2DF (match_dup 1)
10199                   (match_dup 2)))]
10200 {
10201   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10202   operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
10203   /* Avoid possible reformatting on the operands.  */
10204   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10205     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10206   if (operands_match_p (operands[0], operands[2]))
10207     {
10208       rtx tmp;
10209       tmp = operands[1];
10210       operands[1] = operands[2];
10211       operands[2] = tmp;
10212     }
10213 })
10214
10215
10216 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10217 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10218 ;; to itself.
10219 (define_insn "*absdf2_if"
10220   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10221         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10222    (clobber (reg:CC FLAGS_REG))]
10223   "!TARGET_64BIT && TARGET_80387
10224    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10225   "#")
10226
10227 ;; FIXME: We should to allow integer registers here.  Problem is that
10228 ;; we need another scratch register to get constant from.
10229 ;; Forcing constant to mem if no register available in peep2 should be
10230 ;; safe even for PIC mode, because of RIP relative addressing.
10231 (define_insn "*absdf2_if_rex64"
10232   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10233         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10234    (clobber (reg:CC FLAGS_REG))]
10235   "TARGET_64BIT && TARGET_80387
10236    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10237   "#")
10238
10239 (define_split
10240   [(set (match_operand:DF 0 "fp_register_operand" "")
10241         (abs:DF (match_operand:DF 1 "register_operand" "")))
10242    (clobber (reg:CC FLAGS_REG))]
10243   "TARGET_80387 && reload_completed"
10244   [(set (match_dup 0)
10245         (abs:DF (match_dup 1)))]
10246   "")
10247
10248 (define_split
10249   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10250         (abs:DF (match_operand:DF 1 "register_operand" "")))
10251    (clobber (reg:CC FLAGS_REG))]
10252   "!TARGET_64BIT && TARGET_80387 && reload_completed"
10253   [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10254               (clobber (reg:CC FLAGS_REG))])]
10255   "operands[4] = gen_int_mode (~0x80000000, SImode);
10256    split_di (operands+0, 1, operands+2, operands+3);")
10257
10258 (define_expand "absxf2"
10259   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10260                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10261               (clobber (reg:CC FLAGS_REG))])]
10262   "TARGET_80387"
10263   "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10264
10265 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10266 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10267 ;; to itself.
10268 (define_insn "*absxf2_if"
10269   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10270         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10271    (clobber (reg:CC FLAGS_REG))]
10272   "TARGET_80387
10273    && ix86_unary_operator_ok (ABS, XFmode, operands)"
10274   "#")
10275
10276 (define_split
10277   [(set (match_operand:XF 0 "fp_register_operand" "")
10278         (abs:XF (match_operand:XF 1 "register_operand" "")))
10279    (clobber (reg:CC FLAGS_REG))]
10280   "TARGET_80387 && reload_completed"
10281   [(set (match_dup 0)
10282         (abs:XF (match_dup 1)))]
10283   "")
10284
10285 (define_split
10286   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10287         (abs:XF (match_operand:XF 1 "register_operand" "")))
10288    (clobber (reg:CC FLAGS_REG))]
10289   "TARGET_80387 && reload_completed"
10290   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10291               (clobber (reg:CC FLAGS_REG))])]
10292   "operands[1] = GEN_INT (~0x8000);
10293    operands[0] = gen_rtx_REG (SImode,
10294                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10295
10296 (define_insn "*abssf2_1"
10297   [(set (match_operand:SF 0 "register_operand" "=f")
10298         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10299   "TARGET_80387 && reload_completed"
10300   "fabs"
10301   [(set_attr "type" "fsgn")
10302    (set_attr "mode" "SF")])
10303
10304 (define_insn "*absdf2_1"
10305   [(set (match_operand:DF 0 "register_operand" "=f")
10306         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10307   "TARGET_80387 && reload_completed"
10308   "fabs"
10309   [(set_attr "type" "fsgn")
10310    (set_attr "mode" "DF")])
10311
10312 (define_insn "*absextendsfdf2"
10313   [(set (match_operand:DF 0 "register_operand" "=f")
10314         (abs:DF (float_extend:DF
10315                   (match_operand:SF 1 "register_operand" "0"))))]
10316   "TARGET_80387"
10317   "fabs"
10318   [(set_attr "type" "fsgn")
10319    (set_attr "mode" "DF")])
10320
10321 (define_insn "*absxf2_1"
10322   [(set (match_operand:XF 0 "register_operand" "=f")
10323         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10324   "TARGET_80387 && reload_completed"
10325   "fabs"
10326   [(set_attr "type" "fsgn")
10327    (set_attr "mode" "DF")])
10328
10329 (define_insn "*absextenddfxf2"
10330   [(set (match_operand:XF 0 "register_operand" "=f")
10331         (abs:XF (float_extend:XF
10332           (match_operand:DF 1 "register_operand" "0"))))]
10333   "TARGET_80387"
10334   "fabs"
10335   [(set_attr "type" "fsgn")
10336    (set_attr "mode" "XF")])
10337
10338 (define_insn "*absextendsfxf2"
10339   [(set (match_operand:XF 0 "register_operand" "=f")
10340         (abs:XF (float_extend:XF
10341           (match_operand:SF 1 "register_operand" "0"))))]
10342   "TARGET_80387"
10343   "fabs"
10344   [(set_attr "type" "fsgn")
10345    (set_attr "mode" "XF")])
10346 \f
10347 ;; One complement instructions
10348
10349 (define_expand "one_cmpldi2"
10350   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10351         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10352   "TARGET_64BIT"
10353   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10354
10355 (define_insn "*one_cmpldi2_1_rex64"
10356   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10357         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10358   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10359   "not{q}\t%0"
10360   [(set_attr "type" "negnot")
10361    (set_attr "mode" "DI")])
10362
10363 (define_insn "*one_cmpldi2_2_rex64"
10364   [(set (reg 17)
10365         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10366                  (const_int 0)))
10367    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10368         (not:DI (match_dup 1)))]
10369   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10370    && ix86_unary_operator_ok (NOT, DImode, operands)"
10371   "#"
10372   [(set_attr "type" "alu1")
10373    (set_attr "mode" "DI")])
10374
10375 (define_split
10376   [(set (reg 17)
10377         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10378                  (const_int 0)))
10379    (set (match_operand:DI 0 "nonimmediate_operand" "")
10380         (not:DI (match_dup 1)))]
10381   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10382   [(parallel [(set (reg:CCNO FLAGS_REG)
10383                    (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10384                                  (const_int 0)))
10385               (set (match_dup 0)
10386                    (xor:DI (match_dup 1) (const_int -1)))])]
10387   "")
10388
10389 (define_expand "one_cmplsi2"
10390   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10391         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10392   ""
10393   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10394
10395 (define_insn "*one_cmplsi2_1"
10396   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10397         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10398   "ix86_unary_operator_ok (NOT, SImode, operands)"
10399   "not{l}\t%0"
10400   [(set_attr "type" "negnot")
10401    (set_attr "mode" "SI")])
10402
10403 ;; ??? Currently never generated - xor is used instead.
10404 (define_insn "*one_cmplsi2_1_zext"
10405   [(set (match_operand:DI 0 "register_operand" "=r")
10406         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10407   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10408   "not{l}\t%k0"
10409   [(set_attr "type" "negnot")
10410    (set_attr "mode" "SI")])
10411
10412 (define_insn "*one_cmplsi2_2"
10413   [(set (reg 17)
10414         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10415                  (const_int 0)))
10416    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10417         (not:SI (match_dup 1)))]
10418   "ix86_match_ccmode (insn, CCNOmode)
10419    && ix86_unary_operator_ok (NOT, SImode, operands)"
10420   "#"
10421   [(set_attr "type" "alu1")
10422    (set_attr "mode" "SI")])
10423
10424 (define_split
10425   [(set (reg 17)
10426         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10427                  (const_int 0)))
10428    (set (match_operand:SI 0 "nonimmediate_operand" "")
10429         (not:SI (match_dup 1)))]
10430   "ix86_match_ccmode (insn, CCNOmode)"
10431   [(parallel [(set (reg:CCNO FLAGS_REG)
10432                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10433                                  (const_int 0)))
10434               (set (match_dup 0)
10435                    (xor:SI (match_dup 1) (const_int -1)))])]
10436   "")
10437
10438 ;; ??? Currently never generated - xor is used instead.
10439 (define_insn "*one_cmplsi2_2_zext"
10440   [(set (reg 17)
10441         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10442                  (const_int 0)))
10443    (set (match_operand:DI 0 "register_operand" "=r")
10444         (zero_extend:DI (not:SI (match_dup 1))))]
10445   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10446    && ix86_unary_operator_ok (NOT, SImode, operands)"
10447   "#"
10448   [(set_attr "type" "alu1")
10449    (set_attr "mode" "SI")])
10450
10451 (define_split
10452   [(set (reg 17)
10453         (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10454                  (const_int 0)))
10455    (set (match_operand:DI 0 "register_operand" "")
10456         (zero_extend:DI (not:SI (match_dup 1))))]
10457   "ix86_match_ccmode (insn, CCNOmode)"
10458   [(parallel [(set (reg:CCNO FLAGS_REG)
10459                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10460                                  (const_int 0)))
10461               (set (match_dup 0)
10462                    (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10463   "")
10464
10465 (define_expand "one_cmplhi2"
10466   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10467         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10468   "TARGET_HIMODE_MATH"
10469   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10470
10471 (define_insn "*one_cmplhi2_1"
10472   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10473         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10474   "ix86_unary_operator_ok (NOT, HImode, operands)"
10475   "not{w}\t%0"
10476   [(set_attr "type" "negnot")
10477    (set_attr "mode" "HI")])
10478
10479 (define_insn "*one_cmplhi2_2"
10480   [(set (reg 17)
10481         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10482                  (const_int 0)))
10483    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10484         (not:HI (match_dup 1)))]
10485   "ix86_match_ccmode (insn, CCNOmode)
10486    && ix86_unary_operator_ok (NEG, HImode, operands)"
10487   "#"
10488   [(set_attr "type" "alu1")
10489    (set_attr "mode" "HI")])
10490
10491 (define_split
10492   [(set (reg 17)
10493         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10494                  (const_int 0)))
10495    (set (match_operand:HI 0 "nonimmediate_operand" "")
10496         (not:HI (match_dup 1)))]
10497   "ix86_match_ccmode (insn, CCNOmode)"
10498   [(parallel [(set (reg:CCNO FLAGS_REG)
10499                    (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10500                                  (const_int 0)))
10501               (set (match_dup 0)
10502                    (xor:HI (match_dup 1) (const_int -1)))])]
10503   "")
10504
10505 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10506 (define_expand "one_cmplqi2"
10507   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10508         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10509   "TARGET_QIMODE_MATH"
10510   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10511
10512 (define_insn "*one_cmplqi2_1"
10513   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10514         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10515   "ix86_unary_operator_ok (NOT, QImode, operands)"
10516   "@
10517    not{b}\t%0
10518    not{l}\t%k0"
10519   [(set_attr "type" "negnot")
10520    (set_attr "mode" "QI,SI")])
10521
10522 (define_insn "*one_cmplqi2_2"
10523   [(set (reg 17)
10524         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10525                  (const_int 0)))
10526    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10527         (not:QI (match_dup 1)))]
10528   "ix86_match_ccmode (insn, CCNOmode)
10529    && ix86_unary_operator_ok (NOT, QImode, operands)"
10530   "#"
10531   [(set_attr "type" "alu1")
10532    (set_attr "mode" "QI")])
10533
10534 (define_split
10535   [(set (reg 17)
10536         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10537                  (const_int 0)))
10538    (set (match_operand:QI 0 "nonimmediate_operand" "")
10539         (not:QI (match_dup 1)))]
10540   "ix86_match_ccmode (insn, CCNOmode)"
10541   [(parallel [(set (reg:CCNO FLAGS_REG)
10542                    (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10543                                  (const_int 0)))
10544               (set (match_dup 0)
10545                    (xor:QI (match_dup 1) (const_int -1)))])]
10546   "")
10547 \f
10548 ;; Arithmetic shift instructions
10549
10550 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10551 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10552 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10553 ;; from the assembler input.
10554 ;;
10555 ;; This instruction shifts the target reg/mem as usual, but instead of
10556 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10557 ;; is a left shift double, bits are taken from the high order bits of
10558 ;; reg, else if the insn is a shift right double, bits are taken from the
10559 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10560 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10561 ;;
10562 ;; Since sh[lr]d does not change the `reg' operand, that is done
10563 ;; separately, making all shifts emit pairs of shift double and normal
10564 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10565 ;; support a 63 bit shift, each shift where the count is in a reg expands
10566 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10567 ;;
10568 ;; If the shift count is a constant, we need never emit more than one
10569 ;; shift pair, instead using moves and sign extension for counts greater
10570 ;; than 31.
10571
10572 (define_expand "ashldi3"
10573   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10574                    (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10575                               (match_operand:QI 2 "nonmemory_operand" "")))
10576               (clobber (reg:CC FLAGS_REG))])]
10577   ""
10578 {
10579   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10580     {
10581       emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10582       DONE;
10583     }
10584   ix86_expand_binary_operator (ASHIFT, DImode, operands);
10585   DONE;
10586 })
10587
10588 (define_insn "*ashldi3_1_rex64"
10589   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10590         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10591                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10592    (clobber (reg:CC FLAGS_REG))]
10593   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10594 {
10595   switch (get_attr_type (insn))
10596     {
10597     case TYPE_ALU:
10598       if (operands[2] != const1_rtx)
10599         abort ();
10600       if (!rtx_equal_p (operands[0], operands[1]))
10601         abort ();
10602       return "add{q}\t{%0, %0|%0, %0}";
10603
10604     case TYPE_LEA:
10605       if (GET_CODE (operands[2]) != CONST_INT
10606           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10607         abort ();
10608       operands[1] = gen_rtx_MULT (DImode, operands[1],
10609                                   GEN_INT (1 << INTVAL (operands[2])));
10610       return "lea{q}\t{%a1, %0|%0, %a1}";
10611
10612     default:
10613       if (REG_P (operands[2]))
10614         return "sal{q}\t{%b2, %0|%0, %b2}";
10615       else if (operands[2] == const1_rtx
10616                && (TARGET_SHIFT1 || optimize_size))
10617         return "sal{q}\t%0";
10618       else
10619         return "sal{q}\t{%2, %0|%0, %2}";
10620     }
10621 }
10622   [(set (attr "type")
10623      (cond [(eq_attr "alternative" "1")
10624               (const_string "lea")
10625             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10626                           (const_int 0))
10627                       (match_operand 0 "register_operand" ""))
10628                  (match_operand 2 "const1_operand" ""))
10629               (const_string "alu")
10630            ]
10631            (const_string "ishift")))
10632    (set_attr "mode" "DI")])
10633
10634 ;; Convert lea to the lea pattern to avoid flags dependency.
10635 (define_split
10636   [(set (match_operand:DI 0 "register_operand" "")
10637         (ashift:DI (match_operand:DI 1 "register_operand" "")
10638                    (match_operand:QI 2 "immediate_operand" "")))
10639    (clobber (reg:CC FLAGS_REG))]
10640   "TARGET_64BIT && reload_completed
10641    && true_regnum (operands[0]) != true_regnum (operands[1])"
10642   [(set (match_dup 0)
10643         (mult:DI (match_dup 1)
10644                  (match_dup 2)))]
10645   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10646
10647 ;; This pattern can't accept a variable shift count, since shifts by
10648 ;; zero don't affect the flags.  We assume that shifts by constant
10649 ;; zero are optimized away.
10650 (define_insn "*ashldi3_cmp_rex64"
10651   [(set (reg 17)
10652         (compare
10653           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10654                      (match_operand:QI 2 "immediate_operand" "e"))
10655           (const_int 0)))
10656    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10657         (ashift:DI (match_dup 1) (match_dup 2)))]
10658   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10659    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10660 {
10661   switch (get_attr_type (insn))
10662     {
10663     case TYPE_ALU:
10664       if (operands[2] != const1_rtx)
10665         abort ();
10666       return "add{q}\t{%0, %0|%0, %0}";
10667
10668     default:
10669       if (REG_P (operands[2]))
10670         return "sal{q}\t{%b2, %0|%0, %b2}";
10671       else if (operands[2] == const1_rtx
10672                && (TARGET_SHIFT1 || optimize_size))
10673         return "sal{q}\t%0";
10674       else
10675         return "sal{q}\t{%2, %0|%0, %2}";
10676     }
10677 }
10678   [(set (attr "type")
10679      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10680                           (const_int 0))
10681                       (match_operand 0 "register_operand" ""))
10682                  (match_operand 2 "const1_operand" ""))
10683               (const_string "alu")
10684            ]
10685            (const_string "ishift")))
10686    (set_attr "mode" "DI")])
10687
10688 (define_insn "ashldi3_1"
10689   [(set (match_operand:DI 0 "register_operand" "=r")
10690         (ashift:DI (match_operand:DI 1 "register_operand" "0")
10691                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
10692    (clobber (match_scratch:SI 3 "=&r"))
10693    (clobber (reg:CC FLAGS_REG))]
10694   "!TARGET_64BIT && TARGET_CMOVE"
10695   "#"
10696   [(set_attr "type" "multi")])
10697
10698 (define_insn "*ashldi3_2"
10699   [(set (match_operand:DI 0 "register_operand" "=r")
10700         (ashift:DI (match_operand:DI 1 "register_operand" "0")
10701                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
10702    (clobber (reg:CC FLAGS_REG))]
10703   "!TARGET_64BIT"
10704   "#"
10705   [(set_attr "type" "multi")])
10706
10707 (define_split
10708   [(set (match_operand:DI 0 "register_operand" "")
10709         (ashift:DI (match_operand:DI 1 "register_operand" "")
10710                    (match_operand:QI 2 "nonmemory_operand" "")))
10711    (clobber (match_scratch:SI 3 ""))
10712    (clobber (reg:CC FLAGS_REG))]
10713   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10714   [(const_int 0)]
10715   "ix86_split_ashldi (operands, operands[3]); DONE;")
10716
10717 (define_split
10718   [(set (match_operand:DI 0 "register_operand" "")
10719         (ashift:DI (match_operand:DI 1 "register_operand" "")
10720                    (match_operand:QI 2 "nonmemory_operand" "")))
10721    (clobber (reg:CC FLAGS_REG))]
10722   "!TARGET_64BIT && reload_completed"
10723   [(const_int 0)]
10724   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10725
10726 (define_insn "x86_shld_1"
10727   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10728         (ior:SI (ashift:SI (match_dup 0)
10729                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10730                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10731                   (minus:QI (const_int 32) (match_dup 2)))))
10732    (clobber (reg:CC FLAGS_REG))]
10733   ""
10734   "@
10735    shld{l}\t{%2, %1, %0|%0, %1, %2}
10736    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10737   [(set_attr "type" "ishift")
10738    (set_attr "prefix_0f" "1")
10739    (set_attr "mode" "SI")
10740    (set_attr "pent_pair" "np")
10741    (set_attr "athlon_decode" "vector")])
10742
10743 (define_expand "x86_shift_adj_1"
10744   [(set (reg:CCZ FLAGS_REG)
10745         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10746                              (const_int 32))
10747                      (const_int 0)))
10748    (set (match_operand:SI 0 "register_operand" "")
10749         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10750                          (match_operand:SI 1 "register_operand" "")
10751                          (match_dup 0)))
10752    (set (match_dup 1)
10753         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10754                          (match_operand:SI 3 "register_operand" "r")
10755                          (match_dup 1)))]
10756   "TARGET_CMOVE"
10757   "")
10758
10759 (define_expand "x86_shift_adj_2"
10760   [(use (match_operand:SI 0 "register_operand" ""))
10761    (use (match_operand:SI 1 "register_operand" ""))
10762    (use (match_operand:QI 2 "register_operand" ""))]
10763   ""
10764 {
10765   rtx label = gen_label_rtx ();
10766   rtx tmp;
10767
10768   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10769
10770   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10771   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10772   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10773                               gen_rtx_LABEL_REF (VOIDmode, label),
10774                               pc_rtx);
10775   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10776   JUMP_LABEL (tmp) = label;
10777
10778   emit_move_insn (operands[0], operands[1]);
10779   emit_move_insn (operands[1], const0_rtx);
10780
10781   emit_label (label);
10782   LABEL_NUSES (label) = 1;
10783
10784   DONE;
10785 })
10786
10787 (define_expand "ashlsi3"
10788   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10789         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10790                    (match_operand:QI 2 "nonmemory_operand" "")))
10791    (clobber (reg:CC FLAGS_REG))]
10792   ""
10793   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10794
10795 (define_insn "*ashlsi3_1"
10796   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10797         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10798                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10799    (clobber (reg:CC FLAGS_REG))]
10800   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10801 {
10802   switch (get_attr_type (insn))
10803     {
10804     case TYPE_ALU:
10805       if (operands[2] != const1_rtx)
10806         abort ();
10807       if (!rtx_equal_p (operands[0], operands[1]))
10808         abort ();
10809       return "add{l}\t{%0, %0|%0, %0}";
10810
10811     case TYPE_LEA:
10812       return "#";
10813
10814     default:
10815       if (REG_P (operands[2]))
10816         return "sal{l}\t{%b2, %0|%0, %b2}";
10817       else if (operands[2] == const1_rtx
10818                && (TARGET_SHIFT1 || optimize_size))
10819         return "sal{l}\t%0";
10820       else
10821         return "sal{l}\t{%2, %0|%0, %2}";
10822     }
10823 }
10824   [(set (attr "type")
10825      (cond [(eq_attr "alternative" "1")
10826               (const_string "lea")
10827             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10828                           (const_int 0))
10829                       (match_operand 0 "register_operand" ""))
10830                  (match_operand 2 "const1_operand" ""))
10831               (const_string "alu")
10832            ]
10833            (const_string "ishift")))
10834    (set_attr "mode" "SI")])
10835
10836 ;; Convert lea to the lea pattern to avoid flags dependency.
10837 (define_split
10838   [(set (match_operand 0 "register_operand" "")
10839         (ashift (match_operand 1 "index_register_operand" "")
10840                 (match_operand:QI 2 "const_int_operand" "")))
10841    (clobber (reg:CC FLAGS_REG))]
10842   "reload_completed
10843    && true_regnum (operands[0]) != true_regnum (operands[1])"
10844   [(const_int 0)]
10845 {
10846   rtx pat;
10847   operands[0] = gen_lowpart (SImode, operands[0]);
10848   operands[1] = gen_lowpart (Pmode, operands[1]);
10849   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10850   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10851   if (Pmode != SImode)
10852     pat = gen_rtx_SUBREG (SImode, pat, 0);
10853   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10854   DONE;
10855 })
10856
10857 ;; Rare case of shifting RSP is handled by generating move and shift
10858 (define_split
10859   [(set (match_operand 0 "register_operand" "")
10860         (ashift (match_operand 1 "register_operand" "")
10861                 (match_operand:QI 2 "const_int_operand" "")))
10862    (clobber (reg:CC FLAGS_REG))]
10863   "reload_completed
10864    && true_regnum (operands[0]) != true_regnum (operands[1])"
10865   [(const_int 0)]
10866 {
10867   rtx pat, clob;
10868   emit_move_insn (operands[1], operands[0]);
10869   pat = gen_rtx_SET (VOIDmode, operands[0],
10870                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10871                                      operands[0], operands[2]));
10872   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10873   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10874   DONE;
10875 })
10876
10877 (define_insn "*ashlsi3_1_zext"
10878   [(set (match_operand:DI 0 "register_operand" "=r,r")
10879         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10880                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10881    (clobber (reg:CC FLAGS_REG))]
10882   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10883 {
10884   switch (get_attr_type (insn))
10885     {
10886     case TYPE_ALU:
10887       if (operands[2] != const1_rtx)
10888         abort ();
10889       return "add{l}\t{%k0, %k0|%k0, %k0}";
10890
10891     case TYPE_LEA:
10892       return "#";
10893
10894     default:
10895       if (REG_P (operands[2]))
10896         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10897       else if (operands[2] == const1_rtx
10898                && (TARGET_SHIFT1 || optimize_size))
10899         return "sal{l}\t%k0";
10900       else
10901         return "sal{l}\t{%2, %k0|%k0, %2}";
10902     }
10903 }
10904   [(set (attr "type")
10905      (cond [(eq_attr "alternative" "1")
10906               (const_string "lea")
10907             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10908                      (const_int 0))
10909                  (match_operand 2 "const1_operand" ""))
10910               (const_string "alu")
10911            ]
10912            (const_string "ishift")))
10913    (set_attr "mode" "SI")])
10914
10915 ;; Convert lea to the lea pattern to avoid flags dependency.
10916 (define_split
10917   [(set (match_operand:DI 0 "register_operand" "")
10918         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10919                                 (match_operand:QI 2 "const_int_operand" ""))))
10920    (clobber (reg:CC FLAGS_REG))]
10921   "TARGET_64BIT && reload_completed
10922    && true_regnum (operands[0]) != true_regnum (operands[1])"
10923   [(set (match_dup 0) (zero_extend:DI
10924                         (subreg:SI (mult:SI (match_dup 1)
10925                                             (match_dup 2)) 0)))]
10926 {
10927   operands[1] = gen_lowpart (Pmode, operands[1]);
10928   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10929 })
10930
10931 ;; This pattern can't accept a variable shift count, since shifts by
10932 ;; zero don't affect the flags.  We assume that shifts by constant
10933 ;; zero are optimized away.
10934 (define_insn "*ashlsi3_cmp"
10935   [(set (reg 17)
10936         (compare
10937           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10938                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10939           (const_int 0)))
10940    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10941         (ashift:SI (match_dup 1) (match_dup 2)))]
10942   "ix86_match_ccmode (insn, CCGOCmode)
10943    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10944 {
10945   switch (get_attr_type (insn))
10946     {
10947     case TYPE_ALU:
10948       if (operands[2] != const1_rtx)
10949         abort ();
10950       return "add{l}\t{%0, %0|%0, %0}";
10951
10952     default:
10953       if (REG_P (operands[2]))
10954         return "sal{l}\t{%b2, %0|%0, %b2}";
10955       else if (operands[2] == const1_rtx
10956                && (TARGET_SHIFT1 || optimize_size))
10957         return "sal{l}\t%0";
10958       else
10959         return "sal{l}\t{%2, %0|%0, %2}";
10960     }
10961 }
10962   [(set (attr "type")
10963      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10964                           (const_int 0))
10965                       (match_operand 0 "register_operand" ""))
10966                  (match_operand 2 "const1_operand" ""))
10967               (const_string "alu")
10968            ]
10969            (const_string "ishift")))
10970    (set_attr "mode" "SI")])
10971
10972 (define_insn "*ashlsi3_cmp_zext"
10973   [(set (reg 17)
10974         (compare
10975           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10976                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
10977           (const_int 0)))
10978    (set (match_operand:DI 0 "register_operand" "=r")
10979         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10980   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10981    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10982 {
10983   switch (get_attr_type (insn))
10984     {
10985     case TYPE_ALU:
10986       if (operands[2] != const1_rtx)
10987         abort ();
10988       return "add{l}\t{%k0, %k0|%k0, %k0}";
10989
10990     default:
10991       if (REG_P (operands[2]))
10992         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10993       else if (operands[2] == const1_rtx
10994                && (TARGET_SHIFT1 || optimize_size))
10995         return "sal{l}\t%k0";
10996       else
10997         return "sal{l}\t{%2, %k0|%k0, %2}";
10998     }
10999 }
11000   [(set (attr "type")
11001      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11002                      (const_int 0))
11003                  (match_operand 2 "const1_operand" ""))
11004               (const_string "alu")
11005            ]
11006            (const_string "ishift")))
11007    (set_attr "mode" "SI")])
11008
11009 (define_expand "ashlhi3"
11010   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11011         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11012                    (match_operand:QI 2 "nonmemory_operand" "")))
11013    (clobber (reg:CC FLAGS_REG))]
11014   "TARGET_HIMODE_MATH"
11015   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11016
11017 (define_insn "*ashlhi3_1_lea"
11018   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11019         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11020                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11021    (clobber (reg:CC FLAGS_REG))]
11022   "!TARGET_PARTIAL_REG_STALL
11023    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11024 {
11025   switch (get_attr_type (insn))
11026     {
11027     case TYPE_LEA:
11028       return "#";
11029     case TYPE_ALU:
11030       if (operands[2] != const1_rtx)
11031         abort ();
11032       return "add{w}\t{%0, %0|%0, %0}";
11033
11034     default:
11035       if (REG_P (operands[2]))
11036         return "sal{w}\t{%b2, %0|%0, %b2}";
11037       else if (operands[2] == const1_rtx
11038                && (TARGET_SHIFT1 || optimize_size))
11039         return "sal{w}\t%0";
11040       else
11041         return "sal{w}\t{%2, %0|%0, %2}";
11042     }
11043 }
11044   [(set (attr "type")
11045      (cond [(eq_attr "alternative" "1")
11046               (const_string "lea")
11047             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11048                           (const_int 0))
11049                       (match_operand 0 "register_operand" ""))
11050                  (match_operand 2 "const1_operand" ""))
11051               (const_string "alu")
11052            ]
11053            (const_string "ishift")))
11054    (set_attr "mode" "HI,SI")])
11055
11056 (define_insn "*ashlhi3_1"
11057   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11058         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11059                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11060    (clobber (reg:CC FLAGS_REG))]
11061   "TARGET_PARTIAL_REG_STALL
11062    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11063 {
11064   switch (get_attr_type (insn))
11065     {
11066     case TYPE_ALU:
11067       if (operands[2] != const1_rtx)
11068         abort ();
11069       return "add{w}\t{%0, %0|%0, %0}";
11070
11071     default:
11072       if (REG_P (operands[2]))
11073         return "sal{w}\t{%b2, %0|%0, %b2}";
11074       else if (operands[2] == const1_rtx
11075                && (TARGET_SHIFT1 || optimize_size))
11076         return "sal{w}\t%0";
11077       else
11078         return "sal{w}\t{%2, %0|%0, %2}";
11079     }
11080 }
11081   [(set (attr "type")
11082      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11083                           (const_int 0))
11084                       (match_operand 0 "register_operand" ""))
11085                  (match_operand 2 "const1_operand" ""))
11086               (const_string "alu")
11087            ]
11088            (const_string "ishift")))
11089    (set_attr "mode" "HI")])
11090
11091 ;; This pattern can't accept a variable shift count, since shifts by
11092 ;; zero don't affect the flags.  We assume that shifts by constant
11093 ;; zero are optimized away.
11094 (define_insn "*ashlhi3_cmp"
11095   [(set (reg 17)
11096         (compare
11097           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11098                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11099           (const_int 0)))
11100    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11101         (ashift:HI (match_dup 1) (match_dup 2)))]
11102   "ix86_match_ccmode (insn, CCGOCmode)
11103    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11104 {
11105   switch (get_attr_type (insn))
11106     {
11107     case TYPE_ALU:
11108       if (operands[2] != const1_rtx)
11109         abort ();
11110       return "add{w}\t{%0, %0|%0, %0}";
11111
11112     default:
11113       if (REG_P (operands[2]))
11114         return "sal{w}\t{%b2, %0|%0, %b2}";
11115       else if (operands[2] == const1_rtx
11116                && (TARGET_SHIFT1 || optimize_size))
11117         return "sal{w}\t%0";
11118       else
11119         return "sal{w}\t{%2, %0|%0, %2}";
11120     }
11121 }
11122   [(set (attr "type")
11123      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11124                           (const_int 0))
11125                       (match_operand 0 "register_operand" ""))
11126                  (match_operand 2 "const1_operand" ""))
11127               (const_string "alu")
11128            ]
11129            (const_string "ishift")))
11130    (set_attr "mode" "HI")])
11131
11132 (define_expand "ashlqi3"
11133   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11134         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11135                    (match_operand:QI 2 "nonmemory_operand" "")))
11136    (clobber (reg:CC FLAGS_REG))]
11137   "TARGET_QIMODE_MATH"
11138   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11139
11140 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11141
11142 (define_insn "*ashlqi3_1_lea"
11143   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11144         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11145                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11146    (clobber (reg:CC FLAGS_REG))]
11147   "!TARGET_PARTIAL_REG_STALL
11148    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11149 {
11150   switch (get_attr_type (insn))
11151     {
11152     case TYPE_LEA:
11153       return "#";
11154     case TYPE_ALU:
11155       if (operands[2] != const1_rtx)
11156         abort ();
11157       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11158         return "add{l}\t{%k0, %k0|%k0, %k0}";
11159       else
11160         return "add{b}\t{%0, %0|%0, %0}";
11161
11162     default:
11163       if (REG_P (operands[2]))
11164         {
11165           if (get_attr_mode (insn) == MODE_SI)
11166             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11167           else
11168             return "sal{b}\t{%b2, %0|%0, %b2}";
11169         }
11170       else if (operands[2] == const1_rtx
11171                && (TARGET_SHIFT1 || optimize_size))
11172         {
11173           if (get_attr_mode (insn) == MODE_SI)
11174             return "sal{l}\t%0";
11175           else
11176             return "sal{b}\t%0";
11177         }
11178       else
11179         {
11180           if (get_attr_mode (insn) == MODE_SI)
11181             return "sal{l}\t{%2, %k0|%k0, %2}";
11182           else
11183             return "sal{b}\t{%2, %0|%0, %2}";
11184         }
11185     }
11186 }
11187   [(set (attr "type")
11188      (cond [(eq_attr "alternative" "2")
11189               (const_string "lea")
11190             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11191                           (const_int 0))
11192                       (match_operand 0 "register_operand" ""))
11193                  (match_operand 2 "const1_operand" ""))
11194               (const_string "alu")
11195            ]
11196            (const_string "ishift")))
11197    (set_attr "mode" "QI,SI,SI")])
11198
11199 (define_insn "*ashlqi3_1"
11200   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11201         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11202                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11203    (clobber (reg:CC FLAGS_REG))]
11204   "TARGET_PARTIAL_REG_STALL
11205    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11206 {
11207   switch (get_attr_type (insn))
11208     {
11209     case TYPE_ALU:
11210       if (operands[2] != const1_rtx)
11211         abort ();
11212       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11213         return "add{l}\t{%k0, %k0|%k0, %k0}";
11214       else
11215         return "add{b}\t{%0, %0|%0, %0}";
11216
11217     default:
11218       if (REG_P (operands[2]))
11219         {
11220           if (get_attr_mode (insn) == MODE_SI)
11221             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11222           else
11223             return "sal{b}\t{%b2, %0|%0, %b2}";
11224         }
11225       else if (operands[2] == const1_rtx
11226                && (TARGET_SHIFT1 || optimize_size))
11227         {
11228           if (get_attr_mode (insn) == MODE_SI)
11229             return "sal{l}\t%0";
11230           else
11231             return "sal{b}\t%0";
11232         }
11233       else
11234         {
11235           if (get_attr_mode (insn) == MODE_SI)
11236             return "sal{l}\t{%2, %k0|%k0, %2}";
11237           else
11238             return "sal{b}\t{%2, %0|%0, %2}";
11239         }
11240     }
11241 }
11242   [(set (attr "type")
11243      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11244                           (const_int 0))
11245                       (match_operand 0 "register_operand" ""))
11246                  (match_operand 2 "const1_operand" ""))
11247               (const_string "alu")
11248            ]
11249            (const_string "ishift")))
11250    (set_attr "mode" "QI,SI")])
11251
11252 ;; This pattern can't accept a variable shift count, since shifts by
11253 ;; zero don't affect the flags.  We assume that shifts by constant
11254 ;; zero are optimized away.
11255 (define_insn "*ashlqi3_cmp"
11256   [(set (reg 17)
11257         (compare
11258           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11259                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11260           (const_int 0)))
11261    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11262         (ashift:QI (match_dup 1) (match_dup 2)))]
11263   "ix86_match_ccmode (insn, CCGOCmode)
11264    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11265 {
11266   switch (get_attr_type (insn))
11267     {
11268     case TYPE_ALU:
11269       if (operands[2] != const1_rtx)
11270         abort ();
11271       return "add{b}\t{%0, %0|%0, %0}";
11272
11273     default:
11274       if (REG_P (operands[2]))
11275         return "sal{b}\t{%b2, %0|%0, %b2}";
11276       else if (operands[2] == const1_rtx
11277                && (TARGET_SHIFT1 || optimize_size))
11278         return "sal{b}\t%0";
11279       else
11280         return "sal{b}\t{%2, %0|%0, %2}";
11281     }
11282 }
11283   [(set (attr "type")
11284      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11285                           (const_int 0))
11286                       (match_operand 0 "register_operand" ""))
11287                  (match_operand 2 "const1_operand" ""))
11288               (const_string "alu")
11289            ]
11290            (const_string "ishift")))
11291    (set_attr "mode" "QI")])
11292
11293 ;; See comment above `ashldi3' about how this works.
11294
11295 (define_expand "ashrdi3"
11296   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11297                    (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11298                                 (match_operand:QI 2 "nonmemory_operand" "")))
11299               (clobber (reg:CC FLAGS_REG))])]
11300   ""
11301 {
11302   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11303     {
11304       emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11305       DONE;
11306     }
11307   ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11308   DONE;
11309 })
11310
11311 (define_insn "ashrdi3_63_rex64"
11312   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11313         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11314                      (match_operand:DI 2 "const_int_operand" "i,i")))
11315    (clobber (reg:CC FLAGS_REG))]
11316   "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11317    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11318   "@
11319    {cqto|cqo}
11320    sar{q}\t{%2, %0|%0, %2}"
11321   [(set_attr "type" "imovx,ishift")
11322    (set_attr "prefix_0f" "0,*")
11323    (set_attr "length_immediate" "0,*")
11324    (set_attr "modrm" "0,1")
11325    (set_attr "mode" "DI")])
11326
11327 (define_insn "*ashrdi3_1_one_bit_rex64"
11328   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11329         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11330                      (match_operand:QI 2 "const1_operand" "")))
11331    (clobber (reg:CC FLAGS_REG))]
11332   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11333    && (TARGET_SHIFT1 || optimize_size)"
11334   "sar{q}\t%0"
11335   [(set_attr "type" "ishift")
11336    (set (attr "length") 
11337      (if_then_else (match_operand:DI 0 "register_operand" "") 
11338         (const_string "2")
11339         (const_string "*")))])
11340
11341 (define_insn "*ashrdi3_1_rex64"
11342   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11343         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11344                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11345    (clobber (reg:CC FLAGS_REG))]
11346   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11347   "@
11348    sar{q}\t{%2, %0|%0, %2}
11349    sar{q}\t{%b2, %0|%0, %b2}"
11350   [(set_attr "type" "ishift")
11351    (set_attr "mode" "DI")])
11352
11353 ;; This pattern can't accept a variable shift count, since shifts by
11354 ;; zero don't affect the flags.  We assume that shifts by constant
11355 ;; zero are optimized away.
11356 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11357   [(set (reg 17)
11358         (compare
11359           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11360                        (match_operand:QI 2 "const1_operand" ""))
11361           (const_int 0)))
11362    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11363         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11364   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11365    && (TARGET_SHIFT1 || optimize_size)
11366    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11367   "sar{q}\t%0"
11368   [(set_attr "type" "ishift")
11369    (set (attr "length") 
11370      (if_then_else (match_operand:DI 0 "register_operand" "") 
11371         (const_string "2")
11372         (const_string "*")))])
11373
11374 ;; This pattern can't accept a variable shift count, since shifts by
11375 ;; zero don't affect the flags.  We assume that shifts by constant
11376 ;; zero are optimized away.
11377 (define_insn "*ashrdi3_cmp_rex64"
11378   [(set (reg 17)
11379         (compare
11380           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11381                        (match_operand:QI 2 "const_int_operand" "n"))
11382           (const_int 0)))
11383    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11384         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11385   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11386    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11387   "sar{q}\t{%2, %0|%0, %2}"
11388   [(set_attr "type" "ishift")
11389    (set_attr "mode" "DI")])
11390
11391
11392 (define_insn "ashrdi3_1"
11393   [(set (match_operand:DI 0 "register_operand" "=r")
11394         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11395                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11396    (clobber (match_scratch:SI 3 "=&r"))
11397    (clobber (reg:CC FLAGS_REG))]
11398   "!TARGET_64BIT && TARGET_CMOVE"
11399   "#"
11400   [(set_attr "type" "multi")])
11401
11402 (define_insn "*ashrdi3_2"
11403   [(set (match_operand:DI 0 "register_operand" "=r")
11404         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11405                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11406    (clobber (reg:CC FLAGS_REG))]
11407   "!TARGET_64BIT"
11408   "#"
11409   [(set_attr "type" "multi")])
11410
11411 (define_split
11412   [(set (match_operand:DI 0 "register_operand" "")
11413         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11414                      (match_operand:QI 2 "nonmemory_operand" "")))
11415    (clobber (match_scratch:SI 3 ""))
11416    (clobber (reg:CC FLAGS_REG))]
11417   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11418   [(const_int 0)]
11419   "ix86_split_ashrdi (operands, operands[3]); DONE;")
11420
11421 (define_split
11422   [(set (match_operand:DI 0 "register_operand" "")
11423         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11424                      (match_operand:QI 2 "nonmemory_operand" "")))
11425    (clobber (reg:CC FLAGS_REG))]
11426   "!TARGET_64BIT && reload_completed"
11427   [(const_int 0)]
11428   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11429
11430 (define_insn "x86_shrd_1"
11431   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11432         (ior:SI (ashiftrt:SI (match_dup 0)
11433                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11434                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11435                   (minus:QI (const_int 32) (match_dup 2)))))
11436    (clobber (reg:CC FLAGS_REG))]
11437   ""
11438   "@
11439    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11440    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11441   [(set_attr "type" "ishift")
11442    (set_attr "prefix_0f" "1")
11443    (set_attr "pent_pair" "np")
11444    (set_attr "mode" "SI")])
11445
11446 (define_expand "x86_shift_adj_3"
11447   [(use (match_operand:SI 0 "register_operand" ""))
11448    (use (match_operand:SI 1 "register_operand" ""))
11449    (use (match_operand:QI 2 "register_operand" ""))]
11450   ""
11451 {
11452   rtx label = gen_label_rtx ();
11453   rtx tmp;
11454
11455   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11456
11457   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11458   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11459   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11460                               gen_rtx_LABEL_REF (VOIDmode, label),
11461                               pc_rtx);
11462   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11463   JUMP_LABEL (tmp) = label;
11464
11465   emit_move_insn (operands[0], operands[1]);
11466   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11467
11468   emit_label (label);
11469   LABEL_NUSES (label) = 1;
11470
11471   DONE;
11472 })
11473
11474 (define_insn "ashrsi3_31"
11475   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11476         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11477                      (match_operand:SI 2 "const_int_operand" "i,i")))
11478    (clobber (reg:CC FLAGS_REG))]
11479   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11480    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11481   "@
11482    {cltd|cdq}
11483    sar{l}\t{%2, %0|%0, %2}"
11484   [(set_attr "type" "imovx,ishift")
11485    (set_attr "prefix_0f" "0,*")
11486    (set_attr "length_immediate" "0,*")
11487    (set_attr "modrm" "0,1")
11488    (set_attr "mode" "SI")])
11489
11490 (define_insn "*ashrsi3_31_zext"
11491   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11492         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11493                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11494    (clobber (reg:CC FLAGS_REG))]
11495   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11496    && INTVAL (operands[2]) == 31
11497    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11498   "@
11499    {cltd|cdq}
11500    sar{l}\t{%2, %k0|%k0, %2}"
11501   [(set_attr "type" "imovx,ishift")
11502    (set_attr "prefix_0f" "0,*")
11503    (set_attr "length_immediate" "0,*")
11504    (set_attr "modrm" "0,1")
11505    (set_attr "mode" "SI")])
11506
11507 (define_expand "ashrsi3"
11508   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11509         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11510                      (match_operand:QI 2 "nonmemory_operand" "")))
11511    (clobber (reg:CC FLAGS_REG))]
11512   ""
11513   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11514
11515 (define_insn "*ashrsi3_1_one_bit"
11516   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11517         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11518                      (match_operand:QI 2 "const1_operand" "")))
11519    (clobber (reg:CC FLAGS_REG))]
11520   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11521    && (TARGET_SHIFT1 || optimize_size)"
11522   "sar{l}\t%0"
11523   [(set_attr "type" "ishift")
11524    (set (attr "length") 
11525      (if_then_else (match_operand:SI 0 "register_operand" "") 
11526         (const_string "2")
11527         (const_string "*")))])
11528
11529 (define_insn "*ashrsi3_1_one_bit_zext"
11530   [(set (match_operand:DI 0 "register_operand" "=r")
11531         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11532                                      (match_operand:QI 2 "const1_operand" ""))))
11533    (clobber (reg:CC FLAGS_REG))]
11534   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11535    && (TARGET_SHIFT1 || optimize_size)"
11536   "sar{l}\t%k0"
11537   [(set_attr "type" "ishift")
11538    (set_attr "length" "2")])
11539
11540 (define_insn "*ashrsi3_1"
11541   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11542         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11543                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11544    (clobber (reg:CC FLAGS_REG))]
11545   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11546   "@
11547    sar{l}\t{%2, %0|%0, %2}
11548    sar{l}\t{%b2, %0|%0, %b2}"
11549   [(set_attr "type" "ishift")
11550    (set_attr "mode" "SI")])
11551
11552 (define_insn "*ashrsi3_1_zext"
11553   [(set (match_operand:DI 0 "register_operand" "=r,r")
11554         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11555                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11556    (clobber (reg:CC FLAGS_REG))]
11557   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11558   "@
11559    sar{l}\t{%2, %k0|%k0, %2}
11560    sar{l}\t{%b2, %k0|%k0, %b2}"
11561   [(set_attr "type" "ishift")
11562    (set_attr "mode" "SI")])
11563
11564 ;; This pattern can't accept a variable shift count, since shifts by
11565 ;; zero don't affect the flags.  We assume that shifts by constant
11566 ;; zero are optimized away.
11567 (define_insn "*ashrsi3_one_bit_cmp"
11568   [(set (reg 17)
11569         (compare
11570           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11571                        (match_operand:QI 2 "const1_operand" ""))
11572           (const_int 0)))
11573    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11574         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11575   "ix86_match_ccmode (insn, CCGOCmode)
11576    && (TARGET_SHIFT1 || optimize_size)
11577    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11578   "sar{l}\t%0"
11579   [(set_attr "type" "ishift")
11580    (set (attr "length") 
11581      (if_then_else (match_operand:SI 0 "register_operand" "") 
11582         (const_string "2")
11583         (const_string "*")))])
11584
11585 (define_insn "*ashrsi3_one_bit_cmp_zext"
11586   [(set (reg 17)
11587         (compare
11588           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11589                        (match_operand:QI 2 "const1_operand" ""))
11590           (const_int 0)))
11591    (set (match_operand:DI 0 "register_operand" "=r")
11592         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11593   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11594    && (TARGET_SHIFT1 || optimize_size)
11595    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11596   "sar{l}\t%k0"
11597   [(set_attr "type" "ishift")
11598    (set_attr "length" "2")])
11599
11600 ;; This pattern can't accept a variable shift count, since shifts by
11601 ;; zero don't affect the flags.  We assume that shifts by constant
11602 ;; zero are optimized away.
11603 (define_insn "*ashrsi3_cmp"
11604   [(set (reg 17)
11605         (compare
11606           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11607                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11608           (const_int 0)))
11609    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11610         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11611   "ix86_match_ccmode (insn, CCGOCmode)
11612    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11613   "sar{l}\t{%2, %0|%0, %2}"
11614   [(set_attr "type" "ishift")
11615    (set_attr "mode" "SI")])
11616
11617 (define_insn "*ashrsi3_cmp_zext"
11618   [(set (reg 17)
11619         (compare
11620           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11621                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11622           (const_int 0)))
11623    (set (match_operand:DI 0 "register_operand" "=r")
11624         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11625   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11626    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11627   "sar{l}\t{%2, %k0|%k0, %2}"
11628   [(set_attr "type" "ishift")
11629    (set_attr "mode" "SI")])
11630
11631 (define_expand "ashrhi3"
11632   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11633         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11634                      (match_operand:QI 2 "nonmemory_operand" "")))
11635    (clobber (reg:CC FLAGS_REG))]
11636   "TARGET_HIMODE_MATH"
11637   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11638
11639 (define_insn "*ashrhi3_1_one_bit"
11640   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11641         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11642                      (match_operand:QI 2 "const1_operand" "")))
11643    (clobber (reg:CC FLAGS_REG))]
11644   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11645    && (TARGET_SHIFT1 || optimize_size)"
11646   "sar{w}\t%0"
11647   [(set_attr "type" "ishift")
11648    (set (attr "length") 
11649      (if_then_else (match_operand 0 "register_operand" "") 
11650         (const_string "2")
11651         (const_string "*")))])
11652
11653 (define_insn "*ashrhi3_1"
11654   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11655         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11656                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11657    (clobber (reg:CC FLAGS_REG))]
11658   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11659   "@
11660    sar{w}\t{%2, %0|%0, %2}
11661    sar{w}\t{%b2, %0|%0, %b2}"
11662   [(set_attr "type" "ishift")
11663    (set_attr "mode" "HI")])
11664
11665 ;; This pattern can't accept a variable shift count, since shifts by
11666 ;; zero don't affect the flags.  We assume that shifts by constant
11667 ;; zero are optimized away.
11668 (define_insn "*ashrhi3_one_bit_cmp"
11669   [(set (reg 17)
11670         (compare
11671           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11672                        (match_operand:QI 2 "const1_operand" ""))
11673           (const_int 0)))
11674    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11675         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11676   "ix86_match_ccmode (insn, CCGOCmode)
11677    && (TARGET_SHIFT1 || optimize_size)
11678    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11679   "sar{w}\t%0"
11680   [(set_attr "type" "ishift")
11681    (set (attr "length") 
11682      (if_then_else (match_operand 0 "register_operand" "") 
11683         (const_string "2")
11684         (const_string "*")))])
11685
11686 ;; This pattern can't accept a variable shift count, since shifts by
11687 ;; zero don't affect the flags.  We assume that shifts by constant
11688 ;; zero are optimized away.
11689 (define_insn "*ashrhi3_cmp"
11690   [(set (reg 17)
11691         (compare
11692           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11693                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11694           (const_int 0)))
11695    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11696         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11697   "ix86_match_ccmode (insn, CCGOCmode)
11698    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11699   "sar{w}\t{%2, %0|%0, %2}"
11700   [(set_attr "type" "ishift")
11701    (set_attr "mode" "HI")])
11702
11703 (define_expand "ashrqi3"
11704   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11705         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11706                      (match_operand:QI 2 "nonmemory_operand" "")))
11707    (clobber (reg:CC FLAGS_REG))]
11708   "TARGET_QIMODE_MATH"
11709   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11710
11711 (define_insn "*ashrqi3_1_one_bit"
11712   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11713         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11714                      (match_operand:QI 2 "const1_operand" "")))
11715    (clobber (reg:CC FLAGS_REG))]
11716   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11717    && (TARGET_SHIFT1 || optimize_size)"
11718   "sar{b}\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 "*ashrqi3_1_one_bit_slp"
11726   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11727         (ashiftrt:QI (match_dup 0)
11728                      (match_operand:QI 1 "const1_operand" "")))
11729    (clobber (reg:CC FLAGS_REG))]
11730   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11731    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11732    && (TARGET_SHIFT1 || optimize_size)"
11733   "sar{b}\t%0"
11734   [(set_attr "type" "ishift1")
11735    (set (attr "length") 
11736      (if_then_else (match_operand 0 "register_operand" "") 
11737         (const_string "2")
11738         (const_string "*")))])
11739
11740 (define_insn "*ashrqi3_1"
11741   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11742         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11743                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11744    (clobber (reg:CC FLAGS_REG))]
11745   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11746   "@
11747    sar{b}\t{%2, %0|%0, %2}
11748    sar{b}\t{%b2, %0|%0, %b2}"
11749   [(set_attr "type" "ishift")
11750    (set_attr "mode" "QI")])
11751
11752 (define_insn "*ashrqi3_1_slp"
11753   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11754         (ashiftrt:QI (match_dup 0)
11755                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11756    (clobber (reg:CC FLAGS_REG))]
11757   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11758    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11759   "@
11760    sar{b}\t{%1, %0|%0, %1}
11761    sar{b}\t{%b1, %0|%0, %b1}"
11762   [(set_attr "type" "ishift1")
11763    (set_attr "mode" "QI")])
11764
11765 ;; This pattern can't accept a variable shift count, since shifts by
11766 ;; zero don't affect the flags.  We assume that shifts by constant
11767 ;; zero are optimized away.
11768 (define_insn "*ashrqi3_one_bit_cmp"
11769   [(set (reg 17)
11770         (compare
11771           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11772                        (match_operand:QI 2 "const1_operand" "I"))
11773           (const_int 0)))
11774    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11775         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11776   "ix86_match_ccmode (insn, CCGOCmode)
11777    && (TARGET_SHIFT1 || optimize_size)
11778    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11779   "sar{b}\t%0"
11780   [(set_attr "type" "ishift")
11781    (set (attr "length") 
11782      (if_then_else (match_operand 0 "register_operand" "") 
11783         (const_string "2")
11784         (const_string "*")))])
11785
11786 ;; This pattern can't accept a variable shift count, since shifts by
11787 ;; zero don't affect the flags.  We assume that shifts by constant
11788 ;; zero are optimized away.
11789 (define_insn "*ashrqi3_cmp"
11790   [(set (reg 17)
11791         (compare
11792           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11793                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
11794           (const_int 0)))
11795    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11796         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11797   "ix86_match_ccmode (insn, CCGOCmode)
11798    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11799   "sar{b}\t{%2, %0|%0, %2}"
11800   [(set_attr "type" "ishift")
11801    (set_attr "mode" "QI")])
11802 \f
11803 ;; Logical shift instructions
11804
11805 ;; See comment above `ashldi3' about how this works.
11806
11807 (define_expand "lshrdi3"
11808   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11809                    (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11810                                 (match_operand:QI 2 "nonmemory_operand" "")))
11811               (clobber (reg:CC FLAGS_REG))])]
11812   ""
11813 {
11814   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11815     {
11816       emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11817       DONE;
11818     }
11819   ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11820   DONE;
11821 })
11822
11823 (define_insn "*lshrdi3_1_one_bit_rex64"
11824   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11825         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11826                      (match_operand:QI 2 "const1_operand" "")))
11827    (clobber (reg:CC FLAGS_REG))]
11828   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11829    && (TARGET_SHIFT1 || optimize_size)"
11830   "shr{q}\t%0"
11831   [(set_attr "type" "ishift")
11832    (set (attr "length") 
11833      (if_then_else (match_operand:DI 0 "register_operand" "") 
11834         (const_string "2")
11835         (const_string "*")))])
11836
11837 (define_insn "*lshrdi3_1_rex64"
11838   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11839         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11840                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11841    (clobber (reg:CC FLAGS_REG))]
11842   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11843   "@
11844    shr{q}\t{%2, %0|%0, %2}
11845    shr{q}\t{%b2, %0|%0, %b2}"
11846   [(set_attr "type" "ishift")
11847    (set_attr "mode" "DI")])
11848
11849 ;; This pattern can't accept a variable shift count, since shifts by
11850 ;; zero don't affect the flags.  We assume that shifts by constant
11851 ;; zero are optimized away.
11852 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11853   [(set (reg 17)
11854         (compare
11855           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11856                        (match_operand:QI 2 "const1_operand" ""))
11857           (const_int 0)))
11858    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11859         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11860   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11861    && (TARGET_SHIFT1 || optimize_size)
11862    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11863   "shr{q}\t%0"
11864   [(set_attr "type" "ishift")
11865    (set (attr "length") 
11866      (if_then_else (match_operand:DI 0 "register_operand" "") 
11867         (const_string "2")
11868         (const_string "*")))])
11869
11870 ;; This pattern can't accept a variable shift count, since shifts by
11871 ;; zero don't affect the flags.  We assume that shifts by constant
11872 ;; zero are optimized away.
11873 (define_insn "*lshrdi3_cmp_rex64"
11874   [(set (reg 17)
11875         (compare
11876           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11877                        (match_operand:QI 2 "const_int_operand" "e"))
11878           (const_int 0)))
11879    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11880         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11881   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11882    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11883   "shr{q}\t{%2, %0|%0, %2}"
11884   [(set_attr "type" "ishift")
11885    (set_attr "mode" "DI")])
11886
11887 (define_insn "lshrdi3_1"
11888   [(set (match_operand:DI 0 "register_operand" "=r")
11889         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11890                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11891    (clobber (match_scratch:SI 3 "=&r"))
11892    (clobber (reg:CC FLAGS_REG))]
11893   "!TARGET_64BIT && TARGET_CMOVE"
11894   "#"
11895   [(set_attr "type" "multi")])
11896
11897 (define_insn "*lshrdi3_2"
11898   [(set (match_operand:DI 0 "register_operand" "=r")
11899         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11900                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11901    (clobber (reg:CC FLAGS_REG))]
11902   "!TARGET_64BIT"
11903   "#"
11904   [(set_attr "type" "multi")])
11905
11906 (define_split 
11907   [(set (match_operand:DI 0 "register_operand" "")
11908         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11909                      (match_operand:QI 2 "nonmemory_operand" "")))
11910    (clobber (match_scratch:SI 3 ""))
11911    (clobber (reg:CC FLAGS_REG))]
11912   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11913   [(const_int 0)]
11914   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11915
11916 (define_split 
11917   [(set (match_operand:DI 0 "register_operand" "")
11918         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11919                      (match_operand:QI 2 "nonmemory_operand" "")))
11920    (clobber (reg:CC FLAGS_REG))]
11921   "!TARGET_64BIT && reload_completed"
11922   [(const_int 0)]
11923   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11924
11925 (define_expand "lshrsi3"
11926   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11927         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11928                      (match_operand:QI 2 "nonmemory_operand" "")))
11929    (clobber (reg:CC FLAGS_REG))]
11930   ""
11931   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11932
11933 (define_insn "*lshrsi3_1_one_bit"
11934   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11935         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11936                      (match_operand:QI 2 "const1_operand" "")))
11937    (clobber (reg:CC FLAGS_REG))]
11938   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11939    && (TARGET_SHIFT1 || optimize_size)"
11940   "shr{l}\t%0"
11941   [(set_attr "type" "ishift")
11942    (set (attr "length") 
11943      (if_then_else (match_operand:SI 0 "register_operand" "") 
11944         (const_string "2")
11945         (const_string "*")))])
11946
11947 (define_insn "*lshrsi3_1_one_bit_zext"
11948   [(set (match_operand:DI 0 "register_operand" "=r")
11949         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11950                      (match_operand:QI 2 "const1_operand" "")))
11951    (clobber (reg:CC FLAGS_REG))]
11952   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11953    && (TARGET_SHIFT1 || optimize_size)"
11954   "shr{l}\t%k0"
11955   [(set_attr "type" "ishift")
11956    (set_attr "length" "2")])
11957
11958 (define_insn "*lshrsi3_1"
11959   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11960         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11961                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11962    (clobber (reg:CC FLAGS_REG))]
11963   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11964   "@
11965    shr{l}\t{%2, %0|%0, %2}
11966    shr{l}\t{%b2, %0|%0, %b2}"
11967   [(set_attr "type" "ishift")
11968    (set_attr "mode" "SI")])
11969
11970 (define_insn "*lshrsi3_1_zext"
11971   [(set (match_operand:DI 0 "register_operand" "=r,r")
11972         (zero_extend:DI
11973           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11974                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11975    (clobber (reg:CC FLAGS_REG))]
11976   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11977   "@
11978    shr{l}\t{%2, %k0|%k0, %2}
11979    shr{l}\t{%b2, %k0|%k0, %b2}"
11980   [(set_attr "type" "ishift")
11981    (set_attr "mode" "SI")])
11982
11983 ;; This pattern can't accept a variable shift count, since shifts by
11984 ;; zero don't affect the flags.  We assume that shifts by constant
11985 ;; zero are optimized away.
11986 (define_insn "*lshrsi3_one_bit_cmp"
11987   [(set (reg 17)
11988         (compare
11989           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11990                        (match_operand:QI 2 "const1_operand" ""))
11991           (const_int 0)))
11992    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11993         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11994   "ix86_match_ccmode (insn, CCGOCmode)
11995    && (TARGET_SHIFT1 || optimize_size)
11996    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11997   "shr{l}\t%0"
11998   [(set_attr "type" "ishift")
11999    (set (attr "length") 
12000      (if_then_else (match_operand:SI 0 "register_operand" "") 
12001         (const_string "2")
12002         (const_string "*")))])
12003
12004 (define_insn "*lshrsi3_cmp_one_bit_zext"
12005   [(set (reg 17)
12006         (compare
12007           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12008                        (match_operand:QI 2 "const1_operand" ""))
12009           (const_int 0)))
12010    (set (match_operand:DI 0 "register_operand" "=r")
12011         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12012   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12013    && (TARGET_SHIFT1 || optimize_size)
12014    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12015   "shr{l}\t%k0"
12016   [(set_attr "type" "ishift")
12017    (set_attr "length" "2")])
12018
12019 ;; This pattern can't accept a variable shift count, since shifts by
12020 ;; zero don't affect the flags.  We assume that shifts by constant
12021 ;; zero are optimized away.
12022 (define_insn "*lshrsi3_cmp"
12023   [(set (reg 17)
12024         (compare
12025           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12026                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12027           (const_int 0)))
12028    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12029         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12030   "ix86_match_ccmode (insn, CCGOCmode)
12031    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12032   "shr{l}\t{%2, %0|%0, %2}"
12033   [(set_attr "type" "ishift")
12034    (set_attr "mode" "SI")])
12035
12036 (define_insn "*lshrsi3_cmp_zext"
12037   [(set (reg 17)
12038         (compare
12039           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12040                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12041           (const_int 0)))
12042    (set (match_operand:DI 0 "register_operand" "=r")
12043         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12044   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12045    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12046   "shr{l}\t{%2, %k0|%k0, %2}"
12047   [(set_attr "type" "ishift")
12048    (set_attr "mode" "SI")])
12049
12050 (define_expand "lshrhi3"
12051   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12052         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12053                      (match_operand:QI 2 "nonmemory_operand" "")))
12054    (clobber (reg:CC FLAGS_REG))]
12055   "TARGET_HIMODE_MATH"
12056   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12057
12058 (define_insn "*lshrhi3_1_one_bit"
12059   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12060         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12061                      (match_operand:QI 2 "const1_operand" "")))
12062    (clobber (reg:CC FLAGS_REG))]
12063   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12064    && (TARGET_SHIFT1 || optimize_size)"
12065   "shr{w}\t%0"
12066   [(set_attr "type" "ishift")
12067    (set (attr "length") 
12068      (if_then_else (match_operand 0 "register_operand" "") 
12069         (const_string "2")
12070         (const_string "*")))])
12071
12072 (define_insn "*lshrhi3_1"
12073   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12074         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12075                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12076    (clobber (reg:CC FLAGS_REG))]
12077   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12078   "@
12079    shr{w}\t{%2, %0|%0, %2}
12080    shr{w}\t{%b2, %0|%0, %b2}"
12081   [(set_attr "type" "ishift")
12082    (set_attr "mode" "HI")])
12083
12084 ;; This pattern can't accept a variable shift count, since shifts by
12085 ;; zero don't affect the flags.  We assume that shifts by constant
12086 ;; zero are optimized away.
12087 (define_insn "*lshrhi3_one_bit_cmp"
12088   [(set (reg 17)
12089         (compare
12090           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12091                        (match_operand:QI 2 "const1_operand" ""))
12092           (const_int 0)))
12093    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12094         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12095   "ix86_match_ccmode (insn, CCGOCmode)
12096    && (TARGET_SHIFT1 || optimize_size)
12097    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12098   "shr{w}\t%0"
12099   [(set_attr "type" "ishift")
12100    (set (attr "length") 
12101      (if_then_else (match_operand:SI 0 "register_operand" "") 
12102         (const_string "2")
12103         (const_string "*")))])
12104
12105 ;; This pattern can't accept a variable shift count, since shifts by
12106 ;; zero don't affect the flags.  We assume that shifts by constant
12107 ;; zero are optimized away.
12108 (define_insn "*lshrhi3_cmp"
12109   [(set (reg 17)
12110         (compare
12111           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12112                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12113           (const_int 0)))
12114    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12115         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12116   "ix86_match_ccmode (insn, CCGOCmode)
12117    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12118   "shr{w}\t{%2, %0|%0, %2}"
12119   [(set_attr "type" "ishift")
12120    (set_attr "mode" "HI")])
12121
12122 (define_expand "lshrqi3"
12123   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12124         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12125                      (match_operand:QI 2 "nonmemory_operand" "")))
12126    (clobber (reg:CC FLAGS_REG))]
12127   "TARGET_QIMODE_MATH"
12128   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12129
12130 (define_insn "*lshrqi3_1_one_bit"
12131   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12132         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12133                      (match_operand:QI 2 "const1_operand" "")))
12134    (clobber (reg:CC FLAGS_REG))]
12135   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12136    && (TARGET_SHIFT1 || optimize_size)"
12137   "shr{b}\t%0"
12138   [(set_attr "type" "ishift")
12139    (set (attr "length") 
12140      (if_then_else (match_operand 0 "register_operand" "") 
12141         (const_string "2")
12142         (const_string "*")))])
12143
12144 (define_insn "*lshrqi3_1_one_bit_slp"
12145   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12146         (lshiftrt:QI (match_dup 0)
12147                      (match_operand:QI 1 "const1_operand" "")))
12148    (clobber (reg:CC FLAGS_REG))]
12149   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12150    && (TARGET_SHIFT1 || optimize_size)"
12151   "shr{b}\t%0"
12152   [(set_attr "type" "ishift1")
12153    (set (attr "length") 
12154      (if_then_else (match_operand 0 "register_operand" "") 
12155         (const_string "2")
12156         (const_string "*")))])
12157
12158 (define_insn "*lshrqi3_1"
12159   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12160         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12161                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12162    (clobber (reg:CC FLAGS_REG))]
12163   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12164   "@
12165    shr{b}\t{%2, %0|%0, %2}
12166    shr{b}\t{%b2, %0|%0, %b2}"
12167   [(set_attr "type" "ishift")
12168    (set_attr "mode" "QI")])
12169
12170 (define_insn "*lshrqi3_1_slp"
12171   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12172         (lshiftrt:QI (match_dup 0)
12173                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12174    (clobber (reg:CC FLAGS_REG))]
12175   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12176    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12177   "@
12178    shr{b}\t{%1, %0|%0, %1}
12179    shr{b}\t{%b1, %0|%0, %b1}"
12180   [(set_attr "type" "ishift1")
12181    (set_attr "mode" "QI")])
12182
12183 ;; This pattern can't accept a variable shift count, since shifts by
12184 ;; zero don't affect the flags.  We assume that shifts by constant
12185 ;; zero are optimized away.
12186 (define_insn "*lshrqi2_one_bit_cmp"
12187   [(set (reg 17)
12188         (compare
12189           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12190                        (match_operand:QI 2 "const1_operand" ""))
12191           (const_int 0)))
12192    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12193         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12194   "ix86_match_ccmode (insn, CCGOCmode)
12195    && (TARGET_SHIFT1 || optimize_size)
12196    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12197   "shr{b}\t%0"
12198   [(set_attr "type" "ishift")
12199    (set (attr "length") 
12200      (if_then_else (match_operand:SI 0 "register_operand" "") 
12201         (const_string "2")
12202         (const_string "*")))])
12203
12204 ;; This pattern can't accept a variable shift count, since shifts by
12205 ;; zero don't affect the flags.  We assume that shifts by constant
12206 ;; zero are optimized away.
12207 (define_insn "*lshrqi2_cmp"
12208   [(set (reg 17)
12209         (compare
12210           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12211                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12212           (const_int 0)))
12213    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12214         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12215   "ix86_match_ccmode (insn, CCGOCmode)
12216    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12217   "shr{b}\t{%2, %0|%0, %2}"
12218   [(set_attr "type" "ishift")
12219    (set_attr "mode" "QI")])
12220 \f
12221 ;; Rotate instructions
12222
12223 (define_expand "rotldi3"
12224   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12225         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12226                    (match_operand:QI 2 "nonmemory_operand" "")))
12227    (clobber (reg:CC FLAGS_REG))]
12228   "TARGET_64BIT"
12229   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12230
12231 (define_insn "*rotlsi3_1_one_bit_rex64"
12232   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12233         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12234                    (match_operand:QI 2 "const1_operand" "")))
12235    (clobber (reg:CC FLAGS_REG))]
12236   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12237    && (TARGET_SHIFT1 || optimize_size)"
12238   "rol{q}\t%0"
12239   [(set_attr "type" "rotate")
12240    (set (attr "length") 
12241      (if_then_else (match_operand:DI 0 "register_operand" "") 
12242         (const_string "2")
12243         (const_string "*")))])
12244
12245 (define_insn "*rotldi3_1_rex64"
12246   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12247         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12248                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12249    (clobber (reg:CC FLAGS_REG))]
12250   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12251   "@
12252    rol{q}\t{%2, %0|%0, %2}
12253    rol{q}\t{%b2, %0|%0, %b2}"
12254   [(set_attr "type" "rotate")
12255    (set_attr "mode" "DI")])
12256
12257 (define_expand "rotlsi3"
12258   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12259         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12260                    (match_operand:QI 2 "nonmemory_operand" "")))
12261    (clobber (reg:CC FLAGS_REG))]
12262   ""
12263   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12264
12265 (define_insn "*rotlsi3_1_one_bit"
12266   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12267         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12268                    (match_operand:QI 2 "const1_operand" "")))
12269    (clobber (reg:CC FLAGS_REG))]
12270   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12271    && (TARGET_SHIFT1 || optimize_size)"
12272   "rol{l}\t%0"
12273   [(set_attr "type" "rotate")
12274    (set (attr "length") 
12275      (if_then_else (match_operand:SI 0 "register_operand" "") 
12276         (const_string "2")
12277         (const_string "*")))])
12278
12279 (define_insn "*rotlsi3_1_one_bit_zext"
12280   [(set (match_operand:DI 0 "register_operand" "=r")
12281         (zero_extend:DI
12282           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12283                      (match_operand:QI 2 "const1_operand" ""))))
12284    (clobber (reg:CC FLAGS_REG))]
12285   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12286    && (TARGET_SHIFT1 || optimize_size)"
12287   "rol{l}\t%k0"
12288   [(set_attr "type" "rotate")
12289    (set_attr "length" "2")])
12290
12291 (define_insn "*rotlsi3_1"
12292   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12293         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12294                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12295    (clobber (reg:CC FLAGS_REG))]
12296   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12297   "@
12298    rol{l}\t{%2, %0|%0, %2}
12299    rol{l}\t{%b2, %0|%0, %b2}"
12300   [(set_attr "type" "rotate")
12301    (set_attr "mode" "SI")])
12302
12303 (define_insn "*rotlsi3_1_zext"
12304   [(set (match_operand:DI 0 "register_operand" "=r,r")
12305         (zero_extend:DI
12306           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12307                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12308    (clobber (reg:CC FLAGS_REG))]
12309   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12310   "@
12311    rol{l}\t{%2, %k0|%k0, %2}
12312    rol{l}\t{%b2, %k0|%k0, %b2}"
12313   [(set_attr "type" "rotate")
12314    (set_attr "mode" "SI")])
12315
12316 (define_expand "rotlhi3"
12317   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12318         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12319                    (match_operand:QI 2 "nonmemory_operand" "")))
12320    (clobber (reg:CC FLAGS_REG))]
12321   "TARGET_HIMODE_MATH"
12322   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12323
12324 (define_insn "*rotlhi3_1_one_bit"
12325   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12326         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12327                    (match_operand:QI 2 "const1_operand" "")))
12328    (clobber (reg:CC FLAGS_REG))]
12329   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12330    && (TARGET_SHIFT1 || optimize_size)"
12331   "rol{w}\t%0"
12332   [(set_attr "type" "rotate")
12333    (set (attr "length") 
12334      (if_then_else (match_operand 0 "register_operand" "") 
12335         (const_string "2")
12336         (const_string "*")))])
12337
12338 (define_insn "*rotlhi3_1"
12339   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12340         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12341                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12342    (clobber (reg:CC FLAGS_REG))]
12343   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12344   "@
12345    rol{w}\t{%2, %0|%0, %2}
12346    rol{w}\t{%b2, %0|%0, %b2}"
12347   [(set_attr "type" "rotate")
12348    (set_attr "mode" "HI")])
12349
12350 (define_expand "rotlqi3"
12351   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12352         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12353                    (match_operand:QI 2 "nonmemory_operand" "")))
12354    (clobber (reg:CC FLAGS_REG))]
12355   "TARGET_QIMODE_MATH"
12356   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12357
12358 (define_insn "*rotlqi3_1_one_bit_slp"
12359   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12360         (rotate:QI (match_dup 0)
12361                    (match_operand:QI 1 "const1_operand" "")))
12362    (clobber (reg:CC FLAGS_REG))]
12363   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12364    && (TARGET_SHIFT1 || optimize_size)"
12365   "rol{b}\t%0"
12366   [(set_attr "type" "rotate1")
12367    (set (attr "length") 
12368      (if_then_else (match_operand 0 "register_operand" "") 
12369         (const_string "2")
12370         (const_string "*")))])
12371
12372 (define_insn "*rotlqi3_1_one_bit"
12373   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12374         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12375                    (match_operand:QI 2 "const1_operand" "")))
12376    (clobber (reg:CC FLAGS_REG))]
12377   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12378    && (TARGET_SHIFT1 || optimize_size)"
12379   "rol{b}\t%0"
12380   [(set_attr "type" "rotate")
12381    (set (attr "length") 
12382      (if_then_else (match_operand 0 "register_operand" "") 
12383         (const_string "2")
12384         (const_string "*")))])
12385
12386 (define_insn "*rotlqi3_1_slp"
12387   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12388         (rotate:QI (match_dup 0)
12389                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12390    (clobber (reg:CC FLAGS_REG))]
12391   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12392    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12393   "@
12394    rol{b}\t{%1, %0|%0, %1}
12395    rol{b}\t{%b1, %0|%0, %b1}"
12396   [(set_attr "type" "rotate1")
12397    (set_attr "mode" "QI")])
12398
12399 (define_insn "*rotlqi3_1"
12400   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12401         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12402                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12403    (clobber (reg:CC FLAGS_REG))]
12404   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12405   "@
12406    rol{b}\t{%2, %0|%0, %2}
12407    rol{b}\t{%b2, %0|%0, %b2}"
12408   [(set_attr "type" "rotate")
12409    (set_attr "mode" "QI")])
12410
12411 (define_expand "rotrdi3"
12412   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12413         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12414                      (match_operand:QI 2 "nonmemory_operand" "")))
12415    (clobber (reg:CC FLAGS_REG))]
12416   "TARGET_64BIT"
12417   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12418
12419 (define_insn "*rotrdi3_1_one_bit_rex64"
12420   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12421         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12422                      (match_operand:QI 2 "const1_operand" "")))
12423    (clobber (reg:CC FLAGS_REG))]
12424   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12425    && (TARGET_SHIFT1 || optimize_size)"
12426   "ror{q}\t%0"
12427   [(set_attr "type" "rotate")
12428    (set (attr "length") 
12429      (if_then_else (match_operand:DI 0 "register_operand" "") 
12430         (const_string "2")
12431         (const_string "*")))])
12432
12433 (define_insn "*rotrdi3_1_rex64"
12434   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12435         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12436                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12437    (clobber (reg:CC FLAGS_REG))]
12438   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12439   "@
12440    ror{q}\t{%2, %0|%0, %2}
12441    ror{q}\t{%b2, %0|%0, %b2}"
12442   [(set_attr "type" "rotate")
12443    (set_attr "mode" "DI")])
12444
12445 (define_expand "rotrsi3"
12446   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12447         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12448                      (match_operand:QI 2 "nonmemory_operand" "")))
12449    (clobber (reg:CC FLAGS_REG))]
12450   ""
12451   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12452
12453 (define_insn "*rotrsi3_1_one_bit"
12454   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12455         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12456                      (match_operand:QI 2 "const1_operand" "")))
12457    (clobber (reg:CC FLAGS_REG))]
12458   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12459    && (TARGET_SHIFT1 || optimize_size)"
12460   "ror{l}\t%0"
12461   [(set_attr "type" "rotate")
12462    (set (attr "length") 
12463      (if_then_else (match_operand:SI 0 "register_operand" "") 
12464         (const_string "2")
12465         (const_string "*")))])
12466
12467 (define_insn "*rotrsi3_1_one_bit_zext"
12468   [(set (match_operand:DI 0 "register_operand" "=r")
12469         (zero_extend:DI
12470           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12471                        (match_operand:QI 2 "const1_operand" ""))))
12472    (clobber (reg:CC FLAGS_REG))]
12473   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12474    && (TARGET_SHIFT1 || optimize_size)"
12475   "ror{l}\t%k0"
12476   [(set_attr "type" "rotate")
12477    (set (attr "length") 
12478      (if_then_else (match_operand:SI 0 "register_operand" "") 
12479         (const_string "2")
12480         (const_string "*")))])
12481
12482 (define_insn "*rotrsi3_1"
12483   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12484         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12485                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12486    (clobber (reg:CC FLAGS_REG))]
12487   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12488   "@
12489    ror{l}\t{%2, %0|%0, %2}
12490    ror{l}\t{%b2, %0|%0, %b2}"
12491   [(set_attr "type" "rotate")
12492    (set_attr "mode" "SI")])
12493
12494 (define_insn "*rotrsi3_1_zext"
12495   [(set (match_operand:DI 0 "register_operand" "=r,r")
12496         (zero_extend:DI
12497           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12498                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12499    (clobber (reg:CC FLAGS_REG))]
12500   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12501   "@
12502    ror{l}\t{%2, %k0|%k0, %2}
12503    ror{l}\t{%b2, %k0|%k0, %b2}"
12504   [(set_attr "type" "rotate")
12505    (set_attr "mode" "SI")])
12506
12507 (define_expand "rotrhi3"
12508   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12509         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12510                      (match_operand:QI 2 "nonmemory_operand" "")))
12511    (clobber (reg:CC FLAGS_REG))]
12512   "TARGET_HIMODE_MATH"
12513   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12514
12515 (define_insn "*rotrhi3_one_bit"
12516   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12517         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12518                      (match_operand:QI 2 "const1_operand" "")))
12519    (clobber (reg:CC FLAGS_REG))]
12520   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12521    && (TARGET_SHIFT1 || optimize_size)"
12522   "ror{w}\t%0"
12523   [(set_attr "type" "rotate")
12524    (set (attr "length") 
12525      (if_then_else (match_operand 0 "register_operand" "") 
12526         (const_string "2")
12527         (const_string "*")))])
12528
12529 (define_insn "*rotrhi3"
12530   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12531         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12532                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12533    (clobber (reg:CC FLAGS_REG))]
12534   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12535   "@
12536    ror{w}\t{%2, %0|%0, %2}
12537    ror{w}\t{%b2, %0|%0, %b2}"
12538   [(set_attr "type" "rotate")
12539    (set_attr "mode" "HI")])
12540
12541 (define_expand "rotrqi3"
12542   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12543         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12544                      (match_operand:QI 2 "nonmemory_operand" "")))
12545    (clobber (reg:CC FLAGS_REG))]
12546   "TARGET_QIMODE_MATH"
12547   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12548
12549 (define_insn "*rotrqi3_1_one_bit"
12550   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12551         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12552                      (match_operand:QI 2 "const1_operand" "")))
12553    (clobber (reg:CC FLAGS_REG))]
12554   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12555    && (TARGET_SHIFT1 || optimize_size)"
12556   "ror{b}\t%0"
12557   [(set_attr "type" "rotate")
12558    (set (attr "length") 
12559      (if_then_else (match_operand 0 "register_operand" "") 
12560         (const_string "2")
12561         (const_string "*")))])
12562
12563 (define_insn "*rotrqi3_1_one_bit_slp"
12564   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12565         (rotatert:QI (match_dup 0)
12566                      (match_operand:QI 1 "const1_operand" "")))
12567    (clobber (reg:CC FLAGS_REG))]
12568   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12569    && (TARGET_SHIFT1 || optimize_size)"
12570   "ror{b}\t%0"
12571   [(set_attr "type" "rotate1")
12572    (set (attr "length") 
12573      (if_then_else (match_operand 0 "register_operand" "") 
12574         (const_string "2")
12575         (const_string "*")))])
12576
12577 (define_insn "*rotrqi3_1"
12578   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12579         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12580                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12581    (clobber (reg:CC FLAGS_REG))]
12582   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12583   "@
12584    ror{b}\t{%2, %0|%0, %2}
12585    ror{b}\t{%b2, %0|%0, %b2}"
12586   [(set_attr "type" "rotate")
12587    (set_attr "mode" "QI")])
12588
12589 (define_insn "*rotrqi3_1_slp"
12590   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12591         (rotatert:QI (match_dup 0)
12592                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12593    (clobber (reg:CC FLAGS_REG))]
12594   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12595    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12596   "@
12597    ror{b}\t{%1, %0|%0, %1}
12598    ror{b}\t{%b1, %0|%0, %b1}"
12599   [(set_attr "type" "rotate1")
12600    (set_attr "mode" "QI")])
12601 \f
12602 ;; Bit set / bit test instructions
12603
12604 (define_expand "extv"
12605   [(set (match_operand:SI 0 "register_operand" "")
12606         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12607                          (match_operand:SI 2 "immediate_operand" "")
12608                          (match_operand:SI 3 "immediate_operand" "")))]
12609   ""
12610 {
12611   /* Handle extractions from %ah et al.  */
12612   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12613     FAIL;
12614
12615   /* From mips.md: extract_bit_field doesn't verify that our source
12616      matches the predicate, so check it again here.  */
12617   if (! register_operand (operands[1], VOIDmode))
12618     FAIL;
12619 })
12620
12621 (define_expand "extzv"
12622   [(set (match_operand:SI 0 "register_operand" "")
12623         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12624                          (match_operand:SI 2 "immediate_operand" "")
12625                          (match_operand:SI 3 "immediate_operand" "")))]
12626   ""
12627 {
12628   /* Handle extractions from %ah et al.  */
12629   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12630     FAIL;
12631
12632   /* From mips.md: extract_bit_field doesn't verify that our source
12633      matches the predicate, so check it again here.  */
12634   if (! register_operand (operands[1], VOIDmode))
12635     FAIL;
12636 })
12637
12638 (define_expand "insv"
12639   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12640                       (match_operand 1 "immediate_operand" "")
12641                       (match_operand 2 "immediate_operand" ""))
12642         (match_operand 3 "register_operand" ""))]
12643   ""
12644 {
12645   /* Handle extractions from %ah et al.  */
12646   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12647     FAIL;
12648
12649   /* From mips.md: insert_bit_field doesn't verify that our source
12650      matches the predicate, so check it again here.  */
12651   if (! register_operand (operands[0], VOIDmode))
12652     FAIL;
12653
12654   if (TARGET_64BIT)
12655     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12656   else
12657     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12658
12659   DONE;
12660 })
12661
12662 ;; %%% bts, btr, btc, bt.
12663 \f
12664 ;; Store-flag instructions.
12665
12666 ;; For all sCOND expanders, also expand the compare or test insn that
12667 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12668
12669 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12670 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12671 ;; way, which can later delete the movzx if only QImode is needed.
12672
12673 (define_expand "seq"
12674   [(set (match_operand:QI 0 "register_operand" "")
12675         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12676   ""
12677   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12678
12679 (define_expand "sne"
12680   [(set (match_operand:QI 0 "register_operand" "")
12681         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12682   ""
12683   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12684
12685 (define_expand "sgt"
12686   [(set (match_operand:QI 0 "register_operand" "")
12687         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12688   ""
12689   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12690
12691 (define_expand "sgtu"
12692   [(set (match_operand:QI 0 "register_operand" "")
12693         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12694   ""
12695   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12696
12697 (define_expand "slt"
12698   [(set (match_operand:QI 0 "register_operand" "")
12699         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12700   ""
12701   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12702
12703 (define_expand "sltu"
12704   [(set (match_operand:QI 0 "register_operand" "")
12705         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12706   ""
12707   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12708
12709 (define_expand "sge"
12710   [(set (match_operand:QI 0 "register_operand" "")
12711         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12712   ""
12713   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12714
12715 (define_expand "sgeu"
12716   [(set (match_operand:QI 0 "register_operand" "")
12717         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12718   ""
12719   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12720
12721 (define_expand "sle"
12722   [(set (match_operand:QI 0 "register_operand" "")
12723         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12724   ""
12725   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12726
12727 (define_expand "sleu"
12728   [(set (match_operand:QI 0 "register_operand" "")
12729         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12730   ""
12731   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12732
12733 (define_expand "sunordered"
12734   [(set (match_operand:QI 0 "register_operand" "")
12735         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12736   "TARGET_80387 || TARGET_SSE"
12737   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12738
12739 (define_expand "sordered"
12740   [(set (match_operand:QI 0 "register_operand" "")
12741         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12742   "TARGET_80387"
12743   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12744
12745 (define_expand "suneq"
12746   [(set (match_operand:QI 0 "register_operand" "")
12747         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12748   "TARGET_80387 || TARGET_SSE"
12749   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12750
12751 (define_expand "sunge"
12752   [(set (match_operand:QI 0 "register_operand" "")
12753         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12754   "TARGET_80387 || TARGET_SSE"
12755   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12756
12757 (define_expand "sungt"
12758   [(set (match_operand:QI 0 "register_operand" "")
12759         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12760   "TARGET_80387 || TARGET_SSE"
12761   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12762
12763 (define_expand "sunle"
12764   [(set (match_operand:QI 0 "register_operand" "")
12765         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12766   "TARGET_80387 || TARGET_SSE"
12767   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12768
12769 (define_expand "sunlt"
12770   [(set (match_operand:QI 0 "register_operand" "")
12771         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12772   "TARGET_80387 || TARGET_SSE"
12773   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12774
12775 (define_expand "sltgt"
12776   [(set (match_operand:QI 0 "register_operand" "")
12777         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12778   "TARGET_80387 || TARGET_SSE"
12779   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12780
12781 (define_insn "*setcc_1"
12782   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12783         (match_operator:QI 1 "ix86_comparison_operator"
12784           [(reg 17) (const_int 0)]))]
12785   ""
12786   "set%C1\t%0"
12787   [(set_attr "type" "setcc")
12788    (set_attr "mode" "QI")])
12789
12790 (define_insn "setcc_2"
12791   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12792         (match_operator:QI 1 "ix86_comparison_operator"
12793           [(reg 17) (const_int 0)]))]
12794   ""
12795   "set%C1\t%0"
12796   [(set_attr "type" "setcc")
12797    (set_attr "mode" "QI")])
12798
12799 ;; In general it is not safe to assume too much about CCmode registers,
12800 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12801 ;; conditions this is safe on x86, so help combine not create
12802 ;;
12803 ;;      seta    %al
12804 ;;      testb   %al, %al
12805 ;;      sete    %al
12806
12807 (define_split 
12808   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12809         (ne:QI (match_operator 1 "ix86_comparison_operator"
12810                  [(reg 17) (const_int 0)])
12811             (const_int 0)))]
12812   ""
12813   [(set (match_dup 0) (match_dup 1))]
12814 {
12815   PUT_MODE (operands[1], QImode);
12816 })
12817
12818 (define_split 
12819   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12820         (ne:QI (match_operator 1 "ix86_comparison_operator"
12821                  [(reg 17) (const_int 0)])
12822             (const_int 0)))]
12823   ""
12824   [(set (match_dup 0) (match_dup 1))]
12825 {
12826   PUT_MODE (operands[1], QImode);
12827 })
12828
12829 (define_split 
12830   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12831         (eq:QI (match_operator 1 "ix86_comparison_operator"
12832                  [(reg 17) (const_int 0)])
12833             (const_int 0)))]
12834   ""
12835   [(set (match_dup 0) (match_dup 1))]
12836 {
12837   rtx new_op1 = copy_rtx (operands[1]);
12838   operands[1] = new_op1;
12839   PUT_MODE (new_op1, QImode);
12840   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12841                                              GET_MODE (XEXP (new_op1, 0))));
12842
12843   /* Make sure that (a) the CCmode we have for the flags is strong
12844      enough for the reversed compare or (b) we have a valid FP compare.  */
12845   if (! ix86_comparison_operator (new_op1, VOIDmode))
12846     FAIL;
12847 })
12848
12849 (define_split 
12850   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12851         (eq:QI (match_operator 1 "ix86_comparison_operator"
12852                  [(reg 17) (const_int 0)])
12853             (const_int 0)))]
12854   ""
12855   [(set (match_dup 0) (match_dup 1))]
12856 {
12857   rtx new_op1 = copy_rtx (operands[1]);
12858   operands[1] = new_op1;
12859   PUT_MODE (new_op1, QImode);
12860   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12861                                              GET_MODE (XEXP (new_op1, 0))));
12862
12863   /* Make sure that (a) the CCmode we have for the flags is strong
12864      enough for the reversed compare or (b) we have a valid FP compare.  */
12865   if (! ix86_comparison_operator (new_op1, VOIDmode))
12866     FAIL;
12867 })
12868
12869 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12870 ;; subsequent logical operations are used to imitate conditional moves.
12871 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12872 ;; it directly.  Further holding this value in pseudo register might bring
12873 ;; problem in implicit normalization in spill code.
12874 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12875 ;; instructions after reload by splitting the conditional move patterns.
12876
12877 (define_insn "*sse_setccsf"
12878   [(set (match_operand:SF 0 "register_operand" "=x")
12879         (match_operator:SF 1 "sse_comparison_operator"
12880           [(match_operand:SF 2 "register_operand" "0")
12881            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12882   "TARGET_SSE && reload_completed"
12883   "cmp%D1ss\t{%3, %0|%0, %3}"
12884   [(set_attr "type" "ssecmp")
12885    (set_attr "mode" "SF")])
12886
12887 (define_insn "*sse_setccdf"
12888   [(set (match_operand:DF 0 "register_operand" "=Y")
12889         (match_operator:DF 1 "sse_comparison_operator"
12890           [(match_operand:DF 2 "register_operand" "0")
12891            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12892   "TARGET_SSE2 && reload_completed"
12893   "cmp%D1sd\t{%3, %0|%0, %3}"
12894   [(set_attr "type" "ssecmp")
12895    (set_attr "mode" "DF")])
12896 \f
12897 ;; Basic conditional jump instructions.
12898 ;; We ignore the overflow flag for signed branch instructions.
12899
12900 ;; For all bCOND expanders, also expand the compare or test insn that
12901 ;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
12902
12903 (define_expand "beq"
12904   [(set (pc)
12905         (if_then_else (match_dup 1)
12906                       (label_ref (match_operand 0 "" ""))
12907                       (pc)))]
12908   ""
12909   "ix86_expand_branch (EQ, operands[0]); DONE;")
12910
12911 (define_expand "bne"
12912   [(set (pc)
12913         (if_then_else (match_dup 1)
12914                       (label_ref (match_operand 0 "" ""))
12915                       (pc)))]
12916   ""
12917   "ix86_expand_branch (NE, operands[0]); DONE;")
12918
12919 (define_expand "bgt"
12920   [(set (pc)
12921         (if_then_else (match_dup 1)
12922                       (label_ref (match_operand 0 "" ""))
12923                       (pc)))]
12924   ""
12925   "ix86_expand_branch (GT, operands[0]); DONE;")
12926
12927 (define_expand "bgtu"
12928   [(set (pc)
12929         (if_then_else (match_dup 1)
12930                       (label_ref (match_operand 0 "" ""))
12931                       (pc)))]
12932   ""
12933   "ix86_expand_branch (GTU, operands[0]); DONE;")
12934
12935 (define_expand "blt"
12936   [(set (pc)
12937         (if_then_else (match_dup 1)
12938                       (label_ref (match_operand 0 "" ""))
12939                       (pc)))]
12940   ""
12941   "ix86_expand_branch (LT, operands[0]); DONE;")
12942
12943 (define_expand "bltu"
12944   [(set (pc)
12945         (if_then_else (match_dup 1)
12946                       (label_ref (match_operand 0 "" ""))
12947                       (pc)))]
12948   ""
12949   "ix86_expand_branch (LTU, operands[0]); DONE;")
12950
12951 (define_expand "bge"
12952   [(set (pc)
12953         (if_then_else (match_dup 1)
12954                       (label_ref (match_operand 0 "" ""))
12955                       (pc)))]
12956   ""
12957   "ix86_expand_branch (GE, operands[0]); DONE;")
12958
12959 (define_expand "bgeu"
12960   [(set (pc)
12961         (if_then_else (match_dup 1)
12962                       (label_ref (match_operand 0 "" ""))
12963                       (pc)))]
12964   ""
12965   "ix86_expand_branch (GEU, operands[0]); DONE;")
12966
12967 (define_expand "ble"
12968   [(set (pc)
12969         (if_then_else (match_dup 1)
12970                       (label_ref (match_operand 0 "" ""))
12971                       (pc)))]
12972   ""
12973   "ix86_expand_branch (LE, operands[0]); DONE;")
12974
12975 (define_expand "bleu"
12976   [(set (pc)
12977         (if_then_else (match_dup 1)
12978                       (label_ref (match_operand 0 "" ""))
12979                       (pc)))]
12980   ""
12981   "ix86_expand_branch (LEU, operands[0]); DONE;")
12982
12983 (define_expand "bunordered"
12984   [(set (pc)
12985         (if_then_else (match_dup 1)
12986                       (label_ref (match_operand 0 "" ""))
12987                       (pc)))]
12988   "TARGET_80387 || TARGET_SSE"
12989   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12990
12991 (define_expand "bordered"
12992   [(set (pc)
12993         (if_then_else (match_dup 1)
12994                       (label_ref (match_operand 0 "" ""))
12995                       (pc)))]
12996   "TARGET_80387 || TARGET_SSE"
12997   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12998
12999 (define_expand "buneq"
13000   [(set (pc)
13001         (if_then_else (match_dup 1)
13002                       (label_ref (match_operand 0 "" ""))
13003                       (pc)))]
13004   "TARGET_80387 || TARGET_SSE"
13005   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13006
13007 (define_expand "bunge"
13008   [(set (pc)
13009         (if_then_else (match_dup 1)
13010                       (label_ref (match_operand 0 "" ""))
13011                       (pc)))]
13012   "TARGET_80387 || TARGET_SSE"
13013   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13014
13015 (define_expand "bungt"
13016   [(set (pc)
13017         (if_then_else (match_dup 1)
13018                       (label_ref (match_operand 0 "" ""))
13019                       (pc)))]
13020   "TARGET_80387 || TARGET_SSE"
13021   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13022
13023 (define_expand "bunle"
13024   [(set (pc)
13025         (if_then_else (match_dup 1)
13026                       (label_ref (match_operand 0 "" ""))
13027                       (pc)))]
13028   "TARGET_80387 || TARGET_SSE"
13029   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13030
13031 (define_expand "bunlt"
13032   [(set (pc)
13033         (if_then_else (match_dup 1)
13034                       (label_ref (match_operand 0 "" ""))
13035                       (pc)))]
13036   "TARGET_80387 || TARGET_SSE"
13037   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13038
13039 (define_expand "bltgt"
13040   [(set (pc)
13041         (if_then_else (match_dup 1)
13042                       (label_ref (match_operand 0 "" ""))
13043                       (pc)))]
13044   "TARGET_80387 || TARGET_SSE"
13045   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13046
13047 (define_insn "*jcc_1"
13048   [(set (pc)
13049         (if_then_else (match_operator 1 "ix86_comparison_operator"
13050                                       [(reg 17) (const_int 0)])
13051                       (label_ref (match_operand 0 "" ""))
13052                       (pc)))]
13053   ""
13054   "%+j%C1\t%l0"
13055   [(set_attr "type" "ibr")
13056    (set_attr "modrm" "0")
13057    (set (attr "length")
13058            (if_then_else (and (ge (minus (match_dup 0) (pc))
13059                                   (const_int -126))
13060                               (lt (minus (match_dup 0) (pc))
13061                                   (const_int 128)))
13062              (const_int 2)
13063              (const_int 6)))])
13064
13065 (define_insn "*jcc_2"
13066   [(set (pc)
13067         (if_then_else (match_operator 1 "ix86_comparison_operator"
13068                                       [(reg 17) (const_int 0)])
13069                       (pc)
13070                       (label_ref (match_operand 0 "" ""))))]
13071   ""
13072   "%+j%c1\t%l0"
13073   [(set_attr "type" "ibr")
13074    (set_attr "modrm" "0")
13075    (set (attr "length")
13076            (if_then_else (and (ge (minus (match_dup 0) (pc))
13077                                   (const_int -126))
13078                               (lt (minus (match_dup 0) (pc))
13079                                   (const_int 128)))
13080              (const_int 2)
13081              (const_int 6)))])
13082
13083 ;; In general it is not safe to assume too much about CCmode registers,
13084 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13085 ;; conditions this is safe on x86, so help combine not create
13086 ;;
13087 ;;      seta    %al
13088 ;;      testb   %al, %al
13089 ;;      je      Lfoo
13090
13091 (define_split 
13092   [(set (pc)
13093         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13094                                       [(reg 17) (const_int 0)])
13095                           (const_int 0))
13096                       (label_ref (match_operand 1 "" ""))
13097                       (pc)))]
13098   ""
13099   [(set (pc)
13100         (if_then_else (match_dup 0)
13101                       (label_ref (match_dup 1))
13102                       (pc)))]
13103 {
13104   PUT_MODE (operands[0], VOIDmode);
13105 })
13106   
13107 (define_split 
13108   [(set (pc)
13109         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13110                                       [(reg 17) (const_int 0)])
13111                           (const_int 0))
13112                       (label_ref (match_operand 1 "" ""))
13113                       (pc)))]
13114   ""
13115   [(set (pc)
13116         (if_then_else (match_dup 0)
13117                       (label_ref (match_dup 1))
13118                       (pc)))]
13119 {
13120   rtx new_op0 = copy_rtx (operands[0]);
13121   operands[0] = new_op0;
13122   PUT_MODE (new_op0, VOIDmode);
13123   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13124                                              GET_MODE (XEXP (new_op0, 0))));
13125
13126   /* Make sure that (a) the CCmode we have for the flags is strong
13127      enough for the reversed compare or (b) we have a valid FP compare.  */
13128   if (! ix86_comparison_operator (new_op0, VOIDmode))
13129     FAIL;
13130 })
13131
13132 ;; Define combination compare-and-branch fp compare instructions to use
13133 ;; during early optimization.  Splitting the operation apart early makes
13134 ;; for bad code when we want to reverse the operation.
13135
13136 (define_insn "*fp_jcc_1"
13137   [(set (pc)
13138         (if_then_else (match_operator 0 "comparison_operator"
13139                         [(match_operand 1 "register_operand" "f")
13140                          (match_operand 2 "register_operand" "f")])
13141           (label_ref (match_operand 3 "" ""))
13142           (pc)))
13143    (clobber (reg:CCFP FPSR_REG))
13144    (clobber (reg:CCFP FLAGS_REG))]
13145   "TARGET_CMOVE && TARGET_80387
13146    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13147    && FLOAT_MODE_P (GET_MODE (operands[1]))
13148    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13149    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13150   "#")
13151
13152 (define_insn "*fp_jcc_1_sse"
13153   [(set (pc)
13154         (if_then_else (match_operator 0 "comparison_operator"
13155                         [(match_operand 1 "register_operand" "f#x,x#f")
13156                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13157           (label_ref (match_operand 3 "" ""))
13158           (pc)))
13159    (clobber (reg:CCFP FPSR_REG))
13160    (clobber (reg:CCFP FLAGS_REG))]
13161   "TARGET_80387
13162    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13163    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13164    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13165   "#")
13166
13167 (define_insn "*fp_jcc_1_sse_only"
13168   [(set (pc)
13169         (if_then_else (match_operator 0 "comparison_operator"
13170                         [(match_operand 1 "register_operand" "x")
13171                          (match_operand 2 "nonimmediate_operand" "xm")])
13172           (label_ref (match_operand 3 "" ""))
13173           (pc)))
13174    (clobber (reg:CCFP FPSR_REG))
13175    (clobber (reg:CCFP FLAGS_REG))]
13176   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13177    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13178    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13179   "#")
13180
13181 (define_insn "*fp_jcc_2"
13182   [(set (pc)
13183         (if_then_else (match_operator 0 "comparison_operator"
13184                         [(match_operand 1 "register_operand" "f")
13185                          (match_operand 2 "register_operand" "f")])
13186           (pc)
13187           (label_ref (match_operand 3 "" ""))))
13188    (clobber (reg:CCFP FPSR_REG))
13189    (clobber (reg:CCFP FLAGS_REG))]
13190   "TARGET_CMOVE && TARGET_80387
13191    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13192    && FLOAT_MODE_P (GET_MODE (operands[1]))
13193    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13194    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13195   "#")
13196
13197 (define_insn "*fp_jcc_2_sse"
13198   [(set (pc)
13199         (if_then_else (match_operator 0 "comparison_operator"
13200                         [(match_operand 1 "register_operand" "f#x,x#f")
13201                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13202           (pc)
13203           (label_ref (match_operand 3 "" ""))))
13204    (clobber (reg:CCFP FPSR_REG))
13205    (clobber (reg:CCFP FLAGS_REG))]
13206   "TARGET_80387
13207    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13208    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13209    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13210   "#")
13211
13212 (define_insn "*fp_jcc_2_sse_only"
13213   [(set (pc)
13214         (if_then_else (match_operator 0 "comparison_operator"
13215                         [(match_operand 1 "register_operand" "x")
13216                          (match_operand 2 "nonimmediate_operand" "xm")])
13217           (pc)
13218           (label_ref (match_operand 3 "" ""))))
13219    (clobber (reg:CCFP FPSR_REG))
13220    (clobber (reg:CCFP FLAGS_REG))]
13221   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13222    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13223    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13224   "#")
13225
13226 (define_insn "*fp_jcc_3"
13227   [(set (pc)
13228         (if_then_else (match_operator 0 "comparison_operator"
13229                         [(match_operand 1 "register_operand" "f")
13230                          (match_operand 2 "nonimmediate_operand" "fm")])
13231           (label_ref (match_operand 3 "" ""))
13232           (pc)))
13233    (clobber (reg:CCFP FPSR_REG))
13234    (clobber (reg:CCFP FLAGS_REG))
13235    (clobber (match_scratch:HI 4 "=a"))]
13236   "TARGET_80387
13237    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13238    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13239    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13240    && SELECT_CC_MODE (GET_CODE (operands[0]),
13241                       operands[1], operands[2]) == CCFPmode
13242    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13243   "#")
13244
13245 (define_insn "*fp_jcc_4"
13246   [(set (pc)
13247         (if_then_else (match_operator 0 "comparison_operator"
13248                         [(match_operand 1 "register_operand" "f")
13249                          (match_operand 2 "nonimmediate_operand" "fm")])
13250           (pc)
13251           (label_ref (match_operand 3 "" ""))))
13252    (clobber (reg:CCFP FPSR_REG))
13253    (clobber (reg:CCFP FLAGS_REG))
13254    (clobber (match_scratch:HI 4 "=a"))]
13255   "TARGET_80387
13256    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13257    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13258    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13259    && SELECT_CC_MODE (GET_CODE (operands[0]),
13260                       operands[1], operands[2]) == CCFPmode
13261    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13262   "#")
13263
13264 (define_insn "*fp_jcc_5"
13265   [(set (pc)
13266         (if_then_else (match_operator 0 "comparison_operator"
13267                         [(match_operand 1 "register_operand" "f")
13268                          (match_operand 2 "register_operand" "f")])
13269           (label_ref (match_operand 3 "" ""))
13270           (pc)))
13271    (clobber (reg:CCFP FPSR_REG))
13272    (clobber (reg:CCFP FLAGS_REG))
13273    (clobber (match_scratch:HI 4 "=a"))]
13274   "TARGET_80387
13275    && FLOAT_MODE_P (GET_MODE (operands[1]))
13276    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13277    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13278   "#")
13279
13280 (define_insn "*fp_jcc_6"
13281   [(set (pc)
13282         (if_then_else (match_operator 0 "comparison_operator"
13283                         [(match_operand 1 "register_operand" "f")
13284                          (match_operand 2 "register_operand" "f")])
13285           (pc)
13286           (label_ref (match_operand 3 "" ""))))
13287    (clobber (reg:CCFP FPSR_REG))
13288    (clobber (reg:CCFP FLAGS_REG))
13289    (clobber (match_scratch:HI 4 "=a"))]
13290   "TARGET_80387
13291    && FLOAT_MODE_P (GET_MODE (operands[1]))
13292    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13293    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13294   "#")
13295
13296 (define_split
13297   [(set (pc)
13298         (if_then_else (match_operator 0 "comparison_operator"
13299                         [(match_operand 1 "register_operand" "")
13300                          (match_operand 2 "nonimmediate_operand" "")])
13301           (match_operand 3 "" "")
13302           (match_operand 4 "" "")))
13303    (clobber (reg:CCFP FPSR_REG))
13304    (clobber (reg:CCFP FLAGS_REG))]
13305   "reload_completed"
13306   [(const_int 0)]
13307 {
13308   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13309                         operands[3], operands[4], NULL_RTX);
13310   DONE;
13311 })
13312
13313 (define_split
13314   [(set (pc)
13315         (if_then_else (match_operator 0 "comparison_operator"
13316                         [(match_operand 1 "register_operand" "")
13317                          (match_operand 2 "nonimmediate_operand" "")])
13318           (match_operand 3 "" "")
13319           (match_operand 4 "" "")))
13320    (clobber (reg:CCFP FPSR_REG))
13321    (clobber (reg:CCFP FLAGS_REG))
13322    (clobber (match_scratch:HI 5 "=a"))]
13323   "reload_completed"
13324   [(set (pc)
13325         (if_then_else (match_dup 6)
13326           (match_dup 3)
13327           (match_dup 4)))]
13328 {
13329   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13330                         operands[3], operands[4], operands[5]);
13331   DONE;
13332 })
13333 \f
13334 ;; Unconditional and other jump instructions
13335
13336 (define_insn "jump"
13337   [(set (pc)
13338         (label_ref (match_operand 0 "" "")))]
13339   ""
13340   "jmp\t%l0"
13341   [(set_attr "type" "ibr")
13342    (set (attr "length")
13343            (if_then_else (and (ge (minus (match_dup 0) (pc))
13344                                   (const_int -126))
13345                               (lt (minus (match_dup 0) (pc))
13346                                   (const_int 128)))
13347              (const_int 2)
13348              (const_int 5)))
13349    (set_attr "modrm" "0")])
13350
13351 (define_expand "indirect_jump"
13352   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13353   ""
13354   "")
13355
13356 (define_insn "*indirect_jump"
13357   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13358   "!TARGET_64BIT"
13359   "jmp\t%A0"
13360   [(set_attr "type" "ibr")
13361    (set_attr "length_immediate" "0")])
13362
13363 (define_insn "*indirect_jump_rtx64"
13364   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13365   "TARGET_64BIT"
13366   "jmp\t%A0"
13367   [(set_attr "type" "ibr")
13368    (set_attr "length_immediate" "0")])
13369
13370 (define_expand "tablejump"
13371   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13372               (use (label_ref (match_operand 1 "" "")))])]
13373   ""
13374 {
13375   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13376      relative.  Convert the relative address to an absolute address.  */
13377   if (flag_pic)
13378     {
13379       rtx op0, op1;
13380       enum rtx_code code;
13381
13382       if (TARGET_64BIT)
13383         {
13384           code = PLUS;
13385           op0 = operands[0];
13386           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13387         }
13388       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13389         {
13390           code = PLUS;
13391           op0 = operands[0];
13392           op1 = pic_offset_table_rtx;
13393         }
13394       else
13395         {
13396           code = MINUS;
13397           op0 = pic_offset_table_rtx;
13398           op1 = operands[0];
13399         }
13400
13401       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13402                                          OPTAB_DIRECT);
13403     }
13404 })
13405
13406 (define_insn "*tablejump_1"
13407   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13408    (use (label_ref (match_operand 1 "" "")))]
13409   "!TARGET_64BIT"
13410   "jmp\t%A0"
13411   [(set_attr "type" "ibr")
13412    (set_attr "length_immediate" "0")])
13413
13414 (define_insn "*tablejump_1_rtx64"
13415   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13416    (use (label_ref (match_operand 1 "" "")))]
13417   "TARGET_64BIT"
13418   "jmp\t%A0"
13419   [(set_attr "type" "ibr")
13420    (set_attr "length_immediate" "0")])
13421 \f
13422 ;; Loop instruction
13423 ;;
13424 ;; This is all complicated by the fact that since this is a jump insn
13425 ;; we must handle our own reloads.
13426
13427 (define_expand "doloop_end"
13428   [(use (match_operand 0 "" ""))        ; loop pseudo
13429    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13430    (use (match_operand 2 "" ""))        ; max iterations
13431    (use (match_operand 3 "" ""))        ; loop level 
13432    (use (match_operand 4 "" ""))]       ; label
13433   "!TARGET_64BIT && TARGET_USE_LOOP"
13434   "                                 
13435 {
13436   /* Only use cloop on innermost loops.  */
13437   if (INTVAL (operands[3]) > 1)
13438     FAIL;
13439   if (GET_MODE (operands[0]) != SImode)
13440     FAIL;
13441   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13442                                            operands[0]));
13443   DONE;
13444 }")
13445
13446 (define_insn "doloop_end_internal"
13447   [(set (pc)
13448         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13449                           (const_int 1))
13450                       (label_ref (match_operand 0 "" ""))
13451                       (pc)))
13452    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13453         (plus:SI (match_dup 1)
13454                  (const_int -1)))
13455    (clobber (match_scratch:SI 3 "=X,X,r"))
13456    (clobber (reg:CC FLAGS_REG))]
13457   "!TARGET_64BIT && TARGET_USE_LOOP
13458    && (reload_in_progress || reload_completed
13459        || register_operand (operands[2], VOIDmode))"
13460 {
13461   if (which_alternative != 0)
13462     return "#";
13463   if (get_attr_length (insn) == 2)
13464     return "%+loop\t%l0";
13465   else
13466     return "dec{l}\t%1\;%+jne\t%l0";
13467 }
13468   [(set (attr "length")
13469         (if_then_else (and (eq_attr "alternative" "0")
13470                            (and (ge (minus (match_dup 0) (pc))
13471                                     (const_int -126))
13472                                 (lt (minus (match_dup 0) (pc))
13473                                     (const_int 128))))
13474                       (const_int 2)
13475                       (const_int 16)))
13476    ;; We don't know the type before shorten branches.  Optimistically expect
13477    ;; the loop instruction to match.
13478    (set (attr "type") (const_string "ibr"))])
13479
13480 (define_split
13481   [(set (pc)
13482         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13483                           (const_int 1))
13484                       (match_operand 0 "" "")
13485                       (pc)))
13486    (set (match_dup 1)
13487         (plus:SI (match_dup 1)
13488                  (const_int -1)))
13489    (clobber (match_scratch:SI 2 ""))
13490    (clobber (reg:CC FLAGS_REG))]
13491   "!TARGET_64BIT && TARGET_USE_LOOP
13492    && reload_completed
13493    && REGNO (operands[1]) != 2"
13494   [(parallel [(set (reg:CCZ FLAGS_REG)
13495                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13496                                  (const_int 0)))
13497               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13498    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13499                            (match_dup 0)
13500                            (pc)))]
13501   "")
13502   
13503 (define_split
13504   [(set (pc)
13505         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13506                           (const_int 1))
13507                       (match_operand 0 "" "")
13508                       (pc)))
13509    (set (match_operand:SI 2 "nonimmediate_operand" "")
13510         (plus:SI (match_dup 1)
13511                  (const_int -1)))
13512    (clobber (match_scratch:SI 3 ""))
13513    (clobber (reg:CC FLAGS_REG))]
13514   "!TARGET_64BIT && TARGET_USE_LOOP
13515    && reload_completed
13516    && (! REG_P (operands[2])
13517        || ! rtx_equal_p (operands[1], operands[2]))"
13518   [(set (match_dup 3) (match_dup 1))
13519    (parallel [(set (reg:CCZ FLAGS_REG)
13520                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13521                                 (const_int 0)))
13522               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13523    (set (match_dup 2) (match_dup 3))
13524    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13525                            (match_dup 0)
13526                            (pc)))]
13527   "")
13528
13529 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13530
13531 (define_peephole2
13532   [(set (reg 17) (match_operand 0 "" ""))
13533    (set (match_operand:QI 1 "register_operand" "")
13534         (match_operator:QI 2 "ix86_comparison_operator"
13535           [(reg 17) (const_int 0)]))
13536    (set (match_operand 3 "q_regs_operand" "")
13537         (zero_extend (match_dup 1)))]
13538   "(peep2_reg_dead_p (3, operands[1])
13539     || operands_match_p (operands[1], operands[3]))
13540    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13541   [(set (match_dup 4) (match_dup 0))
13542    (set (strict_low_part (match_dup 5))
13543         (match_dup 2))]
13544 {
13545   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13546   operands[5] = gen_lowpart (QImode, operands[3]);
13547   ix86_expand_clear (operands[3]);
13548 })
13549
13550 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13551
13552 (define_peephole2
13553   [(set (reg 17) (match_operand 0 "" ""))
13554    (set (match_operand:QI 1 "register_operand" "")
13555         (match_operator:QI 2 "ix86_comparison_operator"
13556           [(reg 17) (const_int 0)]))
13557    (parallel [(set (match_operand 3 "q_regs_operand" "")
13558                    (zero_extend (match_dup 1)))
13559               (clobber (reg:CC FLAGS_REG))])]
13560   "(peep2_reg_dead_p (3, operands[1])
13561     || operands_match_p (operands[1], operands[3]))
13562    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13563   [(set (match_dup 4) (match_dup 0))
13564    (set (strict_low_part (match_dup 5))
13565         (match_dup 2))]
13566 {
13567   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13568   operands[5] = gen_lowpart (QImode, operands[3]);
13569   ix86_expand_clear (operands[3]);
13570 })
13571 \f
13572 ;; Call instructions.
13573
13574 ;; The predicates normally associated with named expanders are not properly
13575 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13576 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13577
13578 ;; Call subroutine returning no value.
13579
13580 (define_expand "call_pop"
13581   [(parallel [(call (match_operand:QI 0 "" "")
13582                     (match_operand:SI 1 "" ""))
13583               (set (reg:SI SP_REG)
13584                    (plus:SI (reg:SI SP_REG)
13585                             (match_operand:SI 3 "" "")))])]
13586   "!TARGET_64BIT"
13587 {
13588   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13589   DONE;
13590 })
13591
13592 (define_insn "*call_pop_0"
13593   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13594          (match_operand:SI 1 "" ""))
13595    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13596                             (match_operand:SI 2 "immediate_operand" "")))]
13597   "!TARGET_64BIT"
13598 {
13599   if (SIBLING_CALL_P (insn))
13600     return "jmp\t%P0";
13601   else
13602     return "call\t%P0";
13603 }
13604   [(set_attr "type" "call")])
13605   
13606 (define_insn "*call_pop_1"
13607   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13608          (match_operand:SI 1 "" ""))
13609    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13610                             (match_operand:SI 2 "immediate_operand" "i")))]
13611   "!TARGET_64BIT"
13612 {
13613   if (constant_call_address_operand (operands[0], Pmode))
13614     {
13615       if (SIBLING_CALL_P (insn))
13616         return "jmp\t%P0";
13617       else
13618         return "call\t%P0";
13619     }
13620   if (SIBLING_CALL_P (insn))
13621     return "jmp\t%A0";
13622   else
13623     return "call\t%A0";
13624 }
13625   [(set_attr "type" "call")])
13626
13627 (define_expand "call"
13628   [(call (match_operand:QI 0 "" "")
13629          (match_operand 1 "" ""))
13630    (use (match_operand 2 "" ""))]
13631   ""
13632 {
13633   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13634   DONE;
13635 })
13636
13637 (define_expand "sibcall"
13638   [(call (match_operand:QI 0 "" "")
13639          (match_operand 1 "" ""))
13640    (use (match_operand 2 "" ""))]
13641   ""
13642 {
13643   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13644   DONE;
13645 })
13646
13647 (define_insn "*call_0"
13648   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13649          (match_operand 1 "" ""))]
13650   ""
13651 {
13652   if (SIBLING_CALL_P (insn))
13653     return "jmp\t%P0";
13654   else
13655     return "call\t%P0";
13656 }
13657   [(set_attr "type" "call")])
13658
13659 (define_insn "*call_1"
13660   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13661          (match_operand 1 "" ""))]
13662   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13663 {
13664   if (constant_call_address_operand (operands[0], QImode))
13665     return "call\t%P0";
13666   return "call\t%A0";
13667 }
13668   [(set_attr "type" "call")])
13669
13670 (define_insn "*sibcall_1"
13671   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13672          (match_operand 1 "" ""))]
13673   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13674 {
13675   if (constant_call_address_operand (operands[0], QImode))
13676     return "jmp\t%P0";
13677   return "jmp\t%A0";
13678 }
13679   [(set_attr "type" "call")])
13680
13681 (define_insn "*call_1_rex64"
13682   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13683          (match_operand 1 "" ""))]
13684   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13685 {
13686   if (constant_call_address_operand (operands[0], QImode))
13687     return "call\t%P0";
13688   return "call\t%A0";
13689 }
13690   [(set_attr "type" "call")])
13691
13692 (define_insn "*sibcall_1_rex64"
13693   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13694          (match_operand 1 "" ""))]
13695   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13696   "jmp\t%P0"
13697   [(set_attr "type" "call")])
13698
13699 (define_insn "*sibcall_1_rex64_v"
13700   [(call (mem:QI (reg:DI 40))
13701          (match_operand 0 "" ""))]
13702   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13703   "jmp\t*%%r11"
13704   [(set_attr "type" "call")])
13705
13706
13707 ;; Call subroutine, returning value in operand 0
13708
13709 (define_expand "call_value_pop"
13710   [(parallel [(set (match_operand 0 "" "")
13711                    (call (match_operand:QI 1 "" "")
13712                          (match_operand:SI 2 "" "")))
13713               (set (reg:SI SP_REG)
13714                    (plus:SI (reg:SI SP_REG)
13715                             (match_operand:SI 4 "" "")))])]
13716   "!TARGET_64BIT"
13717 {
13718   ix86_expand_call (operands[0], operands[1], operands[2],
13719                     operands[3], operands[4], 0);
13720   DONE;
13721 })
13722
13723 (define_expand "call_value"
13724   [(set (match_operand 0 "" "")
13725         (call (match_operand:QI 1 "" "")
13726               (match_operand:SI 2 "" "")))
13727    (use (match_operand:SI 3 "" ""))]
13728   ;; Operand 2 not used on the i386.
13729   ""
13730 {
13731   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13732   DONE;
13733 })
13734
13735 (define_expand "sibcall_value"
13736   [(set (match_operand 0 "" "")
13737         (call (match_operand:QI 1 "" "")
13738               (match_operand:SI 2 "" "")))
13739    (use (match_operand:SI 3 "" ""))]
13740   ;; Operand 2 not used on the i386.
13741   ""
13742 {
13743   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13744   DONE;
13745 })
13746
13747 ;; Call subroutine returning any type.
13748
13749 (define_expand "untyped_call"
13750   [(parallel [(call (match_operand 0 "" "")
13751                     (const_int 0))
13752               (match_operand 1 "" "")
13753               (match_operand 2 "" "")])]
13754   ""
13755 {
13756   int i;
13757
13758   /* In order to give reg-stack an easier job in validating two
13759      coprocessor registers as containing a possible return value,
13760      simply pretend the untyped call returns a complex long double
13761      value.  */
13762
13763   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13764                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13765                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13766                     NULL, 0);
13767
13768   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13769     {
13770       rtx set = XVECEXP (operands[2], 0, i);
13771       emit_move_insn (SET_DEST (set), SET_SRC (set));
13772     }
13773
13774   /* The optimizer does not know that the call sets the function value
13775      registers we stored in the result block.  We avoid problems by
13776      claiming that all hard registers are used and clobbered at this
13777      point.  */
13778   emit_insn (gen_blockage (const0_rtx));
13779
13780   DONE;
13781 })
13782 \f
13783 ;; Prologue and epilogue instructions
13784
13785 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13786 ;; all of memory.  This blocks insns from being moved across this point.
13787
13788 (define_insn "blockage"
13789   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13790   ""
13791   ""
13792   [(set_attr "length" "0")])
13793
13794 ;; Insn emitted into the body of a function to return from a function.
13795 ;; This is only done if the function's epilogue is known to be simple.
13796 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13797
13798 (define_expand "return"
13799   [(return)]
13800   "ix86_can_use_return_insn_p ()"
13801 {
13802   if (current_function_pops_args)
13803     {
13804       rtx popc = GEN_INT (current_function_pops_args);
13805       emit_jump_insn (gen_return_pop_internal (popc));
13806       DONE;
13807     }
13808 })
13809
13810 (define_insn "return_internal"
13811   [(return)]
13812   "reload_completed"
13813   "ret"
13814   [(set_attr "length" "1")
13815    (set_attr "length_immediate" "0")
13816    (set_attr "modrm" "0")])
13817
13818 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13819 ;; instruction Athlon and K8 have.
13820
13821 (define_insn "return_internal_long"
13822   [(return)
13823    (unspec [(const_int 0)] UNSPEC_REP)]
13824   "reload_completed"
13825   "rep {;} ret"
13826   [(set_attr "length" "1")
13827    (set_attr "length_immediate" "0")
13828    (set_attr "prefix_rep" "1")
13829    (set_attr "modrm" "0")])
13830
13831 (define_insn "return_pop_internal"
13832   [(return)
13833    (use (match_operand:SI 0 "const_int_operand" ""))]
13834   "reload_completed"
13835   "ret\t%0"
13836   [(set_attr "length" "3")
13837    (set_attr "length_immediate" "2")
13838    (set_attr "modrm" "0")])
13839
13840 (define_insn "return_indirect_internal"
13841   [(return)
13842    (use (match_operand:SI 0 "register_operand" "r"))]
13843   "reload_completed"
13844   "jmp\t%A0"
13845   [(set_attr "type" "ibr")
13846    (set_attr "length_immediate" "0")])
13847
13848 (define_insn "nop"
13849   [(const_int 0)]
13850   ""
13851   "nop"
13852   [(set_attr "length" "1")
13853    (set_attr "length_immediate" "0")
13854    (set_attr "modrm" "0")])
13855
13856 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13857 ;; branch prediction penalty for the third jump in a 16-byte
13858 ;; block on K8.
13859
13860 (define_insn "align"
13861   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13862   ""
13863 {
13864 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13865   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13866 #else
13867   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13868      The align insn is used to avoid 3 jump instructions in the row to improve
13869      branch prediction and the benefits hardly outweight the cost of extra 8
13870      nops on the average inserted by full alignment pseudo operation.  */
13871 #endif
13872   return "";
13873 }
13874   [(set_attr "length" "16")])
13875
13876 (define_expand "prologue"
13877   [(const_int 1)]
13878   ""
13879   "ix86_expand_prologue (); DONE;")
13880
13881 (define_insn "set_got"
13882   [(set (match_operand:SI 0 "register_operand" "=r")
13883         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13884    (clobber (reg:CC FLAGS_REG))]
13885   "!TARGET_64BIT"
13886   { return output_set_got (operands[0]); }
13887   [(set_attr "type" "multi")
13888    (set_attr "length" "12")])
13889
13890 (define_expand "epilogue"
13891   [(const_int 1)]
13892   ""
13893   "ix86_expand_epilogue (1); DONE;")
13894
13895 (define_expand "sibcall_epilogue"
13896   [(const_int 1)]
13897   ""
13898   "ix86_expand_epilogue (0); DONE;")
13899
13900 (define_expand "eh_return"
13901   [(use (match_operand 0 "register_operand" ""))]
13902   ""
13903 {
13904   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13905
13906   /* Tricky bit: we write the address of the handler to which we will
13907      be returning into someone else's stack frame, one word below the
13908      stack address we wish to restore.  */
13909   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13910   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13911   tmp = gen_rtx_MEM (Pmode, tmp);
13912   emit_move_insn (tmp, ra);
13913
13914   if (Pmode == SImode)
13915     emit_jump_insn (gen_eh_return_si (sa));
13916   else
13917     emit_jump_insn (gen_eh_return_di (sa));
13918   emit_barrier ();
13919   DONE;
13920 })
13921
13922 (define_insn_and_split "eh_return_si"
13923   [(set (pc) 
13924         (unspec [(match_operand:SI 0 "register_operand" "c")]
13925                  UNSPEC_EH_RETURN))]
13926   "!TARGET_64BIT"
13927   "#"
13928   "reload_completed"
13929   [(const_int 1)]
13930   "ix86_expand_epilogue (2); DONE;")
13931
13932 (define_insn_and_split "eh_return_di"
13933   [(set (pc) 
13934         (unspec [(match_operand:DI 0 "register_operand" "c")]
13935                  UNSPEC_EH_RETURN))]
13936   "TARGET_64BIT"
13937   "#"
13938   "reload_completed"
13939   [(const_int 1)]
13940   "ix86_expand_epilogue (2); DONE;")
13941
13942 (define_insn "leave"
13943   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13944    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13945    (clobber (mem:BLK (scratch)))]
13946   "!TARGET_64BIT"
13947   "leave"
13948   [(set_attr "type" "leave")])
13949
13950 (define_insn "leave_rex64"
13951   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13952    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13953    (clobber (mem:BLK (scratch)))]
13954   "TARGET_64BIT"
13955   "leave"
13956   [(set_attr "type" "leave")])
13957 \f
13958 (define_expand "ffssi2"
13959   [(parallel
13960      [(set (match_operand:SI 0 "register_operand" "") 
13961            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13962       (clobber (match_scratch:SI 2 ""))
13963       (clobber (reg:CC FLAGS_REG))])]
13964   ""
13965   "")
13966
13967 (define_insn_and_split "*ffs_cmove"
13968   [(set (match_operand:SI 0 "register_operand" "=r") 
13969         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13970    (clobber (match_scratch:SI 2 "=&r"))
13971    (clobber (reg:CC FLAGS_REG))]
13972   "TARGET_CMOVE"
13973   "#"
13974   "&& reload_completed"
13975   [(set (match_dup 2) (const_int -1))
13976    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13977               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13978    (set (match_dup 0) (if_then_else:SI
13979                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13980                         (match_dup 2)
13981                         (match_dup 0)))
13982    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13983               (clobber (reg:CC FLAGS_REG))])]
13984   "")
13985
13986 (define_insn_and_split "*ffs_no_cmove"
13987   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13988         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13989    (clobber (match_scratch:SI 2 "=&q"))
13990    (clobber (reg:CC FLAGS_REG))]
13991   ""
13992   "#"
13993   "reload_completed"
13994   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13995               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13996    (set (strict_low_part (match_dup 3))
13997         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13998    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13999               (clobber (reg:CC FLAGS_REG))])
14000    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14001               (clobber (reg:CC FLAGS_REG))])
14002    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14003               (clobber (reg:CC FLAGS_REG))])]
14004 {
14005   operands[3] = gen_lowpart (QImode, operands[2]);
14006   ix86_expand_clear (operands[2]);
14007 })
14008
14009 (define_insn "*ffssi_1"
14010   [(set (reg:CCZ FLAGS_REG)
14011         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14012                      (const_int 0)))
14013    (set (match_operand:SI 0 "register_operand" "=r")
14014         (ctz:SI (match_dup 1)))]
14015   ""
14016   "bsf{l}\t{%1, %0|%0, %1}"
14017   [(set_attr "prefix_0f" "1")])
14018
14019 (define_expand "ffsdi2"
14020   [(parallel
14021      [(set (match_operand:DI 0 "register_operand" "") 
14022            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14023       (clobber (match_scratch:DI 2 ""))
14024       (clobber (reg:CC 17))])]
14025   "TARGET_64BIT && TARGET_CMOVE"
14026   "")
14027
14028 (define_insn_and_split "*ffs_rex64"
14029   [(set (match_operand:DI 0 "register_operand" "=r") 
14030         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14031    (clobber (match_scratch:DI 2 "=&r"))
14032    (clobber (reg:CC 17))]
14033   "TARGET_64BIT && TARGET_CMOVE"
14034   "#"
14035   "&& reload_completed"
14036   [(set (match_dup 2) (const_int -1))
14037    (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14038               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14039    (set (match_dup 0) (if_then_else:DI
14040                         (eq (reg:CCZ 17) (const_int 0))
14041                         (match_dup 2)
14042                         (match_dup 0)))
14043    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14044               (clobber (reg:CC 17))])]
14045   "")
14046
14047 (define_insn "*ffsdi_1"
14048   [(set (reg:CCZ 17)
14049         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14050                      (const_int 0)))
14051    (set (match_operand:DI 0 "register_operand" "=r")
14052         (ctz:DI (match_dup 1)))]
14053   "TARGET_64BIT"
14054   "bsf{q}\t{%1, %0|%0, %1}"
14055   [(set_attr "prefix_0f" "1")])
14056
14057 (define_insn "ctzsi2"
14058   [(set (match_operand:SI 0 "register_operand" "=r")
14059         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14060    (clobber (reg:CC FLAGS_REG))]
14061   ""
14062   "bsf{l}\t{%1, %0|%0, %1}"
14063   [(set_attr "prefix_0f" "1")])
14064
14065 (define_insn "ctzdi2"
14066   [(set (match_operand:DI 0 "register_operand" "=r")
14067         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14068    (clobber (reg:CC 17))]
14069   "TARGET_64BIT"
14070   "bsf{q}\t{%1, %0|%0, %1}"
14071   [(set_attr "prefix_0f" "1")])
14072
14073 (define_expand "clzsi2"
14074   [(parallel
14075      [(set (match_operand:SI 0 "register_operand" "")
14076            (minus:SI (const_int 31)
14077                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14078       (clobber (reg:CC FLAGS_REG))])
14079    (parallel
14080      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14081       (clobber (reg:CC FLAGS_REG))])]
14082   ""
14083   "")
14084
14085 (define_insn "*bsr"
14086   [(set (match_operand:SI 0 "register_operand" "=r")
14087         (minus:SI (const_int 31)
14088                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14089    (clobber (reg:CC FLAGS_REG))]
14090   ""
14091   "bsr{l}\t{%1, %0|%0, %1}"
14092   [(set_attr "prefix_0f" "1")])
14093
14094 (define_expand "clzdi2"
14095   [(parallel
14096      [(set (match_operand:DI 0 "register_operand" "")
14097            (minus:DI (const_int 63)
14098                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14099       (clobber (reg:CC 17))])
14100    (parallel
14101      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14102       (clobber (reg:CC 17))])]
14103   "TARGET_64BIT"
14104   "")
14105
14106 (define_insn "*bsr_rex64"
14107   [(set (match_operand:DI 0 "register_operand" "=r")
14108         (minus:DI (const_int 63)
14109                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14110    (clobber (reg:CC 17))]
14111   "TARGET_64BIT"
14112   "bsr{q}\t{%1, %0|%0, %1}"
14113   [(set_attr "prefix_0f" "1")])
14114 \f
14115 ;; Thread-local storage patterns for ELF.
14116 ;;
14117 ;; Note that these code sequences must appear exactly as shown
14118 ;; in order to allow linker relaxation.
14119
14120 (define_insn "*tls_global_dynamic_32_gnu"
14121   [(set (match_operand:SI 0 "register_operand" "=a")
14122         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14123                     (match_operand:SI 2 "tls_symbolic_operand" "")
14124                     (match_operand:SI 3 "call_insn_operand" "")]
14125                     UNSPEC_TLS_GD))
14126    (clobber (match_scratch:SI 4 "=d"))
14127    (clobber (match_scratch:SI 5 "=c"))
14128    (clobber (reg:CC FLAGS_REG))]
14129   "!TARGET_64BIT && TARGET_GNU_TLS"
14130   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14131   [(set_attr "type" "multi")
14132    (set_attr "length" "12")])
14133
14134 (define_insn "*tls_global_dynamic_32_sun"
14135   [(set (match_operand:SI 0 "register_operand" "=a")
14136         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14137                     (match_operand:SI 2 "tls_symbolic_operand" "")
14138                     (match_operand:SI 3 "call_insn_operand" "")]
14139                     UNSPEC_TLS_GD))
14140    (clobber (match_scratch:SI 4 "=d"))
14141    (clobber (match_scratch:SI 5 "=c"))
14142    (clobber (reg:CC FLAGS_REG))]
14143   "!TARGET_64BIT && TARGET_SUN_TLS"
14144   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14145         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14146   [(set_attr "type" "multi")
14147    (set_attr "length" "14")])
14148
14149 (define_expand "tls_global_dynamic_32"
14150   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14151                    (unspec:SI
14152                     [(match_dup 2)
14153                      (match_operand:SI 1 "tls_symbolic_operand" "")
14154                      (match_dup 3)]
14155                     UNSPEC_TLS_GD))
14156               (clobber (match_scratch:SI 4 ""))
14157               (clobber (match_scratch:SI 5 ""))
14158               (clobber (reg:CC FLAGS_REG))])]
14159   ""
14160 {
14161   if (flag_pic)
14162     operands[2] = pic_offset_table_rtx;
14163   else
14164     {
14165       operands[2] = gen_reg_rtx (Pmode);
14166       emit_insn (gen_set_got (operands[2]));
14167     }
14168   operands[3] = ix86_tls_get_addr ();
14169 })
14170
14171 (define_insn "*tls_global_dynamic_64"
14172   [(set (match_operand:DI 0 "register_operand" "=a")
14173         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14174                       (match_operand:DI 3 "" "")))
14175    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14176               UNSPEC_TLS_GD)]
14177   "TARGET_64BIT"
14178   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14179   [(set_attr "type" "multi")
14180    (set_attr "length" "16")])
14181
14182 (define_expand "tls_global_dynamic_64"
14183   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14184                    (call (mem:QI (match_dup 2)) (const_int 0)))
14185               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14186                          UNSPEC_TLS_GD)])]
14187   ""
14188 {
14189   operands[2] = ix86_tls_get_addr ();
14190 })
14191
14192 (define_insn "*tls_local_dynamic_base_32_gnu"
14193   [(set (match_operand:SI 0 "register_operand" "=a")
14194         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14195                     (match_operand:SI 2 "call_insn_operand" "")]
14196                    UNSPEC_TLS_LD_BASE))
14197    (clobber (match_scratch:SI 3 "=d"))
14198    (clobber (match_scratch:SI 4 "=c"))
14199    (clobber (reg:CC FLAGS_REG))]
14200   "!TARGET_64BIT && TARGET_GNU_TLS"
14201   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14202   [(set_attr "type" "multi")
14203    (set_attr "length" "11")])
14204
14205 (define_insn "*tls_local_dynamic_base_32_sun"
14206   [(set (match_operand:SI 0 "register_operand" "=a")
14207         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14208                     (match_operand:SI 2 "call_insn_operand" "")]
14209                    UNSPEC_TLS_LD_BASE))
14210    (clobber (match_scratch:SI 3 "=d"))
14211    (clobber (match_scratch:SI 4 "=c"))
14212    (clobber (reg:CC FLAGS_REG))]
14213   "!TARGET_64BIT && TARGET_SUN_TLS"
14214   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14215         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14216   [(set_attr "type" "multi")
14217    (set_attr "length" "13")])
14218
14219 (define_expand "tls_local_dynamic_base_32"
14220   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14221                    (unspec:SI [(match_dup 1) (match_dup 2)]
14222                               UNSPEC_TLS_LD_BASE))
14223               (clobber (match_scratch:SI 3 ""))
14224               (clobber (match_scratch:SI 4 ""))
14225               (clobber (reg:CC FLAGS_REG))])]
14226   ""
14227 {
14228   if (flag_pic)
14229     operands[1] = pic_offset_table_rtx;
14230   else
14231     {
14232       operands[1] = gen_reg_rtx (Pmode);
14233       emit_insn (gen_set_got (operands[1]));
14234     }
14235   operands[2] = ix86_tls_get_addr ();
14236 })
14237
14238 (define_insn "*tls_local_dynamic_base_64"
14239   [(set (match_operand:DI 0 "register_operand" "=a")
14240         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14241                       (match_operand:DI 2 "" "")))
14242    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14243   "TARGET_64BIT"
14244   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14245   [(set_attr "type" "multi")
14246    (set_attr "length" "12")])
14247
14248 (define_expand "tls_local_dynamic_base_64"
14249   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14250                    (call (mem:QI (match_dup 1)) (const_int 0)))
14251               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14252   ""
14253 {
14254   operands[1] = ix86_tls_get_addr ();
14255 })
14256
14257 ;; Local dynamic of a single variable is a lose.  Show combine how
14258 ;; to convert that back to global dynamic.
14259
14260 (define_insn_and_split "*tls_local_dynamic_32_once"
14261   [(set (match_operand:SI 0 "register_operand" "=a")
14262         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14263                              (match_operand:SI 2 "call_insn_operand" "")]
14264                             UNSPEC_TLS_LD_BASE)
14265                  (const:SI (unspec:SI
14266                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14267                             UNSPEC_DTPOFF))))
14268    (clobber (match_scratch:SI 4 "=d"))
14269    (clobber (match_scratch:SI 5 "=c"))
14270    (clobber (reg:CC FLAGS_REG))]
14271   ""
14272   "#"
14273   ""
14274   [(parallel [(set (match_dup 0)
14275                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14276                               UNSPEC_TLS_GD))
14277               (clobber (match_dup 4))
14278               (clobber (match_dup 5))
14279               (clobber (reg:CC FLAGS_REG))])]
14280   "")
14281
14282 ;; Load and add the thread base pointer from %gs:0.
14283
14284 (define_insn "*load_tp_si"
14285   [(set (match_operand:SI 0 "register_operand" "=r")
14286         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14287   "!TARGET_64BIT"
14288   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14289   [(set_attr "type" "imov")
14290    (set_attr "modrm" "0")
14291    (set_attr "length" "7")
14292    (set_attr "memory" "load")
14293    (set_attr "imm_disp" "false")])
14294
14295 (define_insn "*add_tp_si"
14296   [(set (match_operand:SI 0 "register_operand" "=r")
14297         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14298                  (match_operand:SI 1 "register_operand" "0")))
14299    (clobber (reg:CC FLAGS_REG))]
14300   "!TARGET_64BIT"
14301   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14302   [(set_attr "type" "alu")
14303    (set_attr "modrm" "0")
14304    (set_attr "length" "7")
14305    (set_attr "memory" "load")
14306    (set_attr "imm_disp" "false")])
14307
14308 (define_insn "*load_tp_di"
14309   [(set (match_operand:DI 0 "register_operand" "=r")
14310         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14311   "TARGET_64BIT"
14312   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14313   [(set_attr "type" "imov")
14314    (set_attr "modrm" "0")
14315    (set_attr "length" "7")
14316    (set_attr "memory" "load")
14317    (set_attr "imm_disp" "false")])
14318
14319 (define_insn "*add_tp_di"
14320   [(set (match_operand:DI 0 "register_operand" "=r")
14321         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14322                  (match_operand:DI 1 "register_operand" "0")))
14323    (clobber (reg:CC FLAGS_REG))]
14324   "TARGET_64BIT"
14325   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14326   [(set_attr "type" "alu")
14327    (set_attr "modrm" "0")
14328    (set_attr "length" "7")
14329    (set_attr "memory" "load")
14330    (set_attr "imm_disp" "false")])
14331 \f
14332 ;; These patterns match the binary 387 instructions for addM3, subM3,
14333 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14334 ;; SFmode.  The first is the normal insn, the second the same insn but
14335 ;; with one operand a conversion, and the third the same insn but with
14336 ;; the other operand a conversion.  The conversion may be SFmode or
14337 ;; SImode if the target mode DFmode, but only SImode if the target mode
14338 ;; is SFmode.
14339
14340 ;; Gcc is slightly more smart about handling normal two address instructions
14341 ;; so use special patterns for add and mull.
14342 (define_insn "*fop_sf_comm_nosse"
14343   [(set (match_operand:SF 0 "register_operand" "=f")
14344         (match_operator:SF 3 "binary_fp_operator"
14345                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14346                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14347   "TARGET_80387 && !TARGET_SSE_MATH
14348    && COMMUTATIVE_ARITH_P (operands[3])
14349    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14350   "* return output_387_binary_op (insn, operands);"
14351   [(set (attr "type") 
14352         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14353            (const_string "fmul")
14354            (const_string "fop")))
14355    (set_attr "mode" "SF")])
14356
14357 (define_insn "*fop_sf_comm"
14358   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14359         (match_operator:SF 3 "binary_fp_operator"
14360                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14361                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14362   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14363    && COMMUTATIVE_ARITH_P (operands[3])
14364    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14365   "* return output_387_binary_op (insn, operands);"
14366   [(set (attr "type") 
14367         (if_then_else (eq_attr "alternative" "1")
14368            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14369               (const_string "ssemul")
14370               (const_string "sseadd"))
14371            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14372               (const_string "fmul")
14373               (const_string "fop"))))
14374    (set_attr "mode" "SF")])
14375
14376 (define_insn "*fop_sf_comm_sse"
14377   [(set (match_operand:SF 0 "register_operand" "=x")
14378         (match_operator:SF 3 "binary_fp_operator"
14379                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14380                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14381   "TARGET_SSE_MATH && COMMUTATIVE_ARITH_P (operands[3])
14382    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14383   "* return output_387_binary_op (insn, operands);"
14384   [(set (attr "type") 
14385         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14386            (const_string "ssemul")
14387            (const_string "sseadd")))
14388    (set_attr "mode" "SF")])
14389
14390 (define_insn "*fop_df_comm_nosse"
14391   [(set (match_operand:DF 0 "register_operand" "=f")
14392         (match_operator:DF 3 "binary_fp_operator"
14393                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14394                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14395   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14396    && COMMUTATIVE_ARITH_P (operands[3])
14397    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14398   "* return output_387_binary_op (insn, operands);"
14399   [(set (attr "type") 
14400         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14401            (const_string "fmul")
14402            (const_string "fop")))
14403    (set_attr "mode" "DF")])
14404
14405 (define_insn "*fop_df_comm"
14406   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14407         (match_operator:DF 3 "binary_fp_operator"
14408                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14409                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14410   "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14411    && COMMUTATIVE_ARITH_P (operands[3])
14412    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14413   "* return output_387_binary_op (insn, operands);"
14414   [(set (attr "type") 
14415         (if_then_else (eq_attr "alternative" "1")
14416            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14417               (const_string "ssemul")
14418               (const_string "sseadd"))
14419            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14420               (const_string "fmul")
14421               (const_string "fop"))))
14422    (set_attr "mode" "DF")])
14423
14424 (define_insn "*fop_df_comm_sse"
14425   [(set (match_operand:DF 0 "register_operand" "=Y")
14426         (match_operator:DF 3 "binary_fp_operator"
14427                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14428                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14429   "TARGET_SSE2 && TARGET_SSE_MATH
14430    && COMMUTATIVE_ARITH_P (operands[3])
14431    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14432   "* return output_387_binary_op (insn, operands);"
14433   [(set (attr "type") 
14434         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14435            (const_string "ssemul")
14436            (const_string "sseadd")))
14437    (set_attr "mode" "DF")])
14438
14439 (define_insn "*fop_xf_comm"
14440   [(set (match_operand:XF 0 "register_operand" "=f")
14441         (match_operator:XF 3 "binary_fp_operator"
14442                         [(match_operand:XF 1 "register_operand" "%0")
14443                          (match_operand:XF 2 "register_operand" "f")]))]
14444   "TARGET_80387
14445    && COMMUTATIVE_ARITH_P (operands[3])"
14446   "* return output_387_binary_op (insn, operands);"
14447   [(set (attr "type") 
14448         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14449            (const_string "fmul")
14450            (const_string "fop")))
14451    (set_attr "mode" "XF")])
14452
14453 (define_insn "*fop_sf_1_nosse"
14454   [(set (match_operand:SF 0 "register_operand" "=f,f")
14455         (match_operator:SF 3 "binary_fp_operator"
14456                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14457                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14458   "TARGET_80387 && !TARGET_SSE_MATH
14459    && !COMMUTATIVE_ARITH_P (operands[3])
14460    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14461   "* return output_387_binary_op (insn, operands);"
14462   [(set (attr "type") 
14463         (cond [(match_operand:SF 3 "mult_operator" "") 
14464                  (const_string "fmul")
14465                (match_operand:SF 3 "div_operator" "") 
14466                  (const_string "fdiv")
14467               ]
14468               (const_string "fop")))
14469    (set_attr "mode" "SF")])
14470
14471 (define_insn "*fop_sf_1"
14472   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14473         (match_operator:SF 3 "binary_fp_operator"
14474                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14475                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14476   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14477    && !COMMUTATIVE_ARITH_P (operands[3])
14478    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14479   "* return output_387_binary_op (insn, operands);"
14480   [(set (attr "type") 
14481         (cond [(and (eq_attr "alternative" "2")
14482                     (match_operand:SF 3 "mult_operator" ""))
14483                  (const_string "ssemul")
14484                (and (eq_attr "alternative" "2")
14485                     (match_operand:SF 3 "div_operator" ""))
14486                  (const_string "ssediv")
14487                (eq_attr "alternative" "2")
14488                  (const_string "sseadd")
14489                (match_operand:SF 3 "mult_operator" "") 
14490                  (const_string "fmul")
14491                (match_operand:SF 3 "div_operator" "") 
14492                  (const_string "fdiv")
14493               ]
14494               (const_string "fop")))
14495    (set_attr "mode" "SF")])
14496
14497 (define_insn "*fop_sf_1_sse"
14498   [(set (match_operand:SF 0 "register_operand" "=x")
14499         (match_operator:SF 3 "binary_fp_operator"
14500                         [(match_operand:SF 1 "register_operand" "0")
14501                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14502   "TARGET_SSE_MATH
14503    && !COMMUTATIVE_ARITH_P (operands[3])"
14504   "* return output_387_binary_op (insn, operands);"
14505   [(set (attr "type") 
14506         (cond [(match_operand:SF 3 "mult_operator" "")
14507                  (const_string "ssemul")
14508                (match_operand:SF 3 "div_operator" "")
14509                  (const_string "ssediv")
14510               ]
14511               (const_string "sseadd")))
14512    (set_attr "mode" "SF")])
14513
14514 ;; ??? Add SSE splitters for these!
14515 (define_insn "*fop_sf_2"
14516   [(set (match_operand:SF 0 "register_operand" "=f,f")
14517         (match_operator:SF 3 "binary_fp_operator"
14518           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14519            (match_operand:SF 2 "register_operand" "0,0")]))]
14520   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14521   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14522   [(set (attr "type") 
14523         (cond [(match_operand:SF 3 "mult_operator" "") 
14524                  (const_string "fmul")
14525                (match_operand:SF 3 "div_operator" "") 
14526                  (const_string "fdiv")
14527               ]
14528               (const_string "fop")))
14529    (set_attr "fp_int_src" "true")
14530    (set_attr "mode" "SI")])
14531
14532 (define_insn "*fop_sf_3"
14533   [(set (match_operand:SF 0 "register_operand" "=f,f")
14534         (match_operator:SF 3 "binary_fp_operator"
14535           [(match_operand:SF 1 "register_operand" "0,0")
14536            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14537   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14538   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14539   [(set (attr "type") 
14540         (cond [(match_operand:SF 3 "mult_operator" "") 
14541                  (const_string "fmul")
14542                (match_operand:SF 3 "div_operator" "") 
14543                  (const_string "fdiv")
14544               ]
14545               (const_string "fop")))
14546    (set_attr "fp_int_src" "true")
14547    (set_attr "mode" "SI")])
14548
14549 (define_insn "*fop_df_1_nosse"
14550   [(set (match_operand:DF 0 "register_operand" "=f,f")
14551         (match_operator:DF 3 "binary_fp_operator"
14552                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14553                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14554   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14555    && !COMMUTATIVE_ARITH_P (operands[3])
14556    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14557   "* return output_387_binary_op (insn, operands);"
14558   [(set (attr "type") 
14559         (cond [(match_operand:DF 3 "mult_operator" "") 
14560                  (const_string "fmul")
14561                (match_operand:DF 3 "div_operator" "")
14562                  (const_string "fdiv")
14563               ]
14564               (const_string "fop")))
14565    (set_attr "mode" "DF")])
14566
14567
14568 (define_insn "*fop_df_1"
14569   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14570         (match_operator:DF 3 "binary_fp_operator"
14571                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14572                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14573   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14574    && !COMMUTATIVE_ARITH_P (operands[3])
14575    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14576   "* return output_387_binary_op (insn, operands);"
14577   [(set (attr "type") 
14578         (cond [(and (eq_attr "alternative" "2")
14579                     (match_operand:SF 3 "mult_operator" ""))
14580                  (const_string "ssemul")
14581                (and (eq_attr "alternative" "2")
14582                     (match_operand:SF 3 "div_operator" ""))
14583                  (const_string "ssediv")
14584                (eq_attr "alternative" "2")
14585                  (const_string "sseadd")
14586                (match_operand:DF 3 "mult_operator" "") 
14587                  (const_string "fmul")
14588                (match_operand:DF 3 "div_operator" "") 
14589                  (const_string "fdiv")
14590               ]
14591               (const_string "fop")))
14592    (set_attr "mode" "DF")])
14593
14594 (define_insn "*fop_df_1_sse"
14595   [(set (match_operand:DF 0 "register_operand" "=Y")
14596         (match_operator:DF 3 "binary_fp_operator"
14597                         [(match_operand:DF 1 "register_operand" "0")
14598                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14599   "TARGET_SSE2 && TARGET_SSE_MATH
14600    && !COMMUTATIVE_ARITH_P (operands[3])"
14601   "* return output_387_binary_op (insn, operands);"
14602   [(set_attr "mode" "DF")
14603    (set (attr "type") 
14604         (cond [(match_operand:SF 3 "mult_operator" "")
14605                  (const_string "ssemul")
14606                (match_operand:SF 3 "div_operator" "")
14607                  (const_string "ssediv")
14608               ]
14609               (const_string "sseadd")))])
14610
14611 ;; ??? Add SSE splitters for these!
14612 (define_insn "*fop_df_2"
14613   [(set (match_operand:DF 0 "register_operand" "=f,f")
14614         (match_operator:DF 3 "binary_fp_operator"
14615            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14616             (match_operand:DF 2 "register_operand" "0,0")]))]
14617   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14618   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14619   [(set (attr "type") 
14620         (cond [(match_operand:DF 3 "mult_operator" "") 
14621                  (const_string "fmul")
14622                (match_operand:DF 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_df_3"
14630   [(set (match_operand:DF 0 "register_operand" "=f,f")
14631         (match_operator:DF 3 "binary_fp_operator"
14632            [(match_operand:DF 1 "register_operand" "0,0")
14633             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14634   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14635   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14636   [(set (attr "type") 
14637         (cond [(match_operand:DF 3 "mult_operator" "") 
14638                  (const_string "fmul")
14639                (match_operand:DF 3 "div_operator" "") 
14640                  (const_string "fdiv")
14641               ]
14642               (const_string "fop")))
14643    (set_attr "fp_int_src" "true")
14644    (set_attr "mode" "SI")])
14645
14646 (define_insn "*fop_df_4"
14647   [(set (match_operand:DF 0 "register_operand" "=f,f")
14648         (match_operator:DF 3 "binary_fp_operator"
14649            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14650             (match_operand:DF 2 "register_operand" "0,f")]))]
14651   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14652    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14653   "* return output_387_binary_op (insn, operands);"
14654   [(set (attr "type") 
14655         (cond [(match_operand:DF 3 "mult_operator" "") 
14656                  (const_string "fmul")
14657                (match_operand:DF 3 "div_operator" "") 
14658                  (const_string "fdiv")
14659               ]
14660               (const_string "fop")))
14661    (set_attr "mode" "SF")])
14662
14663 (define_insn "*fop_df_5"
14664   [(set (match_operand:DF 0 "register_operand" "=f,f")
14665         (match_operator:DF 3 "binary_fp_operator"
14666           [(match_operand:DF 1 "register_operand" "0,f")
14667            (float_extend:DF
14668             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14669   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14670   "* return output_387_binary_op (insn, operands);"
14671   [(set (attr "type") 
14672         (cond [(match_operand:DF 3 "mult_operator" "") 
14673                  (const_string "fmul")
14674                (match_operand:DF 3 "div_operator" "") 
14675                  (const_string "fdiv")
14676               ]
14677               (const_string "fop")))
14678    (set_attr "mode" "SF")])
14679
14680 (define_insn "*fop_df_6"
14681   [(set (match_operand:DF 0 "register_operand" "=f,f")
14682         (match_operator:DF 3 "binary_fp_operator"
14683           [(float_extend:DF
14684             (match_operand:SF 1 "register_operand" "0,f"))
14685            (float_extend:DF
14686             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14687   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14688   "* return output_387_binary_op (insn, operands);"
14689   [(set (attr "type") 
14690         (cond [(match_operand:DF 3 "mult_operator" "") 
14691                  (const_string "fmul")
14692                (match_operand:DF 3 "div_operator" "") 
14693                  (const_string "fdiv")
14694               ]
14695               (const_string "fop")))
14696    (set_attr "mode" "SF")])
14697
14698 (define_insn "*fop_xf_1"
14699   [(set (match_operand:XF 0 "register_operand" "=f,f")
14700         (match_operator:XF 3 "binary_fp_operator"
14701                         [(match_operand:XF 1 "register_operand" "0,f")
14702                          (match_operand:XF 2 "register_operand" "f,0")]))]
14703   "TARGET_80387
14704    && !COMMUTATIVE_ARITH_P (operands[3])"
14705   "* return output_387_binary_op (insn, operands);"
14706   [(set (attr "type") 
14707         (cond [(match_operand:XF 3 "mult_operator" "") 
14708                  (const_string "fmul")
14709                (match_operand:XF 3 "div_operator" "") 
14710                  (const_string "fdiv")
14711               ]
14712               (const_string "fop")))
14713    (set_attr "mode" "XF")])
14714
14715 (define_insn "*fop_xf_2"
14716   [(set (match_operand:XF 0 "register_operand" "=f,f")
14717         (match_operator:XF 3 "binary_fp_operator"
14718            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14719             (match_operand:XF 2 "register_operand" "0,0")]))]
14720   "TARGET_80387 && TARGET_USE_FIOP"
14721   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14722   [(set (attr "type") 
14723         (cond [(match_operand:XF 3 "mult_operator" "") 
14724                  (const_string "fmul")
14725                (match_operand:XF 3 "div_operator" "") 
14726                  (const_string "fdiv")
14727               ]
14728               (const_string "fop")))
14729    (set_attr "fp_int_src" "true")
14730    (set_attr "mode" "SI")])
14731
14732 (define_insn "*fop_xf_3"
14733   [(set (match_operand:XF 0 "register_operand" "=f,f")
14734         (match_operator:XF 3 "binary_fp_operator"
14735           [(match_operand:XF 1 "register_operand" "0,0")
14736            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14737   "TARGET_80387 && TARGET_USE_FIOP"
14738   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14739   [(set (attr "type") 
14740         (cond [(match_operand:XF 3 "mult_operator" "") 
14741                  (const_string "fmul")
14742                (match_operand:XF 3 "div_operator" "") 
14743                  (const_string "fdiv")
14744               ]
14745               (const_string "fop")))
14746    (set_attr "fp_int_src" "true")
14747    (set_attr "mode" "SI")])
14748
14749 (define_insn "*fop_xf_4"
14750   [(set (match_operand:XF 0 "register_operand" "=f,f")
14751         (match_operator:XF 3 "binary_fp_operator"
14752            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14753             (match_operand:XF 2 "register_operand" "0,f")]))]
14754   "TARGET_80387"
14755   "* return output_387_binary_op (insn, operands);"
14756   [(set (attr "type") 
14757         (cond [(match_operand:XF 3 "mult_operator" "") 
14758                  (const_string "fmul")
14759                (match_operand:XF 3 "div_operator" "") 
14760                  (const_string "fdiv")
14761               ]
14762               (const_string "fop")))
14763    (set_attr "mode" "SF")])
14764
14765 (define_insn "*fop_xf_5"
14766   [(set (match_operand:XF 0 "register_operand" "=f,f")
14767         (match_operator:XF 3 "binary_fp_operator"
14768           [(match_operand:XF 1 "register_operand" "0,f")
14769            (float_extend:XF
14770             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14771   "TARGET_80387"
14772   "* return output_387_binary_op (insn, operands);"
14773   [(set (attr "type") 
14774         (cond [(match_operand:XF 3 "mult_operator" "") 
14775                  (const_string "fmul")
14776                (match_operand:XF 3 "div_operator" "") 
14777                  (const_string "fdiv")
14778               ]
14779               (const_string "fop")))
14780    (set_attr "mode" "SF")])
14781
14782 (define_insn "*fop_xf_6"
14783   [(set (match_operand:XF 0 "register_operand" "=f,f")
14784         (match_operator:XF 3 "binary_fp_operator"
14785           [(float_extend:XF
14786             (match_operand 1 "register_operand" "0,f"))
14787            (float_extend:XF
14788             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14789   "TARGET_80387"
14790   "* return output_387_binary_op (insn, operands);"
14791   [(set (attr "type") 
14792         (cond [(match_operand:XF 3 "mult_operator" "") 
14793                  (const_string "fmul")
14794                (match_operand:XF 3 "div_operator" "") 
14795                  (const_string "fdiv")
14796               ]
14797               (const_string "fop")))
14798    (set_attr "mode" "SF")])
14799
14800 (define_split
14801   [(set (match_operand 0 "register_operand" "")
14802         (match_operator 3 "binary_fp_operator"
14803            [(float (match_operand:SI 1 "register_operand" ""))
14804             (match_operand 2 "register_operand" "")]))]
14805   "TARGET_80387 && reload_completed
14806    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14807   [(const_int 0)]
14808
14809   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14810   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14811   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14812                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14813                                           GET_MODE (operands[3]),
14814                                           operands[4],
14815                                           operands[2])));
14816   ix86_free_from_memory (GET_MODE (operands[1]));
14817   DONE;
14818 })
14819
14820 (define_split
14821   [(set (match_operand 0 "register_operand" "")
14822         (match_operator 3 "binary_fp_operator"
14823            [(match_operand 1 "register_operand" "")
14824             (float (match_operand:SI 2 "register_operand" ""))]))]
14825   "TARGET_80387 && reload_completed
14826    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14827   [(const_int 0)]
14828 {
14829   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14830   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14831   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14832                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14833                                           GET_MODE (operands[3]),
14834                                           operands[1],
14835                                           operands[4])));
14836   ix86_free_from_memory (GET_MODE (operands[2]));
14837   DONE;
14838 })
14839 \f
14840 ;; FPU special functions.
14841
14842 (define_expand "sqrtsf2"
14843   [(set (match_operand:SF 0 "register_operand" "")
14844         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14845   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14846 {
14847   if (!TARGET_SSE_MATH)
14848     operands[1] = force_reg (SFmode, operands[1]);
14849 })
14850
14851 (define_insn "sqrtsf2_1"
14852   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14853         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14854   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14855    && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14856   "@
14857    fsqrt
14858    sqrtss\t{%1, %0|%0, %1}"
14859   [(set_attr "type" "fpspc,sse")
14860    (set_attr "mode" "SF,SF")
14861    (set_attr "athlon_decode" "direct,*")])
14862
14863 (define_insn "sqrtsf2_1_sse_only"
14864   [(set (match_operand:SF 0 "register_operand" "=x")
14865         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14866   "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14867   "sqrtss\t{%1, %0|%0, %1}"
14868   [(set_attr "type" "sse")
14869    (set_attr "mode" "SF")
14870    (set_attr "athlon_decode" "*")])
14871
14872 (define_insn "sqrtsf2_i387"
14873   [(set (match_operand:SF 0 "register_operand" "=f")
14874         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14875   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14876    && !TARGET_SSE_MATH"
14877   "fsqrt"
14878   [(set_attr "type" "fpspc")
14879    (set_attr "mode" "SF")
14880    (set_attr "athlon_decode" "direct")])
14881
14882 (define_expand "sqrtdf2"
14883   [(set (match_operand:DF 0 "register_operand" "")
14884         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14885   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14886    || (TARGET_SSE2 && TARGET_SSE_MATH)"
14887 {
14888   if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14889     operands[1] = force_reg (DFmode, operands[1]);
14890 })
14891
14892 (define_insn "sqrtdf2_1"
14893   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14894         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14895   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14896    && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14897   "@
14898    fsqrt
14899    sqrtsd\t{%1, %0|%0, %1}"
14900   [(set_attr "type" "fpspc,sse")
14901    (set_attr "mode" "DF,DF")
14902    (set_attr "athlon_decode" "direct,*")])
14903
14904 (define_insn "sqrtdf2_1_sse_only"
14905   [(set (match_operand:DF 0 "register_operand" "=Y")
14906         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14907   "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14908   "sqrtsd\t{%1, %0|%0, %1}"
14909   [(set_attr "type" "sse")
14910    (set_attr "mode" "DF")
14911    (set_attr "athlon_decode" "*")])
14912
14913 (define_insn "sqrtdf2_i387"
14914   [(set (match_operand:DF 0 "register_operand" "=f")
14915         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14916   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14917    && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14918   "fsqrt"
14919   [(set_attr "type" "fpspc")
14920    (set_attr "mode" "DF")
14921    (set_attr "athlon_decode" "direct")])
14922
14923 (define_insn "*sqrtextendsfdf2"
14924   [(set (match_operand:DF 0 "register_operand" "=f")
14925         (sqrt:DF (float_extend:DF
14926                   (match_operand:SF 1 "register_operand" "0"))))]
14927   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14928    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14929   "fsqrt"
14930   [(set_attr "type" "fpspc")
14931    (set_attr "mode" "DF")
14932    (set_attr "athlon_decode" "direct")])
14933
14934 (define_insn "sqrtxf2"
14935   [(set (match_operand:XF 0 "register_operand" "=f")
14936         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14937   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387 
14938    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14939   "fsqrt"
14940   [(set_attr "type" "fpspc")
14941    (set_attr "mode" "XF")
14942    (set_attr "athlon_decode" "direct")])
14943
14944 (define_insn "*sqrtextenddfxf2"
14945   [(set (match_operand:XF 0 "register_operand" "=f")
14946         (sqrt:XF (float_extend:XF
14947                   (match_operand:DF 1 "register_operand" "0"))))]
14948   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14949   "fsqrt"
14950   [(set_attr "type" "fpspc")
14951    (set_attr "mode" "XF")
14952    (set_attr "athlon_decode" "direct")])
14953
14954 (define_insn "*sqrtextendsfxf2"
14955   [(set (match_operand:XF 0 "register_operand" "=f")
14956         (sqrt:XF (float_extend:XF
14957                   (match_operand:SF 1 "register_operand" "0"))))]
14958   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14959   "fsqrt"
14960   [(set_attr "type" "fpspc")
14961    (set_attr "mode" "XF")
14962    (set_attr "athlon_decode" "direct")])
14963
14964 (define_insn "fpremxf4"
14965   [(set (match_operand:XF 0 "register_operand" "=f")
14966         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14967                     (match_operand:XF 3 "register_operand" "1")]
14968                    UNSPEC_FPREM_F))
14969    (set (match_operand:XF 1 "register_operand" "=u")
14970         (unspec:XF [(match_dup 2) (match_dup 3)]
14971                    UNSPEC_FPREM_U))
14972    (set (reg:CCFP FPSR_REG)
14973         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14974   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14975    && flag_unsafe_math_optimizations"
14976   "fprem"
14977   [(set_attr "type" "fpspc")
14978    (set_attr "mode" "XF")])
14979
14980 (define_expand "fmodsf3"
14981   [(use (match_operand:SF 0 "register_operand" ""))
14982    (use (match_operand:SF 1 "register_operand" ""))
14983    (use (match_operand:SF 2 "register_operand" ""))]
14984   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14985    && flag_unsafe_math_optimizations"
14986 {
14987   rtx label = gen_label_rtx ();
14988
14989   rtx op1 = gen_reg_rtx (XFmode);
14990   rtx op2 = gen_reg_rtx (XFmode);
14991
14992   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14993   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14994
14995   emit_label (label);
14996
14997   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14998   ix86_emit_fp_unordered_jump (label);
14999
15000   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15001   DONE;
15002 })
15003
15004 (define_expand "fmoddf3"
15005   [(use (match_operand:DF 0 "register_operand" ""))
15006    (use (match_operand:DF 1 "register_operand" ""))
15007    (use (match_operand:DF 2 "register_operand" ""))]
15008   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15009    && flag_unsafe_math_optimizations"
15010 {
15011   rtx label = gen_label_rtx ();
15012
15013   rtx op1 = gen_reg_rtx (XFmode);
15014   rtx op2 = gen_reg_rtx (XFmode);
15015
15016   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15017   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15018
15019   emit_label (label);
15020
15021   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15022   ix86_emit_fp_unordered_jump (label);
15023
15024   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15025   DONE;
15026 })
15027
15028 (define_expand "fmodxf3"
15029   [(use (match_operand:XF 0 "register_operand" ""))
15030    (use (match_operand:XF 1 "register_operand" ""))
15031    (use (match_operand:XF 2 "register_operand" ""))]
15032   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15033    && flag_unsafe_math_optimizations"
15034 {
15035   rtx label = gen_label_rtx ();
15036
15037   emit_label (label);
15038
15039   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15040                            operands[1], operands[2]));
15041   ix86_emit_fp_unordered_jump (label);
15042
15043   emit_move_insn (operands[0], operands[1]);
15044   DONE;
15045 })
15046
15047 (define_insn "fprem1xf4"
15048   [(set (match_operand:XF 0 "register_operand" "=f")
15049         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15050                     (match_operand:XF 3 "register_operand" "1")]
15051                    UNSPEC_FPREM1_F))
15052    (set (match_operand:XF 1 "register_operand" "=u")
15053         (unspec:XF [(match_dup 2) (match_dup 3)]
15054                    UNSPEC_FPREM1_U))
15055    (set (reg:CCFP FPSR_REG)
15056         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15057   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15058    && flag_unsafe_math_optimizations"
15059   "fprem1"
15060   [(set_attr "type" "fpspc")
15061    (set_attr "mode" "XF")])
15062
15063 (define_expand "dremsf3"
15064   [(use (match_operand:SF 0 "register_operand" ""))
15065    (use (match_operand:SF 1 "register_operand" ""))
15066    (use (match_operand:SF 2 "register_operand" ""))]
15067   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15068    && flag_unsafe_math_optimizations"
15069 {
15070   rtx label = gen_label_rtx ();
15071
15072   rtx op1 = gen_reg_rtx (XFmode);
15073   rtx op2 = gen_reg_rtx (XFmode);
15074
15075   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15076   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15077
15078   emit_label (label);
15079
15080   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15081   ix86_emit_fp_unordered_jump (label);
15082
15083   emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15084   DONE;
15085 })
15086
15087 (define_expand "dremdf3"
15088   [(use (match_operand:DF 0 "register_operand" ""))
15089    (use (match_operand:DF 1 "register_operand" ""))
15090    (use (match_operand:DF 2 "register_operand" ""))]
15091   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15092    && flag_unsafe_math_optimizations"
15093 {
15094   rtx label = gen_label_rtx ();
15095
15096   rtx op1 = gen_reg_rtx (XFmode);
15097   rtx op2 = gen_reg_rtx (XFmode);
15098
15099   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15100   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15101
15102   emit_label (label);
15103
15104   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15105   ix86_emit_fp_unordered_jump (label);
15106
15107   emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15108   DONE;
15109 })
15110
15111 (define_expand "dremxf3"
15112   [(use (match_operand:XF 0 "register_operand" ""))
15113    (use (match_operand:XF 1 "register_operand" ""))
15114    (use (match_operand:XF 2 "register_operand" ""))]
15115   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15116    && flag_unsafe_math_optimizations"
15117 {
15118   rtx label = gen_label_rtx ();
15119
15120   emit_label (label);
15121
15122   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15123                             operands[1], operands[2]));
15124   ix86_emit_fp_unordered_jump (label);
15125
15126   emit_move_insn (operands[0], operands[1]);
15127   DONE;
15128 })
15129
15130 (define_insn "*sindf2"
15131   [(set (match_operand:DF 0 "register_operand" "=f")
15132         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15133   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15134    && flag_unsafe_math_optimizations"
15135   "fsin"
15136   [(set_attr "type" "fpspc")
15137    (set_attr "mode" "DF")])
15138
15139 (define_insn "*sinsf2"
15140   [(set (match_operand:SF 0 "register_operand" "=f")
15141         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15142   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15143    && flag_unsafe_math_optimizations"
15144   "fsin"
15145   [(set_attr "type" "fpspc")
15146    (set_attr "mode" "SF")])
15147
15148 (define_insn "*sinextendsfdf2"
15149   [(set (match_operand:DF 0 "register_operand" "=f")
15150         (unspec:DF [(float_extend:DF
15151                      (match_operand:SF 1 "register_operand" "0"))]
15152                    UNSPEC_SIN))]
15153   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15154    && flag_unsafe_math_optimizations"
15155   "fsin"
15156   [(set_attr "type" "fpspc")
15157    (set_attr "mode" "DF")])
15158
15159 (define_insn "*sinxf2"
15160   [(set (match_operand:XF 0 "register_operand" "=f")
15161         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15162   "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15163    && flag_unsafe_math_optimizations"
15164   "fsin"
15165   [(set_attr "type" "fpspc")
15166    (set_attr "mode" "XF")])
15167
15168 (define_insn "*cosdf2"
15169   [(set (match_operand:DF 0 "register_operand" "=f")
15170         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15171   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15172    && flag_unsafe_math_optimizations"
15173   "fcos"
15174   [(set_attr "type" "fpspc")
15175    (set_attr "mode" "DF")])
15176
15177 (define_insn "*cossf2"
15178   [(set (match_operand:SF 0 "register_operand" "=f")
15179         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15180   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15181    && flag_unsafe_math_optimizations"
15182   "fcos"
15183   [(set_attr "type" "fpspc")
15184    (set_attr "mode" "SF")])
15185
15186 (define_insn "*cosextendsfdf2"
15187   [(set (match_operand:DF 0 "register_operand" "=f")
15188         (unspec:DF [(float_extend:DF
15189                      (match_operand:SF 1 "register_operand" "0"))]
15190                    UNSPEC_COS))]
15191   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15192    && flag_unsafe_math_optimizations"
15193   "fcos"
15194   [(set_attr "type" "fpspc")
15195    (set_attr "mode" "DF")])
15196
15197 (define_insn "*cosxf2"
15198   [(set (match_operand:XF 0 "register_operand" "=f")
15199         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15200   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15201    && flag_unsafe_math_optimizations"
15202   "fcos"
15203   [(set_attr "type" "fpspc")
15204    (set_attr "mode" "XF")])
15205
15206 ;; With sincos pattern defined, sin and cos builtin function will be
15207 ;; expanded to sincos pattern with one of its outputs left unused. 
15208 ;; Cse pass  will detected, if two sincos patterns can be combined,
15209 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15210 ;; depending on the unused output.
15211
15212 (define_insn "sincosdf3"
15213   [(set (match_operand:DF 0 "register_operand" "=f")
15214         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15215                    UNSPEC_SINCOS_COS))
15216    (set (match_operand:DF 1 "register_operand" "=u")
15217         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15218   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15219    && flag_unsafe_math_optimizations"
15220   "fsincos"
15221   [(set_attr "type" "fpspc")
15222    (set_attr "mode" "DF")])
15223
15224 (define_split
15225   [(set (match_operand:DF 0 "register_operand" "")
15226         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15227                    UNSPEC_SINCOS_COS))
15228    (set (match_operand:DF 1 "register_operand" "")
15229         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15230   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15231    && !reload_completed && !reload_in_progress"
15232   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15233   "")
15234
15235 (define_split
15236   [(set (match_operand:DF 0 "register_operand" "")
15237         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15238                    UNSPEC_SINCOS_COS))
15239    (set (match_operand:DF 1 "register_operand" "")
15240         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15241   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15242    && !reload_completed && !reload_in_progress"
15243   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15244   "")
15245
15246 (define_insn "sincossf3"
15247   [(set (match_operand:SF 0 "register_operand" "=f")
15248         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15249                    UNSPEC_SINCOS_COS))
15250    (set (match_operand:SF 1 "register_operand" "=u")
15251         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15252   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15253    && flag_unsafe_math_optimizations"
15254   "fsincos"
15255   [(set_attr "type" "fpspc")
15256    (set_attr "mode" "SF")])
15257
15258 (define_split
15259   [(set (match_operand:SF 0 "register_operand" "")
15260         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15261                    UNSPEC_SINCOS_COS))
15262    (set (match_operand:SF 1 "register_operand" "")
15263         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15264   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15265    && !reload_completed && !reload_in_progress"
15266   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15267   "")
15268
15269 (define_split
15270   [(set (match_operand:SF 0 "register_operand" "")
15271         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15272                    UNSPEC_SINCOS_COS))
15273    (set (match_operand:SF 1 "register_operand" "")
15274         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15275   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15276    && !reload_completed && !reload_in_progress"
15277   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15278   "")
15279
15280 (define_insn "*sincosextendsfdf3"
15281   [(set (match_operand:DF 0 "register_operand" "=f")
15282         (unspec:DF [(float_extend:DF
15283                      (match_operand:SF 2 "register_operand" "0"))]
15284                    UNSPEC_SINCOS_COS))
15285    (set (match_operand:DF 1 "register_operand" "=u")
15286         (unspec:DF [(float_extend:DF
15287                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15288   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15289    && flag_unsafe_math_optimizations"
15290   "fsincos"
15291   [(set_attr "type" "fpspc")
15292    (set_attr "mode" "DF")])
15293
15294 (define_split
15295   [(set (match_operand:DF 0 "register_operand" "")
15296         (unspec:DF [(float_extend:DF
15297                      (match_operand:SF 2 "register_operand" ""))]
15298                    UNSPEC_SINCOS_COS))
15299    (set (match_operand:DF 1 "register_operand" "")
15300         (unspec:DF [(float_extend:DF
15301                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15302   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15303    && !reload_completed && !reload_in_progress"
15304   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15305                                    (match_dup 2))] UNSPEC_SIN))]
15306   "")
15307
15308 (define_split
15309   [(set (match_operand:DF 0 "register_operand" "")
15310         (unspec:DF [(float_extend:DF
15311                      (match_operand:SF 2 "register_operand" ""))]
15312                    UNSPEC_SINCOS_COS))
15313    (set (match_operand:DF 1 "register_operand" "")
15314         (unspec:DF [(float_extend:DF
15315                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15316   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15317    && !reload_completed && !reload_in_progress"
15318   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15319                                    (match_dup 2))] UNSPEC_COS))]
15320   "")
15321
15322 (define_insn "sincosxf3"
15323   [(set (match_operand:XF 0 "register_operand" "=f")
15324         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15325                    UNSPEC_SINCOS_COS))
15326    (set (match_operand:XF 1 "register_operand" "=u")
15327         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15328   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15329    && flag_unsafe_math_optimizations"
15330   "fsincos"
15331   [(set_attr "type" "fpspc")
15332    (set_attr "mode" "XF")])
15333
15334 (define_split
15335   [(set (match_operand:XF 0 "register_operand" "")
15336         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15337                    UNSPEC_SINCOS_COS))
15338    (set (match_operand:XF 1 "register_operand" "")
15339         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15340   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15341    && !reload_completed && !reload_in_progress"
15342   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15343   "")
15344
15345 (define_split
15346   [(set (match_operand:XF 0 "register_operand" "")
15347         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15348                    UNSPEC_SINCOS_COS))
15349    (set (match_operand:XF 1 "register_operand" "")
15350         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15351   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15352    && !reload_completed && !reload_in_progress"
15353   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15354   "")
15355
15356 (define_insn "*tandf3_1"
15357   [(set (match_operand:DF 0 "register_operand" "=f")
15358         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15359                    UNSPEC_TAN_ONE))
15360    (set (match_operand:DF 1 "register_operand" "=u")
15361         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15362   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15363    && flag_unsafe_math_optimizations"
15364   "fptan"
15365   [(set_attr "type" "fpspc")
15366    (set_attr "mode" "DF")])
15367
15368 ;; optimize sequence: fptan
15369 ;;                    fstp    %st(0)
15370 ;;                    fld1
15371 ;; into fptan insn.
15372
15373 (define_peephole2
15374   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15375                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15376                              UNSPEC_TAN_ONE))
15377              (set (match_operand:DF 1 "register_operand" "")
15378                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15379    (set (match_dup 0)
15380         (match_operand:DF 3 "immediate_operand" ""))]
15381   "standard_80387_constant_p (operands[3]) == 2"
15382   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15383              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15384   "")
15385
15386 (define_expand "tandf2"
15387   [(parallel [(set (match_dup 2)
15388                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15389                               UNSPEC_TAN_ONE))
15390               (set (match_operand:DF 0 "register_operand" "")
15391                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15392   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15393    && flag_unsafe_math_optimizations"
15394 {
15395   operands[2] = gen_reg_rtx (DFmode);
15396 })
15397
15398 (define_insn "*tansf3_1"
15399   [(set (match_operand:SF 0 "register_operand" "=f")
15400         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15401                    UNSPEC_TAN_ONE))
15402    (set (match_operand:SF 1 "register_operand" "=u")
15403         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15404   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15405    && flag_unsafe_math_optimizations"
15406   "fptan"
15407   [(set_attr "type" "fpspc")
15408    (set_attr "mode" "SF")])
15409
15410 ;; optimize sequence: fptan
15411 ;;                    fstp    %st(0)
15412 ;;                    fld1
15413 ;; into fptan insn.
15414
15415 (define_peephole2
15416   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15417                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15418                              UNSPEC_TAN_ONE))
15419              (set (match_operand:SF 1 "register_operand" "")
15420                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15421    (set (match_dup 0)
15422         (match_operand:SF 3 "immediate_operand" ""))]
15423   "standard_80387_constant_p (operands[3]) == 2"
15424   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15425              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15426   "")
15427
15428 (define_expand "tansf2"
15429   [(parallel [(set (match_dup 2)
15430                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15431                               UNSPEC_TAN_ONE))
15432               (set (match_operand:SF 0 "register_operand" "")
15433                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15434   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15435    && flag_unsafe_math_optimizations"
15436 {
15437   operands[2] = gen_reg_rtx (SFmode);
15438 })
15439
15440 (define_insn "*tanxf3_1"
15441   [(set (match_operand:XF 0 "register_operand" "=f")
15442         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15443                    UNSPEC_TAN_ONE))
15444    (set (match_operand:XF 1 "register_operand" "=u")
15445         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15446   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15447    && flag_unsafe_math_optimizations"
15448   "fptan"
15449   [(set_attr "type" "fpspc")
15450    (set_attr "mode" "XF")])
15451
15452 ;; optimize sequence: fptan
15453 ;;                    fstp    %st(0)
15454 ;;                    fld1
15455 ;; into fptan insn.
15456
15457 (define_peephole2
15458   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15459                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15460                              UNSPEC_TAN_ONE))
15461              (set (match_operand:XF 1 "register_operand" "")
15462                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15463    (set (match_dup 0)
15464         (match_operand:XF 3 "immediate_operand" ""))]
15465   "standard_80387_constant_p (operands[3]) == 2"
15466   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15467              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15468   "")
15469
15470 (define_expand "tanxf2"
15471   [(parallel [(set (match_dup 2)
15472                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15473                               UNSPEC_TAN_ONE))
15474               (set (match_operand:XF 0 "register_operand" "")
15475                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15476   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15477    && flag_unsafe_math_optimizations"
15478 {
15479   operands[2] = gen_reg_rtx (XFmode);
15480 })
15481
15482 (define_insn "atan2df3_1"
15483   [(set (match_operand:DF 0 "register_operand" "=f")
15484         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15485                     (match_operand:DF 1 "register_operand" "u")]
15486                    UNSPEC_FPATAN))
15487    (clobber (match_scratch:DF 3 "=1"))]
15488   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15489    && flag_unsafe_math_optimizations"
15490   "fpatan"
15491   [(set_attr "type" "fpspc")
15492    (set_attr "mode" "DF")])
15493
15494 (define_expand "atan2df3"
15495   [(use (match_operand:DF 0 "register_operand" "=f"))
15496    (use (match_operand:DF 2 "register_operand" "0"))
15497    (use (match_operand:DF 1 "register_operand" "u"))]
15498   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15499    && flag_unsafe_math_optimizations"
15500 {
15501   rtx copy = gen_reg_rtx (DFmode);
15502   emit_move_insn (copy, operands[1]);
15503   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15504   DONE;
15505 })
15506
15507 (define_expand "atandf2"
15508   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15509                    (unspec:DF [(match_dup 2)
15510                                (match_operand:DF 1 "register_operand" "")]
15511                     UNSPEC_FPATAN))
15512               (clobber (match_scratch:DF 3 ""))])]
15513   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15514    && flag_unsafe_math_optimizations"
15515 {
15516   operands[2] = gen_reg_rtx (DFmode);
15517   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15518 })
15519
15520 (define_insn "atan2sf3_1"
15521   [(set (match_operand:SF 0 "register_operand" "=f")
15522         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15523                     (match_operand:SF 1 "register_operand" "u")]
15524                    UNSPEC_FPATAN))
15525    (clobber (match_scratch:SF 3 "=1"))]
15526   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15527    && flag_unsafe_math_optimizations"
15528   "fpatan"
15529   [(set_attr "type" "fpspc")
15530    (set_attr "mode" "SF")])
15531
15532 (define_expand "atan2sf3"
15533   [(use (match_operand:SF 0 "register_operand" "=f"))
15534    (use (match_operand:SF 2 "register_operand" "0"))
15535    (use (match_operand:SF 1 "register_operand" "u"))]
15536   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15537    && flag_unsafe_math_optimizations"
15538 {
15539   rtx copy = gen_reg_rtx (SFmode);
15540   emit_move_insn (copy, operands[1]);
15541   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15542   DONE;
15543 })
15544
15545 (define_expand "atansf2"
15546   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15547                    (unspec:SF [(match_dup 2)
15548                                (match_operand:SF 1 "register_operand" "")]
15549                     UNSPEC_FPATAN))
15550               (clobber (match_scratch:SF 3 ""))])]
15551   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15552    && flag_unsafe_math_optimizations"
15553 {
15554   operands[2] = gen_reg_rtx (SFmode);
15555   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15556 })
15557
15558 (define_insn "atan2xf3_1"
15559   [(set (match_operand:XF 0 "register_operand" "=f")
15560         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15561                     (match_operand:XF 1 "register_operand" "u")]
15562                    UNSPEC_FPATAN))
15563    (clobber (match_scratch:XF 3 "=1"))]
15564   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15565    && flag_unsafe_math_optimizations"
15566   "fpatan"
15567   [(set_attr "type" "fpspc")
15568    (set_attr "mode" "XF")])
15569
15570 (define_expand "atan2xf3"
15571   [(use (match_operand:XF 0 "register_operand" "=f"))
15572    (use (match_operand:XF 2 "register_operand" "0"))
15573    (use (match_operand:XF 1 "register_operand" "u"))]
15574   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15575    && flag_unsafe_math_optimizations"
15576 {
15577   rtx copy = gen_reg_rtx (XFmode);
15578   emit_move_insn (copy, operands[1]);
15579   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15580   DONE;
15581 })
15582
15583 (define_expand "atanxf2"
15584   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15585                    (unspec:XF [(match_dup 2)
15586                                (match_operand:XF 1 "register_operand" "")]
15587                     UNSPEC_FPATAN))
15588               (clobber (match_scratch:XF 3 ""))])]
15589   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15590    && flag_unsafe_math_optimizations"
15591 {
15592   operands[2] = gen_reg_rtx (XFmode);
15593   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15594 })
15595
15596 (define_expand "asindf2"
15597   [(set (match_dup 2)
15598         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15599    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15600    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15601    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15602    (parallel [(set (match_dup 7)
15603                    (unspec:XF [(match_dup 6) (match_dup 2)]
15604                               UNSPEC_FPATAN))
15605               (clobber (match_scratch:XF 8 ""))])
15606    (set (match_operand:DF 0 "register_operand" "")
15607         (float_truncate:DF (match_dup 7)))]
15608   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15609    && flag_unsafe_math_optimizations"
15610 {
15611   int i;
15612
15613   for (i=2; i<8; i++)
15614     operands[i] = gen_reg_rtx (XFmode);
15615
15616   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15617 })
15618
15619 (define_expand "asinsf2"
15620   [(set (match_dup 2)
15621         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15622    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15623    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15624    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15625    (parallel [(set (match_dup 7)
15626                    (unspec:XF [(match_dup 6) (match_dup 2)]
15627                               UNSPEC_FPATAN))
15628               (clobber (match_scratch:XF 8 ""))])
15629    (set (match_operand:SF 0 "register_operand" "")
15630         (float_truncate:SF (match_dup 7)))]
15631   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15632    && flag_unsafe_math_optimizations"
15633 {
15634   int i;
15635
15636   for (i=2; i<8; i++)
15637     operands[i] = gen_reg_rtx (XFmode);
15638
15639   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15640 })
15641
15642 (define_expand "asinxf2"
15643   [(set (match_dup 2)
15644         (mult:XF (match_operand:XF 1 "register_operand" "")
15645                  (match_dup 1)))
15646    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15647    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15648    (parallel [(set (match_operand:XF 0 "register_operand" "")
15649                    (unspec:XF [(match_dup 5) (match_dup 1)]
15650                               UNSPEC_FPATAN))
15651               (clobber (match_scratch:XF 6 ""))])]
15652   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15653    && flag_unsafe_math_optimizations"
15654 {
15655   int i;
15656
15657   for (i=2; i<6; i++)
15658     operands[i] = gen_reg_rtx (XFmode);
15659
15660   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15661 })
15662
15663 (define_expand "acosdf2"
15664   [(set (match_dup 2)
15665         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15666    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15667    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15668    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15669    (parallel [(set (match_dup 7)
15670                    (unspec:XF [(match_dup 2) (match_dup 6)]
15671                               UNSPEC_FPATAN))
15672               (clobber (match_scratch:XF 8 ""))])
15673    (set (match_operand:DF 0 "register_operand" "")
15674         (float_truncate:DF (match_dup 7)))]
15675   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15676    && flag_unsafe_math_optimizations"
15677 {
15678   int i;
15679
15680   for (i=2; i<8; i++)
15681     operands[i] = gen_reg_rtx (XFmode);
15682
15683   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15684 })
15685
15686 (define_expand "acossf2"
15687   [(set (match_dup 2)
15688         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15689    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15690    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15691    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15692    (parallel [(set (match_dup 7)
15693                    (unspec:XF [(match_dup 2) (match_dup 6)]
15694                               UNSPEC_FPATAN))
15695               (clobber (match_scratch:XF 8 ""))])
15696    (set (match_operand:SF 0 "register_operand" "")
15697         (float_truncate:SF (match_dup 7)))]
15698   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15699    && flag_unsafe_math_optimizations"
15700 {
15701   int i;
15702
15703   for (i=2; i<8; i++)
15704     operands[i] = gen_reg_rtx (XFmode);
15705
15706   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15707 })
15708
15709 (define_expand "acosxf2"
15710   [(set (match_dup 2)
15711         (mult:XF (match_operand:XF 1 "register_operand" "")
15712                  (match_dup 1)))
15713    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15714    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15715    (parallel [(set (match_operand:XF 0 "register_operand" "")
15716                    (unspec:XF [(match_dup 1) (match_dup 5)]
15717                               UNSPEC_FPATAN))
15718               (clobber (match_scratch:XF 6 ""))])]
15719   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15720    && flag_unsafe_math_optimizations"
15721 {
15722   int i;
15723
15724   for (i=2; i<6; i++)
15725     operands[i] = gen_reg_rtx (XFmode);
15726
15727   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15728 })
15729
15730 (define_insn "fyl2x_xf3"
15731   [(set (match_operand:XF 0 "register_operand" "=f")
15732         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15733                     (match_operand:XF 1 "register_operand" "u")]
15734                    UNSPEC_FYL2X))
15735    (clobber (match_scratch:XF 3 "=1"))]
15736   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15737    && flag_unsafe_math_optimizations"
15738   "fyl2x"
15739   [(set_attr "type" "fpspc")
15740    (set_attr "mode" "XF")])
15741
15742 (define_expand "logsf2"
15743   [(set (match_dup 2)
15744         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15745    (parallel [(set (match_dup 4)
15746                    (unspec:XF [(match_dup 2)
15747                                (match_dup 3)] UNSPEC_FYL2X))
15748               (clobber (match_scratch:XF 5 ""))])
15749    (set (match_operand:SF 0 "register_operand" "")
15750         (float_truncate:SF (match_dup 4)))]
15751   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15752    && flag_unsafe_math_optimizations"
15753 {
15754   rtx temp;
15755
15756   operands[2] = gen_reg_rtx (XFmode);
15757   operands[3] = gen_reg_rtx (XFmode);
15758   operands[4] = gen_reg_rtx (XFmode);
15759
15760   temp = standard_80387_constant_rtx (4); /* fldln2 */
15761   emit_move_insn (operands[3], temp);
15762 })
15763
15764 (define_expand "logdf2"
15765   [(set (match_dup 2)
15766         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15767    (parallel [(set (match_dup 4)
15768                    (unspec:XF [(match_dup 2)
15769                                (match_dup 3)] UNSPEC_FYL2X))
15770               (clobber (match_scratch:XF 5 ""))])
15771    (set (match_operand:DF 0 "register_operand" "")
15772         (float_truncate:DF (match_dup 4)))]
15773   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15774    && flag_unsafe_math_optimizations"
15775 {
15776   rtx temp;
15777
15778   operands[2] = gen_reg_rtx (XFmode);
15779   operands[3] = gen_reg_rtx (XFmode);
15780   operands[4] = gen_reg_rtx (XFmode);
15781
15782   temp = standard_80387_constant_rtx (4); /* fldln2 */
15783   emit_move_insn (operands[3], temp);
15784 })
15785
15786 (define_expand "logxf2"
15787   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15788                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15789                                (match_dup 2)] UNSPEC_FYL2X))
15790               (clobber (match_scratch:XF 3 ""))])]
15791   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15792    && flag_unsafe_math_optimizations"
15793 {
15794   rtx temp;
15795
15796   operands[2] = gen_reg_rtx (XFmode);
15797   temp = standard_80387_constant_rtx (4); /* fldln2 */
15798   emit_move_insn (operands[2], temp);
15799 })
15800
15801 (define_expand "log10sf2"
15802   [(set (match_dup 2)
15803         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15804    (parallel [(set (match_dup 4)
15805                    (unspec:XF [(match_dup 2)
15806                                (match_dup 3)] UNSPEC_FYL2X))
15807               (clobber (match_scratch:XF 5 ""))])
15808    (set (match_operand:SF 0 "register_operand" "")
15809         (float_truncate:SF (match_dup 4)))]
15810   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15811    && flag_unsafe_math_optimizations"
15812 {
15813   rtx temp;
15814
15815   operands[2] = gen_reg_rtx (XFmode);
15816   operands[3] = gen_reg_rtx (XFmode);
15817   operands[4] = gen_reg_rtx (XFmode);
15818
15819   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15820   emit_move_insn (operands[3], temp);
15821 })
15822
15823 (define_expand "log10df2"
15824   [(set (match_dup 2)
15825         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15826    (parallel [(set (match_dup 4)
15827                    (unspec:XF [(match_dup 2)
15828                                (match_dup 3)] UNSPEC_FYL2X))
15829               (clobber (match_scratch:XF 5 ""))])
15830    (set (match_operand:DF 0 "register_operand" "")
15831         (float_truncate:DF (match_dup 4)))]
15832   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15833    && flag_unsafe_math_optimizations"
15834 {
15835   rtx temp;
15836
15837   operands[2] = gen_reg_rtx (XFmode);
15838   operands[3] = gen_reg_rtx (XFmode);
15839   operands[4] = gen_reg_rtx (XFmode);
15840
15841   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15842   emit_move_insn (operands[3], temp);
15843 })
15844
15845 (define_expand "log10xf2"
15846   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15847                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15848                                (match_dup 2)] UNSPEC_FYL2X))
15849               (clobber (match_scratch:XF 3 ""))])]
15850   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15851    && flag_unsafe_math_optimizations"
15852 {
15853   rtx temp;
15854
15855   operands[2] = gen_reg_rtx (XFmode);
15856   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15857   emit_move_insn (operands[2], temp);
15858 })
15859
15860 (define_expand "log2sf2"
15861   [(set (match_dup 2)
15862         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15863    (parallel [(set (match_dup 4)
15864                    (unspec:XF [(match_dup 2)
15865                                (match_dup 3)] UNSPEC_FYL2X))
15866               (clobber (match_scratch:XF 5 ""))])
15867    (set (match_operand:SF 0 "register_operand" "")
15868         (float_truncate:SF (match_dup 4)))]
15869   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15870    && flag_unsafe_math_optimizations"
15871 {
15872   operands[2] = gen_reg_rtx (XFmode);
15873   operands[3] = gen_reg_rtx (XFmode);
15874   operands[4] = gen_reg_rtx (XFmode);
15875
15876   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15877 })
15878
15879 (define_expand "log2df2"
15880   [(set (match_dup 2)
15881         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15882    (parallel [(set (match_dup 4)
15883                    (unspec:XF [(match_dup 2)
15884                                (match_dup 3)] UNSPEC_FYL2X))
15885               (clobber (match_scratch:XF 5 ""))])
15886    (set (match_operand:DF 0 "register_operand" "")
15887         (float_truncate:DF (match_dup 4)))]
15888   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15889    && flag_unsafe_math_optimizations"
15890 {
15891   operands[2] = gen_reg_rtx (XFmode);
15892   operands[3] = gen_reg_rtx (XFmode);
15893   operands[4] = gen_reg_rtx (XFmode);
15894
15895   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15896 })
15897
15898 (define_expand "log2xf2"
15899   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15900                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15901                                (match_dup 2)] UNSPEC_FYL2X))
15902               (clobber (match_scratch:XF 3 ""))])]
15903   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15904    && flag_unsafe_math_optimizations"
15905 {
15906   operands[2] = gen_reg_rtx (XFmode);
15907   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15908 })
15909
15910 (define_insn "fyl2xp1_xf3"
15911   [(set (match_operand:XF 0 "register_operand" "=f")
15912         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15913                     (match_operand:XF 1 "register_operand" "u")]
15914                    UNSPEC_FYL2XP1))
15915    (clobber (match_scratch:XF 3 "=1"))]
15916   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15917    && flag_unsafe_math_optimizations"
15918   "fyl2xp1"
15919   [(set_attr "type" "fpspc")
15920    (set_attr "mode" "XF")])
15921
15922 (define_expand "log1psf2"
15923   [(use (match_operand:XF 0 "register_operand" ""))
15924    (use (match_operand:XF 1 "register_operand" ""))]
15925   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15926    && flag_unsafe_math_optimizations"
15927 {
15928   rtx op0 = gen_reg_rtx (XFmode);
15929   rtx op1 = gen_reg_rtx (XFmode);
15930
15931   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15932   ix86_emit_i387_log1p (op0, op1);
15933   emit_insn (gen_truncxfsf2_noop (operands[0], op0));
15934   DONE;
15935 })
15936
15937 (define_expand "log1pdf2"
15938   [(use (match_operand:XF 0 "register_operand" ""))
15939    (use (match_operand:XF 1 "register_operand" ""))]
15940   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15941    && flag_unsafe_math_optimizations"
15942 {
15943   rtx op0 = gen_reg_rtx (XFmode);
15944   rtx op1 = gen_reg_rtx (XFmode);
15945
15946   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15947   ix86_emit_i387_log1p (op0, op1);
15948   emit_insn (gen_truncxfdf2_noop (operands[0], op0));
15949   DONE;
15950 })
15951
15952 (define_expand "log1pxf2"
15953   [(use (match_operand:XF 0 "register_operand" ""))
15954    (use (match_operand:XF 1 "register_operand" ""))]
15955   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15956    && flag_unsafe_math_optimizations"
15957 {
15958   ix86_emit_i387_log1p (operands[0], operands[1]);
15959   DONE;
15960 })
15961
15962 (define_insn "*fxtractxf3"
15963   [(set (match_operand:XF 0 "register_operand" "=f")
15964         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15965                    UNSPEC_XTRACT_FRACT))
15966    (set (match_operand:XF 1 "register_operand" "=u")
15967         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15968   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15969    && flag_unsafe_math_optimizations"
15970   "fxtract"
15971   [(set_attr "type" "fpspc")
15972    (set_attr "mode" "XF")])
15973
15974 (define_expand "logbsf2"
15975   [(set (match_dup 2)
15976         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15977    (parallel [(set (match_dup 3)
15978                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15979               (set (match_dup 4)
15980                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15981    (set (match_operand:SF 0 "register_operand" "")
15982         (float_truncate:SF (match_dup 4)))]
15983   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15984    && flag_unsafe_math_optimizations"
15985 {
15986   operands[2] = gen_reg_rtx (XFmode);
15987   operands[3] = gen_reg_rtx (XFmode);
15988   operands[4] = gen_reg_rtx (XFmode);
15989 })
15990
15991 (define_expand "logbdf2"
15992   [(set (match_dup 2)
15993         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15994    (parallel [(set (match_dup 3)
15995                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15996               (set (match_dup 4)
15997                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15998    (set (match_operand:DF 0 "register_operand" "")
15999         (float_truncate:DF (match_dup 4)))]
16000   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16001    && flag_unsafe_math_optimizations"
16002 {
16003   operands[2] = gen_reg_rtx (XFmode);
16004   operands[3] = gen_reg_rtx (XFmode);
16005   operands[4] = gen_reg_rtx (XFmode);
16006 })
16007
16008 (define_expand "logbxf2"
16009   [(parallel [(set (match_dup 2)
16010                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16011                               UNSPEC_XTRACT_FRACT))
16012               (set (match_operand:XF 0 "register_operand" "")
16013                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16014   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16015    && flag_unsafe_math_optimizations"
16016 {
16017   operands[2] = gen_reg_rtx (XFmode);
16018 })
16019
16020 (define_expand "ilogbsi2"
16021   [(parallel [(set (match_dup 2)
16022                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16023                               UNSPEC_XTRACT_FRACT))
16024               (set (match_operand:XF 3 "register_operand" "")
16025                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16026    (parallel [(set (match_operand:SI 0 "register_operand" "")
16027                    (fix:SI (match_dup 3)))
16028               (clobber (reg:CC FLAGS_REG))])]
16029   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16030    && flag_unsafe_math_optimizations"
16031 {
16032   operands[2] = gen_reg_rtx (XFmode);
16033   operands[3] = gen_reg_rtx (XFmode);
16034 })
16035
16036 (define_insn "*frndintxf2"
16037   [(set (match_operand:XF 0 "register_operand" "=f")
16038         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16039          UNSPEC_FRNDINT))]
16040   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16041    && flag_unsafe_math_optimizations"
16042   "frndint"
16043   [(set_attr "type" "fpspc")
16044    (set_attr "mode" "XF")])
16045
16046 (define_insn "*f2xm1xf2"
16047   [(set (match_operand:XF 0 "register_operand" "=f")
16048         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16049          UNSPEC_F2XM1))]
16050   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16051    && flag_unsafe_math_optimizations"
16052   "f2xm1"
16053   [(set_attr "type" "fpspc")
16054    (set_attr "mode" "XF")])
16055
16056 (define_insn "*fscalexf4"
16057   [(set (match_operand:XF 0 "register_operand" "=f")
16058         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16059                     (match_operand:XF 3 "register_operand" "1")]
16060                    UNSPEC_FSCALE_FRACT))
16061    (set (match_operand:XF 1 "register_operand" "=u")
16062         (unspec:XF [(match_dup 2) (match_dup 3)]
16063                    UNSPEC_FSCALE_EXP))]
16064   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
16065    && flag_unsafe_math_optimizations"
16066   "fscale"
16067   [(set_attr "type" "fpspc")
16068    (set_attr "mode" "XF")])
16069
16070 (define_expand "expsf2"
16071   [(set (match_dup 2)
16072         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16073    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16074    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16075    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16076    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16077    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16078    (parallel [(set (match_dup 10)
16079                    (unspec:XF [(match_dup 9) (match_dup 5)]
16080                               UNSPEC_FSCALE_FRACT))
16081               (set (match_dup 11)
16082                    (unspec:XF [(match_dup 9) (match_dup 5)]
16083                               UNSPEC_FSCALE_EXP))])
16084    (set (match_operand:SF 0 "register_operand" "")
16085         (float_truncate:SF (match_dup 10)))]
16086   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16087    && flag_unsafe_math_optimizations"
16088 {
16089   rtx temp;
16090   int i;
16091
16092   for (i=2; i<12; i++)
16093     operands[i] = gen_reg_rtx (XFmode);
16094   temp = standard_80387_constant_rtx (5); /* fldl2e */
16095   emit_move_insn (operands[3], temp);
16096   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16097 })
16098
16099 (define_expand "expdf2"
16100   [(set (match_dup 2)
16101         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16102    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16103    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16104    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16105    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16106    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16107    (parallel [(set (match_dup 10)
16108                    (unspec:XF [(match_dup 9) (match_dup 5)]
16109                               UNSPEC_FSCALE_FRACT))
16110               (set (match_dup 11)
16111                    (unspec:XF [(match_dup 9) (match_dup 5)]
16112                               UNSPEC_FSCALE_EXP))])
16113    (set (match_operand:DF 0 "register_operand" "")
16114         (float_truncate:DF (match_dup 10)))]
16115   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16116    && flag_unsafe_math_optimizations"
16117 {
16118   rtx temp;
16119   int i;
16120
16121   for (i=2; i<12; i++)
16122     operands[i] = gen_reg_rtx (XFmode);
16123   temp = standard_80387_constant_rtx (5); /* fldl2e */
16124   emit_move_insn (operands[3], temp);
16125   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16126 })
16127
16128 (define_expand "expxf2"
16129   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16130                                (match_dup 2)))
16131    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16132    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16133    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16134    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16135    (parallel [(set (match_operand:XF 0 "register_operand" "")
16136                    (unspec:XF [(match_dup 8) (match_dup 4)]
16137                               UNSPEC_FSCALE_FRACT))
16138               (set (match_dup 9)
16139                    (unspec:XF [(match_dup 8) (match_dup 4)]
16140                               UNSPEC_FSCALE_EXP))])]
16141   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16142    && flag_unsafe_math_optimizations"
16143 {
16144   rtx temp;
16145   int i;
16146
16147   for (i=2; i<10; i++)
16148     operands[i] = gen_reg_rtx (XFmode);
16149   temp = standard_80387_constant_rtx (5); /* fldl2e */
16150   emit_move_insn (operands[2], temp);
16151   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16152 })
16153
16154 (define_expand "exp10sf2"
16155   [(set (match_dup 2)
16156         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16157    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16158    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16159    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16160    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16161    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16162    (parallel [(set (match_dup 10)
16163                    (unspec:XF [(match_dup 9) (match_dup 5)]
16164                               UNSPEC_FSCALE_FRACT))
16165               (set (match_dup 11)
16166                    (unspec:XF [(match_dup 9) (match_dup 5)]
16167                               UNSPEC_FSCALE_EXP))])
16168    (set (match_operand:SF 0 "register_operand" "")
16169         (float_truncate:SF (match_dup 10)))]
16170   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16171    && flag_unsafe_math_optimizations"
16172 {
16173   rtx temp;
16174   int i;
16175
16176   for (i=2; i<12; i++)
16177     operands[i] = gen_reg_rtx (XFmode);
16178   temp = standard_80387_constant_rtx (6); /* fldl2t */
16179   emit_move_insn (operands[3], temp);
16180   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16181 })
16182
16183 (define_expand "exp10df2"
16184   [(set (match_dup 2)
16185         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16186    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16187    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16188    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16189    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16190    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16191    (parallel [(set (match_dup 10)
16192                    (unspec:XF [(match_dup 9) (match_dup 5)]
16193                               UNSPEC_FSCALE_FRACT))
16194               (set (match_dup 11)
16195                    (unspec:XF [(match_dup 9) (match_dup 5)]
16196                               UNSPEC_FSCALE_EXP))])
16197    (set (match_operand:DF 0 "register_operand" "")
16198         (float_truncate:DF (match_dup 10)))]
16199   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16200    && flag_unsafe_math_optimizations"
16201 {
16202   rtx temp;
16203   int i;
16204
16205   for (i=2; i<12; i++)
16206     operands[i] = gen_reg_rtx (XFmode);
16207   temp = standard_80387_constant_rtx (6); /* fldl2t */
16208   emit_move_insn (operands[3], temp);
16209   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16210 })
16211
16212 (define_expand "exp10xf2"
16213   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16214                                (match_dup 2)))
16215    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16216    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16217    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16218    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16219    (parallel [(set (match_operand:XF 0 "register_operand" "")
16220                    (unspec:XF [(match_dup 8) (match_dup 4)]
16221                               UNSPEC_FSCALE_FRACT))
16222               (set (match_dup 9)
16223                    (unspec:XF [(match_dup 8) (match_dup 4)]
16224                               UNSPEC_FSCALE_EXP))])]
16225   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16226    && flag_unsafe_math_optimizations"
16227 {
16228   rtx temp;
16229   int i;
16230
16231   for (i=2; i<10; i++)
16232     operands[i] = gen_reg_rtx (XFmode);
16233   temp = standard_80387_constant_rtx (6); /* fldl2t */
16234   emit_move_insn (operands[2], temp);
16235   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16236 })
16237
16238 (define_expand "exp2sf2"
16239   [(set (match_dup 2)
16240         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16241    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16242    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16243    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16244    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16245    (parallel [(set (match_dup 8)
16246                    (unspec:XF [(match_dup 7) (match_dup 3)]
16247                               UNSPEC_FSCALE_FRACT))
16248               (set (match_dup 9)
16249                    (unspec:XF [(match_dup 7) (match_dup 3)]
16250                               UNSPEC_FSCALE_EXP))])
16251    (set (match_operand:SF 0 "register_operand" "")
16252         (float_truncate:SF (match_dup 8)))]
16253   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16254    && flag_unsafe_math_optimizations"
16255 {
16256   int i;
16257
16258   for (i=2; i<10; i++)
16259     operands[i] = gen_reg_rtx (XFmode);
16260   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16261 })
16262
16263 (define_expand "exp2df2"
16264   [(set (match_dup 2)
16265         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16266    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16267    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16268    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16269    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16270    (parallel [(set (match_dup 8)
16271                    (unspec:XF [(match_dup 7) (match_dup 3)]
16272                               UNSPEC_FSCALE_FRACT))
16273               (set (match_dup 9)
16274                    (unspec:XF [(match_dup 7) (match_dup 3)]
16275                               UNSPEC_FSCALE_EXP))])
16276    (set (match_operand:DF 0 "register_operand" "")
16277         (float_truncate:DF (match_dup 8)))]
16278   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16279    && flag_unsafe_math_optimizations"
16280 {
16281   int i;
16282
16283   for (i=2; i<10; i++)
16284     operands[i] = gen_reg_rtx (XFmode);
16285   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16286 })
16287
16288 (define_expand "exp2xf2"
16289   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16290    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16291    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16292    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16293    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16294    (parallel [(set (match_operand:XF 0 "register_operand" "")
16295                    (unspec:XF [(match_dup 7) (match_dup 3)]
16296                               UNSPEC_FSCALE_FRACT))
16297               (set (match_dup 8)
16298                    (unspec:XF [(match_dup 7) (match_dup 3)]
16299                               UNSPEC_FSCALE_EXP))])]
16300   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16301    && flag_unsafe_math_optimizations"
16302 {
16303   int i;
16304
16305   for (i=2; i<9; i++)
16306     operands[i] = gen_reg_rtx (XFmode);
16307   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16308 })
16309
16310 (define_expand "expm1df2"
16311   [(set (match_dup 2)
16312         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16313    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16314    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16315    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16316    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16317    (parallel [(set (match_dup 8)
16318                    (unspec:XF [(match_dup 7) (match_dup 5)]
16319                               UNSPEC_FSCALE_FRACT))
16320                    (set (match_dup 9)
16321                    (unspec:XF [(match_dup 7) (match_dup 5)]
16322                               UNSPEC_FSCALE_EXP))])
16323    (parallel [(set (match_dup 11)
16324                    (unspec:XF [(match_dup 10) (match_dup 9)]
16325                               UNSPEC_FSCALE_FRACT))
16326               (set (match_dup 12)
16327                    (unspec:XF [(match_dup 10) (match_dup 9)]
16328                               UNSPEC_FSCALE_EXP))])
16329    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16330    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16331    (set (match_operand:DF 0 "register_operand" "")
16332         (float_truncate:DF (match_dup 14)))]
16333   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16334    && flag_unsafe_math_optimizations"
16335 {
16336   rtx temp;
16337   int i;
16338
16339   for (i=2; i<15; i++)
16340     operands[i] = gen_reg_rtx (XFmode);
16341   temp = standard_80387_constant_rtx (5); /* fldl2e */
16342   emit_move_insn (operands[3], temp);
16343   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16344 })
16345
16346 (define_expand "expm1sf2"
16347   [(set (match_dup 2)
16348         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16349    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16350    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16351    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16352    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16353    (parallel [(set (match_dup 8)
16354                    (unspec:XF [(match_dup 7) (match_dup 5)]
16355                               UNSPEC_FSCALE_FRACT))
16356                    (set (match_dup 9)
16357                    (unspec:XF [(match_dup 7) (match_dup 5)]
16358                               UNSPEC_FSCALE_EXP))])
16359    (parallel [(set (match_dup 11)
16360                    (unspec:XF [(match_dup 10) (match_dup 9)]
16361                               UNSPEC_FSCALE_FRACT))
16362               (set (match_dup 12)
16363                    (unspec:XF [(match_dup 10) (match_dup 9)]
16364                               UNSPEC_FSCALE_EXP))])
16365    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16366    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16367    (set (match_operand:SF 0 "register_operand" "")
16368         (float_truncate:SF (match_dup 14)))]
16369   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16370    && flag_unsafe_math_optimizations"
16371 {
16372   rtx temp;
16373   int i;
16374
16375   for (i=2; i<15; i++)
16376     operands[i] = gen_reg_rtx (XFmode);
16377   temp = standard_80387_constant_rtx (5); /* fldl2e */
16378   emit_move_insn (operands[3], temp);
16379   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16380 })
16381
16382 (define_expand "expm1xf2"
16383   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16384                                (match_dup 2)))
16385    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16386    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16387    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16388    (parallel [(set (match_dup 7)
16389                    (unspec:XF [(match_dup 6) (match_dup 4)]
16390                               UNSPEC_FSCALE_FRACT))
16391                    (set (match_dup 8)
16392                    (unspec:XF [(match_dup 6) (match_dup 4)]
16393                               UNSPEC_FSCALE_EXP))])
16394    (parallel [(set (match_dup 10)
16395                    (unspec:XF [(match_dup 9) (match_dup 8)]
16396                               UNSPEC_FSCALE_FRACT))
16397               (set (match_dup 11)
16398                    (unspec:XF [(match_dup 9) (match_dup 8)]
16399                               UNSPEC_FSCALE_EXP))])
16400    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16401    (set (match_operand:XF 0 "register_operand" "")
16402         (plus:XF (match_dup 12) (match_dup 7)))]
16403   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16404    && flag_unsafe_math_optimizations"
16405 {
16406   rtx temp;
16407   int i;
16408
16409   for (i=2; i<13; i++)
16410     operands[i] = gen_reg_rtx (XFmode);
16411   temp = standard_80387_constant_rtx (5); /* fldl2e */
16412   emit_move_insn (operands[2], temp);
16413   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16414 })
16415 \f
16416 ;; Block operation instructions
16417
16418 (define_insn "cld"
16419  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16420  ""
16421  "cld"
16422   [(set_attr "type" "cld")])
16423
16424 (define_expand "movmemsi"
16425   [(use (match_operand:BLK 0 "memory_operand" ""))
16426    (use (match_operand:BLK 1 "memory_operand" ""))
16427    (use (match_operand:SI 2 "nonmemory_operand" ""))
16428    (use (match_operand:SI 3 "const_int_operand" ""))]
16429   "! optimize_size"
16430 {
16431  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16432    DONE;
16433  else
16434    FAIL;
16435 })
16436
16437 (define_expand "movmemdi"
16438   [(use (match_operand:BLK 0 "memory_operand" ""))
16439    (use (match_operand:BLK 1 "memory_operand" ""))
16440    (use (match_operand:DI 2 "nonmemory_operand" ""))
16441    (use (match_operand:DI 3 "const_int_operand" ""))]
16442   "TARGET_64BIT"
16443 {
16444  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16445    DONE;
16446  else
16447    FAIL;
16448 })
16449
16450 ;; Most CPUs don't like single string operations
16451 ;; Handle this case here to simplify previous expander.
16452
16453 (define_expand "strmov"
16454   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16455    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16456    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16457               (clobber (reg:CC FLAGS_REG))])
16458    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16459               (clobber (reg:CC FLAGS_REG))])]
16460   ""
16461 {
16462   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16463
16464   /* If .md ever supports :P for Pmode, these can be directly
16465      in the pattern above.  */
16466   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16467   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16468
16469   if (TARGET_SINGLE_STRINGOP || optimize_size)
16470     {
16471       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16472                                       operands[2], operands[3],
16473                                       operands[5], operands[6]));
16474       DONE;
16475     }
16476
16477   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16478 })
16479
16480 (define_expand "strmov_singleop"
16481   [(parallel [(set (match_operand 1 "memory_operand" "")
16482                    (match_operand 3 "memory_operand" ""))
16483               (set (match_operand 0 "register_operand" "")
16484                    (match_operand 4 "" ""))
16485               (set (match_operand 2 "register_operand" "")
16486                    (match_operand 5 "" ""))
16487               (use (reg:SI DIRFLAG_REG))])]
16488   "TARGET_SINGLE_STRINGOP || optimize_size"
16489   "")
16490
16491 (define_insn "*strmovdi_rex_1"
16492   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16493         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16494    (set (match_operand:DI 0 "register_operand" "=D")
16495         (plus:DI (match_dup 2)
16496                  (const_int 8)))
16497    (set (match_operand:DI 1 "register_operand" "=S")
16498         (plus:DI (match_dup 3)
16499                  (const_int 8)))
16500    (use (reg:SI DIRFLAG_REG))]
16501   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16502   "movsq"
16503   [(set_attr "type" "str")
16504    (set_attr "mode" "DI")
16505    (set_attr "memory" "both")])
16506
16507 (define_insn "*strmovsi_1"
16508   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16509         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16510    (set (match_operand:SI 0 "register_operand" "=D")
16511         (plus:SI (match_dup 2)
16512                  (const_int 4)))
16513    (set (match_operand:SI 1 "register_operand" "=S")
16514         (plus:SI (match_dup 3)
16515                  (const_int 4)))
16516    (use (reg:SI DIRFLAG_REG))]
16517   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16518   "{movsl|movsd}"
16519   [(set_attr "type" "str")
16520    (set_attr "mode" "SI")
16521    (set_attr "memory" "both")])
16522
16523 (define_insn "*strmovsi_rex_1"
16524   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16525         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16526    (set (match_operand:DI 0 "register_operand" "=D")
16527         (plus:DI (match_dup 2)
16528                  (const_int 4)))
16529    (set (match_operand:DI 1 "register_operand" "=S")
16530         (plus:DI (match_dup 3)
16531                  (const_int 4)))
16532    (use (reg:SI DIRFLAG_REG))]
16533   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16534   "{movsl|movsd}"
16535   [(set_attr "type" "str")
16536    (set_attr "mode" "SI")
16537    (set_attr "memory" "both")])
16538
16539 (define_insn "*strmovhi_1"
16540   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16541         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16542    (set (match_operand:SI 0 "register_operand" "=D")
16543         (plus:SI (match_dup 2)
16544                  (const_int 2)))
16545    (set (match_operand:SI 1 "register_operand" "=S")
16546         (plus:SI (match_dup 3)
16547                  (const_int 2)))
16548    (use (reg:SI DIRFLAG_REG))]
16549   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16550   "movsw"
16551   [(set_attr "type" "str")
16552    (set_attr "memory" "both")
16553    (set_attr "mode" "HI")])
16554
16555 (define_insn "*strmovhi_rex_1"
16556   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16557         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16558    (set (match_operand:DI 0 "register_operand" "=D")
16559         (plus:DI (match_dup 2)
16560                  (const_int 2)))
16561    (set (match_operand:DI 1 "register_operand" "=S")
16562         (plus:DI (match_dup 3)
16563                  (const_int 2)))
16564    (use (reg:SI DIRFLAG_REG))]
16565   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16566   "movsw"
16567   [(set_attr "type" "str")
16568    (set_attr "memory" "both")
16569    (set_attr "mode" "HI")])
16570
16571 (define_insn "*strmovqi_1"
16572   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16573         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16574    (set (match_operand:SI 0 "register_operand" "=D")
16575         (plus:SI (match_dup 2)
16576                  (const_int 1)))
16577    (set (match_operand:SI 1 "register_operand" "=S")
16578         (plus:SI (match_dup 3)
16579                  (const_int 1)))
16580    (use (reg:SI DIRFLAG_REG))]
16581   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16582   "movsb"
16583   [(set_attr "type" "str")
16584    (set_attr "memory" "both")
16585    (set_attr "mode" "QI")])
16586
16587 (define_insn "*strmovqi_rex_1"
16588   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16589         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16590    (set (match_operand:DI 0 "register_operand" "=D")
16591         (plus:DI (match_dup 2)
16592                  (const_int 1)))
16593    (set (match_operand:DI 1 "register_operand" "=S")
16594         (plus:DI (match_dup 3)
16595                  (const_int 1)))
16596    (use (reg:SI DIRFLAG_REG))]
16597   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16598   "movsb"
16599   [(set_attr "type" "str")
16600    (set_attr "memory" "both")
16601    (set_attr "mode" "QI")])
16602
16603 (define_expand "rep_mov"
16604   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16605               (set (match_operand 0 "register_operand" "")
16606                    (match_operand 5 "" ""))
16607               (set (match_operand 2 "register_operand" "")
16608                    (match_operand 6 "" ""))
16609               (set (match_operand 1 "memory_operand" "")
16610                    (match_operand 3 "memory_operand" ""))
16611               (use (match_dup 4))
16612               (use (reg:SI DIRFLAG_REG))])]
16613   ""
16614   "")
16615
16616 (define_insn "*rep_movdi_rex64"
16617   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16618    (set (match_operand:DI 0 "register_operand" "=D") 
16619         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16620                             (const_int 3))
16621                  (match_operand:DI 3 "register_operand" "0")))
16622    (set (match_operand:DI 1 "register_operand" "=S") 
16623         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16624                  (match_operand:DI 4 "register_operand" "1")))
16625    (set (mem:BLK (match_dup 3))
16626         (mem:BLK (match_dup 4)))
16627    (use (match_dup 5))
16628    (use (reg:SI DIRFLAG_REG))]
16629   "TARGET_64BIT"
16630   "{rep\;movsq|rep movsq}"
16631   [(set_attr "type" "str")
16632    (set_attr "prefix_rep" "1")
16633    (set_attr "memory" "both")
16634    (set_attr "mode" "DI")])
16635
16636 (define_insn "*rep_movsi"
16637   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16638    (set (match_operand:SI 0 "register_operand" "=D") 
16639         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16640                             (const_int 2))
16641                  (match_operand:SI 3 "register_operand" "0")))
16642    (set (match_operand:SI 1 "register_operand" "=S") 
16643         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16644                  (match_operand:SI 4 "register_operand" "1")))
16645    (set (mem:BLK (match_dup 3))
16646         (mem:BLK (match_dup 4)))
16647    (use (match_dup 5))
16648    (use (reg:SI DIRFLAG_REG))]
16649   "!TARGET_64BIT"
16650   "{rep\;movsl|rep movsd}"
16651   [(set_attr "type" "str")
16652    (set_attr "prefix_rep" "1")
16653    (set_attr "memory" "both")
16654    (set_attr "mode" "SI")])
16655
16656 (define_insn "*rep_movsi_rex64"
16657   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16658    (set (match_operand:DI 0 "register_operand" "=D") 
16659         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16660                             (const_int 2))
16661                  (match_operand:DI 3 "register_operand" "0")))
16662    (set (match_operand:DI 1 "register_operand" "=S") 
16663         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16664                  (match_operand:DI 4 "register_operand" "1")))
16665    (set (mem:BLK (match_dup 3))
16666         (mem:BLK (match_dup 4)))
16667    (use (match_dup 5))
16668    (use (reg:SI DIRFLAG_REG))]
16669   "TARGET_64BIT"
16670   "{rep\;movsl|rep movsd}"
16671   [(set_attr "type" "str")
16672    (set_attr "prefix_rep" "1")
16673    (set_attr "memory" "both")
16674    (set_attr "mode" "SI")])
16675
16676 (define_insn "*rep_movqi"
16677   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16678    (set (match_operand:SI 0 "register_operand" "=D") 
16679         (plus:SI (match_operand:SI 3 "register_operand" "0")
16680                  (match_operand:SI 5 "register_operand" "2")))
16681    (set (match_operand:SI 1 "register_operand" "=S") 
16682         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16683    (set (mem:BLK (match_dup 3))
16684         (mem:BLK (match_dup 4)))
16685    (use (match_dup 5))
16686    (use (reg:SI DIRFLAG_REG))]
16687   "!TARGET_64BIT"
16688   "{rep\;movsb|rep movsb}"
16689   [(set_attr "type" "str")
16690    (set_attr "prefix_rep" "1")
16691    (set_attr "memory" "both")
16692    (set_attr "mode" "SI")])
16693
16694 (define_insn "*rep_movqi_rex64"
16695   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16696    (set (match_operand:DI 0 "register_operand" "=D") 
16697         (plus:DI (match_operand:DI 3 "register_operand" "0")
16698                  (match_operand:DI 5 "register_operand" "2")))
16699    (set (match_operand:DI 1 "register_operand" "=S") 
16700         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16701    (set (mem:BLK (match_dup 3))
16702         (mem:BLK (match_dup 4)))
16703    (use (match_dup 5))
16704    (use (reg:SI DIRFLAG_REG))]
16705   "TARGET_64BIT"
16706   "{rep\;movsb|rep movsb}"
16707   [(set_attr "type" "str")
16708    (set_attr "prefix_rep" "1")
16709    (set_attr "memory" "both")
16710    (set_attr "mode" "SI")])
16711
16712 (define_expand "clrmemsi"
16713    [(use (match_operand:BLK 0 "memory_operand" ""))
16714     (use (match_operand:SI 1 "nonmemory_operand" ""))
16715     (use (match_operand 2 "const_int_operand" ""))]
16716   ""
16717 {
16718  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16719    DONE;
16720  else
16721    FAIL;
16722 })
16723
16724 (define_expand "clrmemdi"
16725    [(use (match_operand:BLK 0 "memory_operand" ""))
16726     (use (match_operand:DI 1 "nonmemory_operand" ""))
16727     (use (match_operand 2 "const_int_operand" ""))]
16728   "TARGET_64BIT"
16729 {
16730  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16731    DONE;
16732  else
16733    FAIL;
16734 })
16735
16736 ;; Most CPUs don't like single string operations
16737 ;; Handle this case here to simplify previous expander.
16738
16739 (define_expand "strset"
16740   [(set (match_operand 1 "memory_operand" "")
16741         (match_operand 2 "register_operand" ""))
16742    (parallel [(set (match_operand 0 "register_operand" "")
16743                    (match_dup 3))
16744               (clobber (reg:CC FLAGS_REG))])]
16745   ""
16746 {
16747   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16748     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16749
16750   /* If .md ever supports :P for Pmode, this can be directly
16751      in the pattern above.  */
16752   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16753                               GEN_INT (GET_MODE_SIZE (GET_MODE
16754                                                       (operands[2]))));
16755   if (TARGET_SINGLE_STRINGOP || optimize_size)
16756     {
16757       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16758                                       operands[3]));
16759       DONE;
16760     }
16761 })
16762
16763 (define_expand "strset_singleop"
16764   [(parallel [(set (match_operand 1 "memory_operand" "")
16765                    (match_operand 2 "register_operand" ""))
16766               (set (match_operand 0 "register_operand" "")
16767                    (match_operand 3 "" ""))
16768               (use (reg:SI DIRFLAG_REG))])]
16769   "TARGET_SINGLE_STRINGOP || optimize_size"
16770   "")
16771
16772 (define_insn "*strsetdi_rex_1"
16773   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16774         (match_operand:DI 2 "register_operand" "a"))
16775    (set (match_operand:DI 0 "register_operand" "=D")
16776         (plus:DI (match_dup 1)
16777                  (const_int 8)))
16778    (use (reg:SI DIRFLAG_REG))]
16779   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16780   "stosq"
16781   [(set_attr "type" "str")
16782    (set_attr "memory" "store")
16783    (set_attr "mode" "DI")])
16784
16785 (define_insn "*strsetsi_1"
16786   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16787         (match_operand:SI 2 "register_operand" "a"))
16788    (set (match_operand:SI 0 "register_operand" "=D")
16789         (plus:SI (match_dup 1)
16790                  (const_int 4)))
16791    (use (reg:SI DIRFLAG_REG))]
16792   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16793   "{stosl|stosd}"
16794   [(set_attr "type" "str")
16795    (set_attr "memory" "store")
16796    (set_attr "mode" "SI")])
16797
16798 (define_insn "*strsetsi_rex_1"
16799   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16800         (match_operand:SI 2 "register_operand" "a"))
16801    (set (match_operand:DI 0 "register_operand" "=D")
16802         (plus:DI (match_dup 1)
16803                  (const_int 4)))
16804    (use (reg:SI DIRFLAG_REG))]
16805   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16806   "{stosl|stosd}"
16807   [(set_attr "type" "str")
16808    (set_attr "memory" "store")
16809    (set_attr "mode" "SI")])
16810
16811 (define_insn "*strsethi_1"
16812   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16813         (match_operand:HI 2 "register_operand" "a"))
16814    (set (match_operand:SI 0 "register_operand" "=D")
16815         (plus:SI (match_dup 1)
16816                  (const_int 2)))
16817    (use (reg:SI DIRFLAG_REG))]
16818   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16819   "stosw"
16820   [(set_attr "type" "str")
16821    (set_attr "memory" "store")
16822    (set_attr "mode" "HI")])
16823
16824 (define_insn "*strsethi_rex_1"
16825   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16826         (match_operand:HI 2 "register_operand" "a"))
16827    (set (match_operand:DI 0 "register_operand" "=D")
16828         (plus:DI (match_dup 1)
16829                  (const_int 2)))
16830    (use (reg:SI DIRFLAG_REG))]
16831   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16832   "stosw"
16833   [(set_attr "type" "str")
16834    (set_attr "memory" "store")
16835    (set_attr "mode" "HI")])
16836
16837 (define_insn "*strsetqi_1"
16838   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16839         (match_operand:QI 2 "register_operand" "a"))
16840    (set (match_operand:SI 0 "register_operand" "=D")
16841         (plus:SI (match_dup 1)
16842                  (const_int 1)))
16843    (use (reg:SI DIRFLAG_REG))]
16844   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16845   "stosb"
16846   [(set_attr "type" "str")
16847    (set_attr "memory" "store")
16848    (set_attr "mode" "QI")])
16849
16850 (define_insn "*strsetqi_rex_1"
16851   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16852         (match_operand:QI 2 "register_operand" "a"))
16853    (set (match_operand:DI 0 "register_operand" "=D")
16854         (plus:DI (match_dup 1)
16855                  (const_int 1)))
16856    (use (reg:SI DIRFLAG_REG))]
16857   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16858   "stosb"
16859   [(set_attr "type" "str")
16860    (set_attr "memory" "store")
16861    (set_attr "mode" "QI")])
16862
16863 (define_expand "rep_stos"
16864   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16865               (set (match_operand 0 "register_operand" "")
16866                    (match_operand 4 "" ""))
16867               (set (match_operand 2 "memory_operand" "") (const_int 0))
16868               (use (match_operand 3 "register_operand" ""))
16869               (use (match_dup 1))
16870               (use (reg:SI DIRFLAG_REG))])]
16871   ""
16872   "")
16873
16874 (define_insn "*rep_stosdi_rex64"
16875   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16876    (set (match_operand:DI 0 "register_operand" "=D") 
16877         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16878                             (const_int 3))
16879                  (match_operand:DI 3 "register_operand" "0")))
16880    (set (mem:BLK (match_dup 3))
16881         (const_int 0))
16882    (use (match_operand:DI 2 "register_operand" "a"))
16883    (use (match_dup 4))
16884    (use (reg:SI DIRFLAG_REG))]
16885   "TARGET_64BIT"
16886   "{rep\;stosq|rep stosq}"
16887   [(set_attr "type" "str")
16888    (set_attr "prefix_rep" "1")
16889    (set_attr "memory" "store")
16890    (set_attr "mode" "DI")])
16891
16892 (define_insn "*rep_stossi"
16893   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16894    (set (match_operand:SI 0 "register_operand" "=D") 
16895         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16896                             (const_int 2))
16897                  (match_operand:SI 3 "register_operand" "0")))
16898    (set (mem:BLK (match_dup 3))
16899         (const_int 0))
16900    (use (match_operand:SI 2 "register_operand" "a"))
16901    (use (match_dup 4))
16902    (use (reg:SI DIRFLAG_REG))]
16903   "!TARGET_64BIT"
16904   "{rep\;stosl|rep stosd}"
16905   [(set_attr "type" "str")
16906    (set_attr "prefix_rep" "1")
16907    (set_attr "memory" "store")
16908    (set_attr "mode" "SI")])
16909
16910 (define_insn "*rep_stossi_rex64"
16911   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16912    (set (match_operand:DI 0 "register_operand" "=D") 
16913         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16914                             (const_int 2))
16915                  (match_operand:DI 3 "register_operand" "0")))
16916    (set (mem:BLK (match_dup 3))
16917         (const_int 0))
16918    (use (match_operand:SI 2 "register_operand" "a"))
16919    (use (match_dup 4))
16920    (use (reg:SI DIRFLAG_REG))]
16921   "TARGET_64BIT"
16922   "{rep\;stosl|rep stosd}"
16923   [(set_attr "type" "str")
16924    (set_attr "prefix_rep" "1")
16925    (set_attr "memory" "store")
16926    (set_attr "mode" "SI")])
16927
16928 (define_insn "*rep_stosqi"
16929   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16930    (set (match_operand:SI 0 "register_operand" "=D") 
16931         (plus:SI (match_operand:SI 3 "register_operand" "0")
16932                  (match_operand:SI 4 "register_operand" "1")))
16933    (set (mem:BLK (match_dup 3))
16934         (const_int 0))
16935    (use (match_operand:QI 2 "register_operand" "a"))
16936    (use (match_dup 4))
16937    (use (reg:SI DIRFLAG_REG))]
16938   "!TARGET_64BIT"
16939   "{rep\;stosb|rep stosb}"
16940   [(set_attr "type" "str")
16941    (set_attr "prefix_rep" "1")
16942    (set_attr "memory" "store")
16943    (set_attr "mode" "QI")])
16944
16945 (define_insn "*rep_stosqi_rex64"
16946   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16947    (set (match_operand:DI 0 "register_operand" "=D") 
16948         (plus:DI (match_operand:DI 3 "register_operand" "0")
16949                  (match_operand:DI 4 "register_operand" "1")))
16950    (set (mem:BLK (match_dup 3))
16951         (const_int 0))
16952    (use (match_operand:QI 2 "register_operand" "a"))
16953    (use (match_dup 4))
16954    (use (reg:SI DIRFLAG_REG))]
16955   "TARGET_64BIT"
16956   "{rep\;stosb|rep stosb}"
16957   [(set_attr "type" "str")
16958    (set_attr "prefix_rep" "1")
16959    (set_attr "memory" "store")
16960    (set_attr "mode" "QI")])
16961
16962 (define_expand "cmpstrsi"
16963   [(set (match_operand:SI 0 "register_operand" "")
16964         (compare:SI (match_operand:BLK 1 "general_operand" "")
16965                     (match_operand:BLK 2 "general_operand" "")))
16966    (use (match_operand 3 "general_operand" ""))
16967    (use (match_operand 4 "immediate_operand" ""))]
16968   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
16969 {
16970   rtx addr1, addr2, out, outlow, count, countreg, align;
16971
16972   /* Can't use this if the user has appropriated esi or edi.  */
16973   if (global_regs[4] || global_regs[5])
16974     FAIL;
16975
16976   out = operands[0];
16977   if (GET_CODE (out) != REG)
16978     out = gen_reg_rtx (SImode);
16979
16980   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16981   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16982   if (addr1 != XEXP (operands[1], 0))
16983     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16984   if (addr2 != XEXP (operands[2], 0))
16985     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16986
16987   count = operands[3];
16988   countreg = ix86_zero_extend_to_Pmode (count);
16989
16990   /* %%% Iff we are testing strict equality, we can use known alignment
16991      to good advantage.  This may be possible with combine, particularly
16992      once cc0 is dead.  */
16993   align = operands[4];
16994
16995   emit_insn (gen_cld ());
16996   if (GET_CODE (count) == CONST_INT)
16997     {
16998       if (INTVAL (count) == 0)
16999         {
17000           emit_move_insn (operands[0], const0_rtx);
17001           DONE;
17002         }
17003       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17004                                     operands[1], operands[2]));
17005     }
17006   else
17007     {
17008       if (TARGET_64BIT)
17009         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17010       else
17011         emit_insn (gen_cmpsi_1 (countreg, countreg));
17012       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17013                                  operands[1], operands[2]));
17014     }
17015
17016   outlow = gen_lowpart (QImode, out);
17017   emit_insn (gen_cmpintqi (outlow));
17018   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17019
17020   if (operands[0] != out)
17021     emit_move_insn (operands[0], out);
17022
17023   DONE;
17024 })
17025
17026 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17027
17028 (define_expand "cmpintqi"
17029   [(set (match_dup 1)
17030         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17031    (set (match_dup 2)
17032         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17033    (parallel [(set (match_operand:QI 0 "register_operand" "")
17034                    (minus:QI (match_dup 1)
17035                              (match_dup 2)))
17036               (clobber (reg:CC FLAGS_REG))])]
17037   ""
17038   "operands[1] = gen_reg_rtx (QImode);
17039    operands[2] = gen_reg_rtx (QImode);")
17040
17041 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17042 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17043
17044 (define_expand "cmpstrqi_nz_1"
17045   [(parallel [(set (reg:CC FLAGS_REG)
17046                    (compare:CC (match_operand 4 "memory_operand" "")
17047                                (match_operand 5 "memory_operand" "")))
17048               (use (match_operand 2 "register_operand" ""))
17049               (use (match_operand:SI 3 "immediate_operand" ""))
17050               (use (reg:SI DIRFLAG_REG))
17051               (clobber (match_operand 0 "register_operand" ""))
17052               (clobber (match_operand 1 "register_operand" ""))
17053               (clobber (match_dup 2))])]
17054   ""
17055   "")
17056
17057 (define_insn "*cmpstrqi_nz_1"
17058   [(set (reg:CC FLAGS_REG)
17059         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17060                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17061    (use (match_operand:SI 6 "register_operand" "2"))
17062    (use (match_operand:SI 3 "immediate_operand" "i"))
17063    (use (reg:SI DIRFLAG_REG))
17064    (clobber (match_operand:SI 0 "register_operand" "=S"))
17065    (clobber (match_operand:SI 1 "register_operand" "=D"))
17066    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17067   "!TARGET_64BIT"
17068   "repz{\;| }cmpsb"
17069   [(set_attr "type" "str")
17070    (set_attr "mode" "QI")
17071    (set_attr "prefix_rep" "1")])
17072
17073 (define_insn "*cmpstrqi_nz_rex_1"
17074   [(set (reg:CC FLAGS_REG)
17075         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17076                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17077    (use (match_operand:DI 6 "register_operand" "2"))
17078    (use (match_operand:SI 3 "immediate_operand" "i"))
17079    (use (reg:SI DIRFLAG_REG))
17080    (clobber (match_operand:DI 0 "register_operand" "=S"))
17081    (clobber (match_operand:DI 1 "register_operand" "=D"))
17082    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17083   "TARGET_64BIT"
17084   "repz{\;| }cmpsb"
17085   [(set_attr "type" "str")
17086    (set_attr "mode" "QI")
17087    (set_attr "prefix_rep" "1")])
17088
17089 ;; The same, but the count is not known to not be zero.
17090
17091 (define_expand "cmpstrqi_1"
17092   [(parallel [(set (reg:CC FLAGS_REG)
17093                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17094                                      (const_int 0))
17095                   (compare:CC (match_operand 4 "memory_operand" "")
17096                               (match_operand 5 "memory_operand" ""))
17097                   (const_int 0)))
17098               (use (match_operand:SI 3 "immediate_operand" ""))
17099               (use (reg:CC FLAGS_REG))
17100               (use (reg:SI DIRFLAG_REG))
17101               (clobber (match_operand 0 "register_operand" ""))
17102               (clobber (match_operand 1 "register_operand" ""))
17103               (clobber (match_dup 2))])]
17104   ""
17105   "")
17106
17107 (define_insn "*cmpstrqi_1"
17108   [(set (reg:CC FLAGS_REG)
17109         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17110                              (const_int 0))
17111           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17112                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17113           (const_int 0)))
17114    (use (match_operand:SI 3 "immediate_operand" "i"))
17115    (use (reg:CC FLAGS_REG))
17116    (use (reg:SI DIRFLAG_REG))
17117    (clobber (match_operand:SI 0 "register_operand" "=S"))
17118    (clobber (match_operand:SI 1 "register_operand" "=D"))
17119    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17120   "!TARGET_64BIT"
17121   "repz{\;| }cmpsb"
17122   [(set_attr "type" "str")
17123    (set_attr "mode" "QI")
17124    (set_attr "prefix_rep" "1")])
17125
17126 (define_insn "*cmpstrqi_rex_1"
17127   [(set (reg:CC FLAGS_REG)
17128         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17129                              (const_int 0))
17130           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17131                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17132           (const_int 0)))
17133    (use (match_operand:SI 3 "immediate_operand" "i"))
17134    (use (reg:CC FLAGS_REG))
17135    (use (reg:SI DIRFLAG_REG))
17136    (clobber (match_operand:DI 0 "register_operand" "=S"))
17137    (clobber (match_operand:DI 1 "register_operand" "=D"))
17138    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17139   "TARGET_64BIT"
17140   "repz{\;| }cmpsb"
17141   [(set_attr "type" "str")
17142    (set_attr "mode" "QI")
17143    (set_attr "prefix_rep" "1")])
17144
17145 (define_expand "strlensi"
17146   [(set (match_operand:SI 0 "register_operand" "")
17147         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17148                     (match_operand:QI 2 "immediate_operand" "")
17149                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17150   ""
17151 {
17152  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17153    DONE;
17154  else
17155    FAIL;
17156 })
17157
17158 (define_expand "strlendi"
17159   [(set (match_operand:DI 0 "register_operand" "")
17160         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17161                     (match_operand:QI 2 "immediate_operand" "")
17162                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17163   ""
17164 {
17165  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17166    DONE;
17167  else
17168    FAIL;
17169 })
17170
17171 (define_expand "strlenqi_1"
17172   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17173               (use (reg:SI DIRFLAG_REG))
17174               (clobber (match_operand 1 "register_operand" ""))
17175               (clobber (reg:CC FLAGS_REG))])]
17176   ""
17177   "")
17178
17179 (define_insn "*strlenqi_1"
17180   [(set (match_operand:SI 0 "register_operand" "=&c")
17181         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17182                     (match_operand:QI 2 "register_operand" "a")
17183                     (match_operand:SI 3 "immediate_operand" "i")
17184                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17185    (use (reg:SI DIRFLAG_REG))
17186    (clobber (match_operand:SI 1 "register_operand" "=D"))
17187    (clobber (reg:CC FLAGS_REG))]
17188   "!TARGET_64BIT"
17189   "repnz{\;| }scasb"
17190   [(set_attr "type" "str")
17191    (set_attr "mode" "QI")
17192    (set_attr "prefix_rep" "1")])
17193
17194 (define_insn "*strlenqi_rex_1"
17195   [(set (match_operand:DI 0 "register_operand" "=&c")
17196         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17197                     (match_operand:QI 2 "register_operand" "a")
17198                     (match_operand:DI 3 "immediate_operand" "i")
17199                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17200    (use (reg:SI DIRFLAG_REG))
17201    (clobber (match_operand:DI 1 "register_operand" "=D"))
17202    (clobber (reg:CC FLAGS_REG))]
17203   "TARGET_64BIT"
17204   "repnz{\;| }scasb"
17205   [(set_attr "type" "str")
17206    (set_attr "mode" "QI")
17207    (set_attr "prefix_rep" "1")])
17208
17209 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17210 ;; handled in combine, but it is not currently up to the task.
17211 ;; When used for their truth value, the cmpstr* expanders generate
17212 ;; code like this:
17213 ;;
17214 ;;   repz cmpsb
17215 ;;   seta       %al
17216 ;;   setb       %dl
17217 ;;   cmpb       %al, %dl
17218 ;;   jcc        label
17219 ;;
17220 ;; The intermediate three instructions are unnecessary.
17221
17222 ;; This one handles cmpstr*_nz_1...
17223 (define_peephole2
17224   [(parallel[
17225      (set (reg:CC FLAGS_REG)
17226           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17227                       (mem:BLK (match_operand 5 "register_operand" ""))))
17228      (use (match_operand 6 "register_operand" ""))
17229      (use (match_operand:SI 3 "immediate_operand" ""))
17230      (use (reg:SI DIRFLAG_REG))
17231      (clobber (match_operand 0 "register_operand" ""))
17232      (clobber (match_operand 1 "register_operand" ""))
17233      (clobber (match_operand 2 "register_operand" ""))])
17234    (set (match_operand:QI 7 "register_operand" "")
17235         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17236    (set (match_operand:QI 8 "register_operand" "")
17237         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17238    (set (reg 17)
17239         (compare (match_dup 7) (match_dup 8)))
17240   ]
17241   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17242   [(parallel[
17243      (set (reg:CC FLAGS_REG)
17244           (compare:CC (mem:BLK (match_dup 4))
17245                       (mem:BLK (match_dup 5))))
17246      (use (match_dup 6))
17247      (use (match_dup 3))
17248      (use (reg:SI DIRFLAG_REG))
17249      (clobber (match_dup 0))
17250      (clobber (match_dup 1))
17251      (clobber (match_dup 2))])]
17252   "")
17253
17254 ;; ...and this one handles cmpstr*_1.
17255 (define_peephole2
17256   [(parallel[
17257      (set (reg:CC FLAGS_REG)
17258           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17259                                (const_int 0))
17260             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17261                         (mem:BLK (match_operand 5 "register_operand" "")))
17262             (const_int 0)))
17263      (use (match_operand:SI 3 "immediate_operand" ""))
17264      (use (reg:CC FLAGS_REG))
17265      (use (reg:SI DIRFLAG_REG))
17266      (clobber (match_operand 0 "register_operand" ""))
17267      (clobber (match_operand 1 "register_operand" ""))
17268      (clobber (match_operand 2 "register_operand" ""))])
17269    (set (match_operand:QI 7 "register_operand" "")
17270         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17271    (set (match_operand:QI 8 "register_operand" "")
17272         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17273    (set (reg 17)
17274         (compare (match_dup 7) (match_dup 8)))
17275   ]
17276   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17277   [(parallel[
17278      (set (reg:CC FLAGS_REG)
17279           (if_then_else:CC (ne (match_dup 6)
17280                                (const_int 0))
17281             (compare:CC (mem:BLK (match_dup 4))
17282                         (mem:BLK (match_dup 5)))
17283             (const_int 0)))
17284      (use (match_dup 3))
17285      (use (reg:CC FLAGS_REG))
17286      (use (reg:SI DIRFLAG_REG))
17287      (clobber (match_dup 0))
17288      (clobber (match_dup 1))
17289      (clobber (match_dup 2))])]
17290   "")
17291
17292
17293 \f
17294 ;; Conditional move instructions.
17295
17296 (define_expand "movdicc"
17297   [(set (match_operand:DI 0 "register_operand" "")
17298         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17299                          (match_operand:DI 2 "general_operand" "")
17300                          (match_operand:DI 3 "general_operand" "")))]
17301   "TARGET_64BIT"
17302   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17303
17304 (define_insn "x86_movdicc_0_m1_rex64"
17305   [(set (match_operand:DI 0 "register_operand" "=r")
17306         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17307           (const_int -1)
17308           (const_int 0)))
17309    (clobber (reg:CC FLAGS_REG))]
17310   "TARGET_64BIT"
17311   "sbb{q}\t%0, %0"
17312   ; Since we don't have the proper number of operands for an alu insn,
17313   ; fill in all the blanks.
17314   [(set_attr "type" "alu")
17315    (set_attr "pent_pair" "pu")
17316    (set_attr "memory" "none")
17317    (set_attr "imm_disp" "false")
17318    (set_attr "mode" "DI")
17319    (set_attr "length_immediate" "0")])
17320
17321 (define_insn "movdicc_c_rex64"
17322   [(set (match_operand:DI 0 "register_operand" "=r,r")
17323         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17324                                 [(reg 17) (const_int 0)])
17325                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17326                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17327   "TARGET_64BIT && TARGET_CMOVE
17328    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17329   "@
17330    cmov%O2%C1\t{%2, %0|%0, %2}
17331    cmov%O2%c1\t{%3, %0|%0, %3}"
17332   [(set_attr "type" "icmov")
17333    (set_attr "mode" "DI")])
17334
17335 (define_expand "movsicc"
17336   [(set (match_operand:SI 0 "register_operand" "")
17337         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17338                          (match_operand:SI 2 "general_operand" "")
17339                          (match_operand:SI 3 "general_operand" "")))]
17340   ""
17341   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17342
17343 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17344 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17345 ;; So just document what we're doing explicitly.
17346
17347 (define_insn "x86_movsicc_0_m1"
17348   [(set (match_operand:SI 0 "register_operand" "=r")
17349         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17350           (const_int -1)
17351           (const_int 0)))
17352    (clobber (reg:CC FLAGS_REG))]
17353   ""
17354   "sbb{l}\t%0, %0"
17355   ; Since we don't have the proper number of operands for an alu insn,
17356   ; fill in all the blanks.
17357   [(set_attr "type" "alu")
17358    (set_attr "pent_pair" "pu")
17359    (set_attr "memory" "none")
17360    (set_attr "imm_disp" "false")
17361    (set_attr "mode" "SI")
17362    (set_attr "length_immediate" "0")])
17363
17364 (define_insn "*movsicc_noc"
17365   [(set (match_operand:SI 0 "register_operand" "=r,r")
17366         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17367                                 [(reg 17) (const_int 0)])
17368                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17369                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17370   "TARGET_CMOVE
17371    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17372   "@
17373    cmov%O2%C1\t{%2, %0|%0, %2}
17374    cmov%O2%c1\t{%3, %0|%0, %3}"
17375   [(set_attr "type" "icmov")
17376    (set_attr "mode" "SI")])
17377
17378 (define_expand "movhicc"
17379   [(set (match_operand:HI 0 "register_operand" "")
17380         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17381                          (match_operand:HI 2 "general_operand" "")
17382                          (match_operand:HI 3 "general_operand" "")))]
17383   "TARGET_HIMODE_MATH"
17384   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17385
17386 (define_insn "*movhicc_noc"
17387   [(set (match_operand:HI 0 "register_operand" "=r,r")
17388         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17389                                 [(reg 17) (const_int 0)])
17390                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17391                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17392   "TARGET_CMOVE
17393    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17394   "@
17395    cmov%O2%C1\t{%2, %0|%0, %2}
17396    cmov%O2%c1\t{%3, %0|%0, %3}"
17397   [(set_attr "type" "icmov")
17398    (set_attr "mode" "HI")])
17399
17400 (define_expand "movqicc"
17401   [(set (match_operand:QI 0 "register_operand" "")
17402         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17403                          (match_operand:QI 2 "general_operand" "")
17404                          (match_operand:QI 3 "general_operand" "")))]
17405   "TARGET_QIMODE_MATH"
17406   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17407
17408 (define_insn_and_split "*movqicc_noc"
17409   [(set (match_operand:QI 0 "register_operand" "=r,r")
17410         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17411                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17412                       (match_operand:QI 2 "register_operand" "r,0")
17413                       (match_operand:QI 3 "register_operand" "0,r")))]
17414   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17415   "#"
17416   "&& reload_completed"
17417   [(set (match_dup 0)
17418         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17419                       (match_dup 2)
17420                       (match_dup 3)))]
17421   "operands[0] = gen_lowpart (SImode, operands[0]);
17422    operands[2] = gen_lowpart (SImode, operands[2]);
17423    operands[3] = gen_lowpart (SImode, operands[3]);"
17424   [(set_attr "type" "icmov")
17425    (set_attr "mode" "SI")])
17426
17427 (define_expand "movsfcc"
17428   [(set (match_operand:SF 0 "register_operand" "")
17429         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17430                          (match_operand:SF 2 "register_operand" "")
17431                          (match_operand:SF 3 "register_operand" "")))]
17432   "TARGET_CMOVE"
17433   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17434
17435 (define_insn "*movsfcc_1"
17436   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17437         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17438                                 [(reg 17) (const_int 0)])
17439                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17440                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17441   "TARGET_CMOVE
17442    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17443   "@
17444    fcmov%F1\t{%2, %0|%0, %2}
17445    fcmov%f1\t{%3, %0|%0, %3}
17446    cmov%O2%C1\t{%2, %0|%0, %2}
17447    cmov%O2%c1\t{%3, %0|%0, %3}"
17448   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17449    (set_attr "mode" "SF,SF,SI,SI")])
17450
17451 (define_expand "movdfcc"
17452   [(set (match_operand:DF 0 "register_operand" "")
17453         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17454                          (match_operand:DF 2 "register_operand" "")
17455                          (match_operand:DF 3 "register_operand" "")))]
17456   "TARGET_CMOVE"
17457   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17458
17459 (define_insn "*movdfcc_1"
17460   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17461         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17462                                 [(reg 17) (const_int 0)])
17463                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17464                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17465   "!TARGET_64BIT && TARGET_CMOVE
17466    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17467   "@
17468    fcmov%F1\t{%2, %0|%0, %2}
17469    fcmov%f1\t{%3, %0|%0, %3}
17470    #
17471    #"
17472   [(set_attr "type" "fcmov,fcmov,multi,multi")
17473    (set_attr "mode" "DF")])
17474
17475 (define_insn "*movdfcc_1_rex64"
17476   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17477         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17478                                 [(reg 17) (const_int 0)])
17479                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17480                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17481   "TARGET_64BIT && TARGET_CMOVE
17482    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17483   "@
17484    fcmov%F1\t{%2, %0|%0, %2}
17485    fcmov%f1\t{%3, %0|%0, %3}
17486    cmov%O2%C1\t{%2, %0|%0, %2}
17487    cmov%O2%c1\t{%3, %0|%0, %3}"
17488   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17489    (set_attr "mode" "DF")])
17490
17491 (define_split
17492   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17493         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17494                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17495                       (match_operand:DF 2 "nonimmediate_operand" "")
17496                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17497   "!TARGET_64BIT && reload_completed"
17498   [(set (match_dup 2)
17499         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17500                       (match_dup 5)
17501                       (match_dup 7)))
17502    (set (match_dup 3)
17503         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17504                       (match_dup 6)
17505                       (match_dup 8)))]
17506   "split_di (operands+2, 1, operands+5, operands+6);
17507    split_di (operands+3, 1, operands+7, operands+8);
17508    split_di (operands, 1, operands+2, operands+3);")
17509
17510 (define_expand "movxfcc"
17511   [(set (match_operand:XF 0 "register_operand" "")
17512         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17513                          (match_operand:XF 2 "register_operand" "")
17514                          (match_operand:XF 3 "register_operand" "")))]
17515   "TARGET_CMOVE"
17516   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17517
17518 (define_insn "*movxfcc_1"
17519   [(set (match_operand:XF 0 "register_operand" "=f,f")
17520         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17521                                 [(reg 17) (const_int 0)])
17522                       (match_operand:XF 2 "register_operand" "f,0")
17523                       (match_operand:XF 3 "register_operand" "0,f")))]
17524   "TARGET_CMOVE"
17525   "@
17526    fcmov%F1\t{%2, %0|%0, %2}
17527    fcmov%f1\t{%3, %0|%0, %3}"
17528   [(set_attr "type" "fcmov")
17529    (set_attr "mode" "XF")])
17530
17531 (define_expand "minsf3"
17532   [(parallel [
17533      (set (match_operand:SF 0 "register_operand" "")
17534           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17535                                (match_operand:SF 2 "nonimmediate_operand" ""))
17536                            (match_dup 1)
17537                            (match_dup 2)))
17538      (clobber (reg:CC FLAGS_REG))])]
17539   "TARGET_SSE"
17540   "")
17541
17542 (define_insn "*minsf"
17543   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17544         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17545                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17546                          (match_dup 1)
17547                          (match_dup 2)))
17548    (clobber (reg:CC FLAGS_REG))]
17549   "TARGET_SSE && TARGET_IEEE_FP"
17550   "#")
17551
17552 (define_insn "*minsf_nonieee"
17553   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17554         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17555                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17556                          (match_dup 1)
17557                          (match_dup 2)))
17558    (clobber (reg:CC FLAGS_REG))]
17559   "TARGET_SSE && !TARGET_IEEE_FP
17560    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17561   "#")
17562
17563 (define_split
17564   [(set (match_operand:SF 0 "register_operand" "")
17565         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17566                              (match_operand:SF 2 "nonimmediate_operand" ""))
17567                          (match_operand:SF 3 "register_operand" "")
17568                          (match_operand:SF 4 "nonimmediate_operand" "")))
17569    (clobber (reg:CC FLAGS_REG))]
17570   "SSE_REG_P (operands[0]) && reload_completed
17571    && ((operands_match_p (operands[1], operands[3])
17572         && operands_match_p (operands[2], operands[4]))
17573        || (operands_match_p (operands[1], operands[4])
17574            && operands_match_p (operands[2], operands[3])))"
17575   [(set (match_dup 0)
17576         (if_then_else:SF (lt (match_dup 1)
17577                              (match_dup 2))
17578                          (match_dup 1)
17579                          (match_dup 2)))])
17580
17581 ;; Conditional addition patterns
17582 (define_expand "addqicc"
17583   [(match_operand:QI 0 "register_operand" "")
17584    (match_operand 1 "comparison_operator" "")
17585    (match_operand:QI 2 "register_operand" "")
17586    (match_operand:QI 3 "const_int_operand" "")]
17587   ""
17588   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17589
17590 (define_expand "addhicc"
17591   [(match_operand:HI 0 "register_operand" "")
17592    (match_operand 1 "comparison_operator" "")
17593    (match_operand:HI 2 "register_operand" "")
17594    (match_operand:HI 3 "const_int_operand" "")]
17595   ""
17596   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17597
17598 (define_expand "addsicc"
17599   [(match_operand:SI 0 "register_operand" "")
17600    (match_operand 1 "comparison_operator" "")
17601    (match_operand:SI 2 "register_operand" "")
17602    (match_operand:SI 3 "const_int_operand" "")]
17603   ""
17604   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17605
17606 (define_expand "adddicc"
17607   [(match_operand:DI 0 "register_operand" "")
17608    (match_operand 1 "comparison_operator" "")
17609    (match_operand:DI 2 "register_operand" "")
17610    (match_operand:DI 3 "const_int_operand" "")]
17611   "TARGET_64BIT"
17612   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17613
17614 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17615
17616 (define_split
17617   [(set (match_operand:SF 0 "fp_register_operand" "")
17618         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17619                              (match_operand:SF 2 "register_operand" ""))
17620                          (match_operand:SF 3 "register_operand" "")
17621                          (match_operand:SF 4 "register_operand" "")))
17622    (clobber (reg:CC FLAGS_REG))]
17623   "reload_completed
17624    && ((operands_match_p (operands[1], operands[3])
17625         && operands_match_p (operands[2], operands[4]))
17626        || (operands_match_p (operands[1], operands[4])
17627            && operands_match_p (operands[2], operands[3])))"
17628   [(set (reg:CCFP FLAGS_REG)
17629         (compare:CCFP (match_dup 2)
17630                       (match_dup 1)))
17631    (set (match_dup 0)
17632         (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17633                          (match_dup 1)
17634                          (match_dup 2)))])
17635
17636 (define_insn "*minsf_sse"
17637   [(set (match_operand:SF 0 "register_operand" "=x")
17638         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17639                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17640                          (match_dup 1)
17641                          (match_dup 2)))]
17642   "TARGET_SSE && reload_completed"
17643   "minss\t{%2, %0|%0, %2}"
17644   [(set_attr "type" "sse")
17645    (set_attr "mode" "SF")])
17646
17647 (define_expand "mindf3"
17648   [(parallel [
17649      (set (match_operand:DF 0 "register_operand" "")
17650           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17651                                (match_operand:DF 2 "nonimmediate_operand" ""))
17652                            (match_dup 1)
17653                            (match_dup 2)))
17654      (clobber (reg:CC FLAGS_REG))])]
17655   "TARGET_SSE2 && TARGET_SSE_MATH"
17656   "#")
17657
17658 (define_insn "*mindf"
17659   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17660         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17661                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17662                          (match_dup 1)
17663                          (match_dup 2)))
17664    (clobber (reg:CC FLAGS_REG))]
17665   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17666   "#")
17667
17668 (define_insn "*mindf_nonieee"
17669   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17670         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17671                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17672                          (match_dup 1)
17673                          (match_dup 2)))
17674    (clobber (reg:CC FLAGS_REG))]
17675   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17676    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17677   "#")
17678
17679 (define_split
17680   [(set (match_operand:DF 0 "register_operand" "")
17681         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17682                              (match_operand:DF 2 "nonimmediate_operand" ""))
17683                          (match_operand:DF 3 "register_operand" "")
17684                          (match_operand:DF 4 "nonimmediate_operand" "")))
17685    (clobber (reg:CC FLAGS_REG))]
17686   "SSE_REG_P (operands[0]) && reload_completed
17687    && ((operands_match_p (operands[1], operands[3])
17688         && operands_match_p (operands[2], operands[4]))
17689        || (operands_match_p (operands[1], operands[4])
17690            && operands_match_p (operands[2], operands[3])))"
17691   [(set (match_dup 0)
17692         (if_then_else:DF (lt (match_dup 1)
17693                              (match_dup 2))
17694                          (match_dup 1)
17695                          (match_dup 2)))])
17696
17697 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17698 (define_split
17699   [(set (match_operand:DF 0 "fp_register_operand" "")
17700         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17701                              (match_operand:DF 2 "register_operand" ""))
17702                          (match_operand:DF 3 "register_operand" "")
17703                          (match_operand:DF 4 "register_operand" "")))
17704    (clobber (reg:CC FLAGS_REG))]
17705   "reload_completed
17706    && ((operands_match_p (operands[1], operands[3])
17707         && operands_match_p (operands[2], operands[4]))
17708        || (operands_match_p (operands[1], operands[4])
17709            && operands_match_p (operands[2], operands[3])))"
17710   [(set (reg:CCFP FLAGS_REG)
17711         (compare:CCFP (match_dup 2)
17712                       (match_dup 1)))
17713    (set (match_dup 0)
17714         (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17715                          (match_dup 1)
17716                          (match_dup 2)))])
17717
17718 (define_insn "*mindf_sse"
17719   [(set (match_operand:DF 0 "register_operand" "=Y")
17720         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17721                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17722                          (match_dup 1)
17723                          (match_dup 2)))]
17724   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17725   "minsd\t{%2, %0|%0, %2}"
17726   [(set_attr "type" "sse")
17727    (set_attr "mode" "DF")])
17728
17729 (define_expand "maxsf3"
17730   [(parallel [
17731      (set (match_operand:SF 0 "register_operand" "")
17732           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17733                                (match_operand:SF 2 "nonimmediate_operand" ""))
17734                            (match_dup 1)
17735                            (match_dup 2)))
17736      (clobber (reg:CC FLAGS_REG))])]
17737   "TARGET_SSE"
17738   "#")
17739
17740 (define_insn "*maxsf"
17741   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17742         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17743                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17744                          (match_dup 1)
17745                          (match_dup 2)))
17746    (clobber (reg:CC FLAGS_REG))]
17747   "TARGET_SSE && TARGET_IEEE_FP"
17748   "#")
17749
17750 (define_insn "*maxsf_nonieee"
17751   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17752         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17753                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17754                          (match_dup 1)
17755                          (match_dup 2)))
17756    (clobber (reg:CC FLAGS_REG))]
17757   "TARGET_SSE && !TARGET_IEEE_FP
17758    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17759   "#")
17760
17761 (define_split
17762   [(set (match_operand:SF 0 "register_operand" "")
17763         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17764                              (match_operand:SF 2 "nonimmediate_operand" ""))
17765                          (match_operand:SF 3 "register_operand" "")
17766                          (match_operand:SF 4 "nonimmediate_operand" "")))
17767    (clobber (reg:CC FLAGS_REG))]
17768   "SSE_REG_P (operands[0]) && reload_completed
17769    && ((operands_match_p (operands[1], operands[3])
17770         && operands_match_p (operands[2], operands[4]))
17771        || (operands_match_p (operands[1], operands[4])
17772            && operands_match_p (operands[2], operands[3])))"
17773   [(set (match_dup 0)
17774         (if_then_else:SF (gt (match_dup 1)
17775                              (match_dup 2))
17776                          (match_dup 1)
17777                          (match_dup 2)))])
17778
17779 (define_split
17780   [(set (match_operand:SF 0 "fp_register_operand" "")
17781         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17782                              (match_operand:SF 2 "register_operand" ""))
17783                          (match_operand:SF 3 "register_operand" "")
17784                          (match_operand:SF 4 "register_operand" "")))
17785    (clobber (reg:CC FLAGS_REG))]
17786   "reload_completed
17787    && ((operands_match_p (operands[1], operands[3])
17788         && operands_match_p (operands[2], operands[4]))
17789        || (operands_match_p (operands[1], operands[4])
17790            && operands_match_p (operands[2], operands[3])))"
17791   [(set (reg:CCFP FLAGS_REG)
17792         (compare:CCFP (match_dup 1)
17793                       (match_dup 2)))
17794    (set (match_dup 0)
17795         (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17796                          (match_dup 1)
17797                          (match_dup 2)))])
17798
17799 (define_insn "*maxsf_sse"
17800   [(set (match_operand:SF 0 "register_operand" "=x")
17801         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17802                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17803                          (match_dup 1)
17804                          (match_dup 2)))]
17805   "TARGET_SSE && reload_completed"
17806   "maxss\t{%2, %0|%0, %2}"
17807   [(set_attr "type" "sse")
17808    (set_attr "mode" "SF")])
17809
17810 (define_expand "maxdf3"
17811   [(parallel [
17812      (set (match_operand:DF 0 "register_operand" "")
17813           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17814                                (match_operand:DF 2 "nonimmediate_operand" ""))
17815                            (match_dup 1)
17816                            (match_dup 2)))
17817      (clobber (reg:CC FLAGS_REG))])]
17818   "TARGET_SSE2 && TARGET_SSE_MATH"
17819   "#")
17820
17821 (define_insn "*maxdf"
17822   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17823         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17824                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17825                          (match_dup 1)
17826                          (match_dup 2)))
17827    (clobber (reg:CC FLAGS_REG))]
17828   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17829   "#")
17830
17831 (define_insn "*maxdf_nonieee"
17832   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17833         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17834                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17835                          (match_dup 1)
17836                          (match_dup 2)))
17837    (clobber (reg:CC FLAGS_REG))]
17838   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17839    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17840   "#")
17841
17842 (define_split
17843   [(set (match_operand:DF 0 "register_operand" "")
17844         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17845                              (match_operand:DF 2 "nonimmediate_operand" ""))
17846                          (match_operand:DF 3 "register_operand" "")
17847                          (match_operand:DF 4 "nonimmediate_operand" "")))
17848    (clobber (reg:CC FLAGS_REG))]
17849   "SSE_REG_P (operands[0]) && reload_completed
17850    && ((operands_match_p (operands[1], operands[3])
17851         && operands_match_p (operands[2], operands[4]))
17852        || (operands_match_p (operands[1], operands[4])
17853            && operands_match_p (operands[2], operands[3])))"
17854   [(set (match_dup 0)
17855         (if_then_else:DF (gt (match_dup 1)
17856                              (match_dup 2))
17857                          (match_dup 1)
17858                          (match_dup 2)))])
17859
17860 (define_split
17861   [(set (match_operand:DF 0 "fp_register_operand" "")
17862         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17863                              (match_operand:DF 2 "register_operand" ""))
17864                          (match_operand:DF 3 "register_operand" "")
17865                          (match_operand:DF 4 "register_operand" "")))
17866    (clobber (reg:CC FLAGS_REG))]
17867   "reload_completed
17868    && ((operands_match_p (operands[1], operands[3])
17869         && operands_match_p (operands[2], operands[4]))
17870        || (operands_match_p (operands[1], operands[4])
17871            && operands_match_p (operands[2], operands[3])))"
17872   [(set (reg:CCFP FLAGS_REG)
17873         (compare:CCFP (match_dup 1)
17874                       (match_dup 2)))
17875    (set (match_dup 0)
17876         (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17877                          (match_dup 1)
17878                          (match_dup 2)))])
17879
17880 (define_insn "*maxdf_sse"
17881   [(set (match_operand:DF 0 "register_operand" "=Y")
17882         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17883                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17884                          (match_dup 1)
17885                          (match_dup 2)))]
17886   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17887   "maxsd\t{%2, %0|%0, %2}"
17888   [(set_attr "type" "sse")
17889    (set_attr "mode" "DF")])
17890 \f
17891 ;; Misc patterns (?)
17892
17893 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17894 ;; Otherwise there will be nothing to keep
17895 ;; 
17896 ;; [(set (reg ebp) (reg esp))]
17897 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17898 ;;  (clobber (eflags)]
17899 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17900 ;;
17901 ;; in proper program order.
17902 (define_insn "pro_epilogue_adjust_stack_1"
17903   [(set (match_operand:SI 0 "register_operand" "=r,r")
17904         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17905                  (match_operand:SI 2 "immediate_operand" "i,i")))
17906    (clobber (reg:CC FLAGS_REG))
17907    (clobber (mem:BLK (scratch)))]
17908   "!TARGET_64BIT"
17909 {
17910   switch (get_attr_type (insn))
17911     {
17912     case TYPE_IMOV:
17913       return "mov{l}\t{%1, %0|%0, %1}";
17914
17915     case TYPE_ALU:
17916       if (GET_CODE (operands[2]) == CONST_INT
17917           && (INTVAL (operands[2]) == 128
17918               || (INTVAL (operands[2]) < 0
17919                   && INTVAL (operands[2]) != -128)))
17920         {
17921           operands[2] = GEN_INT (-INTVAL (operands[2]));
17922           return "sub{l}\t{%2, %0|%0, %2}";
17923         }
17924       return "add{l}\t{%2, %0|%0, %2}";
17925
17926     case TYPE_LEA:
17927       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17928       return "lea{l}\t{%a2, %0|%0, %a2}";
17929
17930     default:
17931       abort ();
17932     }
17933 }
17934   [(set (attr "type")
17935         (cond [(eq_attr "alternative" "0")
17936                  (const_string "alu")
17937                (match_operand:SI 2 "const0_operand" "")
17938                  (const_string "imov")
17939               ]
17940               (const_string "lea")))
17941    (set_attr "mode" "SI")])
17942
17943 (define_insn "pro_epilogue_adjust_stack_rex64"
17944   [(set (match_operand:DI 0 "register_operand" "=r,r")
17945         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17946                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17947    (clobber (reg:CC FLAGS_REG))
17948    (clobber (mem:BLK (scratch)))]
17949   "TARGET_64BIT"
17950 {
17951   switch (get_attr_type (insn))
17952     {
17953     case TYPE_IMOV:
17954       return "mov{q}\t{%1, %0|%0, %1}";
17955
17956     case TYPE_ALU:
17957       if (GET_CODE (operands[2]) == CONST_INT
17958           /* Avoid overflows.  */
17959           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17960           && (INTVAL (operands[2]) == 128
17961               || (INTVAL (operands[2]) < 0
17962                   && INTVAL (operands[2]) != -128)))
17963         {
17964           operands[2] = GEN_INT (-INTVAL (operands[2]));
17965           return "sub{q}\t{%2, %0|%0, %2}";
17966         }
17967       return "add{q}\t{%2, %0|%0, %2}";
17968
17969     case TYPE_LEA:
17970       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17971       return "lea{q}\t{%a2, %0|%0, %a2}";
17972
17973     default:
17974       abort ();
17975     }
17976 }
17977   [(set (attr "type")
17978         (cond [(eq_attr "alternative" "0")
17979                  (const_string "alu")
17980                (match_operand:DI 2 "const0_operand" "")
17981                  (const_string "imov")
17982               ]
17983               (const_string "lea")))
17984    (set_attr "mode" "DI")])
17985
17986 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17987   [(set (match_operand:DI 0 "register_operand" "=r,r")
17988         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17989                  (match_operand:DI 3 "immediate_operand" "i,i")))
17990    (use (match_operand:DI 2 "register_operand" "r,r"))
17991    (clobber (reg:CC FLAGS_REG))
17992    (clobber (mem:BLK (scratch)))]
17993   "TARGET_64BIT"
17994 {
17995   switch (get_attr_type (insn))
17996     {
17997     case TYPE_ALU:
17998       return "add{q}\t{%2, %0|%0, %2}";
17999
18000     case TYPE_LEA:
18001       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18002       return "lea{q}\t{%a2, %0|%0, %a2}";
18003
18004     default:
18005       abort ();
18006     }
18007 }
18008   [(set_attr "type" "alu,lea")
18009    (set_attr "mode" "DI")])
18010
18011 ;; Placeholder for the conditional moves.  This one is split either to SSE
18012 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
18013 ;; fact is that compares supported by the cmp??ss instructions are exactly
18014 ;; swapped of those supported by cmove sequence.
18015 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18016 ;; supported by i387 comparisons and we do need to emit two conditional moves
18017 ;; in tandem.
18018
18019 (define_insn "sse_movsfcc"
18020   [(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")
18021         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18022                         [(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")
18023                          (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")])
18024                       (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")
18025                       (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")))
18026    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18027    (clobber (reg:CC FLAGS_REG))]
18028   "TARGET_SSE
18029    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18030    /* Avoid combine from being smart and converting min/max
18031       instruction patterns into conditional moves.  */
18032    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18033         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18034        || !rtx_equal_p (operands[4], operands[2])
18035        || !rtx_equal_p (operands[5], operands[3]))
18036    && (!TARGET_IEEE_FP
18037        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18038   "#")
18039
18040 (define_insn "sse_movsfcc_eq"
18041   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18042         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18043                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18044                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18045                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18046    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18047    (clobber (reg:CC FLAGS_REG))]
18048   "TARGET_SSE
18049    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18050   "#")
18051
18052 (define_insn "sse_movdfcc"
18053   [(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")
18054         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18055                         [(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")
18056                          (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")])
18057                       (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")
18058                       (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")))
18059    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18060    (clobber (reg:CC FLAGS_REG))]
18061   "TARGET_SSE2
18062    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18063    /* Avoid combine from being smart and converting min/max
18064       instruction patterns into conditional moves.  */
18065    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18066         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18067        || !rtx_equal_p (operands[4], operands[2])
18068        || !rtx_equal_p (operands[5], operands[3]))
18069    && (!TARGET_IEEE_FP
18070        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18071   "#")
18072
18073 (define_insn "sse_movdfcc_eq"
18074   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18075         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18076                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18077                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18078                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18079    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18080    (clobber (reg:CC FLAGS_REG))]
18081   "TARGET_SSE
18082    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18083   "#")
18084
18085 ;; For non-sse moves just expand the usual cmove sequence.
18086 (define_split
18087   [(set (match_operand 0 "register_operand" "")
18088         (if_then_else (match_operator 1 "comparison_operator"
18089                         [(match_operand 4 "nonimmediate_operand" "")
18090                          (match_operand 5 "register_operand" "")])
18091                       (match_operand 2 "nonimmediate_operand" "")
18092                       (match_operand 3 "nonimmediate_operand" "")))
18093    (clobber (match_operand 6 "" ""))
18094    (clobber (reg:CC FLAGS_REG))]
18095   "!SSE_REG_P (operands[0]) && reload_completed
18096    && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
18097   [(const_int 0)]
18098 {
18099    ix86_compare_op0 = operands[5];
18100    ix86_compare_op1 = operands[4];
18101    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18102                                  VOIDmode, operands[5], operands[4]);
18103    ix86_expand_fp_movcc (operands);
18104    DONE;
18105 })
18106
18107 ;; Split SSE based conditional move into sequence:
18108 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
18109 ;; and   op2, op0   -  zero op2 if comparison was false
18110 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
18111 ;; or    op2, op0   -  get the nonzero one into the result.
18112 (define_split
18113   [(set (match_operand:SF 0 "register_operand" "")
18114         (if_then_else (match_operator:SF 1 "sse_comparison_operator"
18115                         [(match_operand:SF 4 "register_operand" "")
18116                          (match_operand:SF 5 "nonimmediate_operand" "")])
18117                       (match_operand:SF 2 "register_operand" "")
18118                       (match_operand:SF 3 "register_operand" "")))
18119    (clobber (match_operand 6 "" ""))
18120    (clobber (reg:CC FLAGS_REG))]
18121   "SSE_REG_P (operands[0]) && reload_completed"
18122   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18123    (set (match_dup 2) (and:V4SF (match_dup 2)
18124                                 (match_dup 8)))
18125    (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18126                                           (match_dup 3)))
18127    (set (match_dup 0) (ior:V4SF (match_dup 6)
18128                                 (match_dup 7)))]
18129 {
18130   /* If op2 == op3, op3 would be clobbered before it is used.  */
18131   if (operands_match_p (operands[2], operands[3]))
18132     {
18133       emit_move_insn (operands[0], operands[2]);
18134       DONE;
18135     }
18136
18137   PUT_MODE (operands[1], GET_MODE (operands[0]));
18138   if (operands_match_p (operands[0], operands[4]))
18139     operands[6] = operands[4], operands[7] = operands[2];
18140   else
18141     operands[6] = operands[2], operands[7] = operands[4];
18142   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18143   operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18144   operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18145   operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18146   operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18147   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18148 })
18149
18150 (define_split
18151   [(set (match_operand:DF 0 "register_operand" "")
18152         (if_then_else (match_operator:DF 1 "sse_comparison_operator"
18153                         [(match_operand:DF 4 "register_operand" "")
18154                          (match_operand:DF 5 "nonimmediate_operand" "")])
18155                       (match_operand:DF 2 "register_operand" "")
18156                       (match_operand:DF 3 "register_operand" "")))
18157    (clobber (match_operand 6 "" ""))
18158    (clobber (reg:CC FLAGS_REG))]
18159   "SSE_REG_P (operands[0]) && reload_completed"
18160   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18161    (set (match_dup 2) (and:V2DF (match_dup 2)
18162                                 (match_dup 8)))
18163    (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18164                                           (match_dup 3)))
18165    (set (match_dup 0) (ior:V2DF (match_dup 6)
18166                                 (match_dup 7)))]
18167 {
18168   if (GET_MODE (operands[2]) == DFmode
18169       && TARGET_SSE_PARTIAL_REGS && !optimize_size)
18170     {
18171       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18172       emit_insn (gen_sse2_unpcklpd (op, op, op));
18173       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18174       emit_insn (gen_sse2_unpcklpd (op, op, op));
18175     }
18176
18177   /* If op2 == op3, op3 would be clobbered before it is used.  */
18178   if (operands_match_p (operands[2], operands[3]))
18179     {
18180       emit_move_insn (operands[0], operands[2]);
18181       DONE;
18182     }
18183
18184   PUT_MODE (operands[1], GET_MODE (operands[0]));
18185   if (operands_match_p (operands[0], operands[4]))
18186     operands[6] = operands[4], operands[7] = operands[2];
18187   else
18188     operands[6] = operands[2], operands[7] = operands[4];
18189   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18190   operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18191   operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18192   operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18193   operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18194   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18195 })
18196
18197 ;; Special case of conditional move we can handle effectively.
18198 ;; Do not brother with the integer/floating point case, since these are
18199 ;; bot considerably slower, unlike in the generic case.
18200 (define_insn "*sse_movsfcc_const0_1"
18201   [(set (match_operand:SF 0 "register_operand" "=&x")
18202         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18203                         [(match_operand:SF 4 "register_operand" "0")
18204                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18205                       (match_operand:SF 2 "register_operand" "x")
18206                       (match_operand:SF 3 "const0_operand" "X")))]
18207   "TARGET_SSE"
18208   "#")
18209
18210 (define_insn "*sse_movsfcc_const0_2"
18211   [(set (match_operand:SF 0 "register_operand" "=&x")
18212         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18213                         [(match_operand:SF 4 "register_operand" "0")
18214                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18215                       (match_operand:SF 2 "const0_operand" "X")
18216                       (match_operand:SF 3 "register_operand" "x")))]
18217   "TARGET_SSE"
18218   "#")
18219
18220 (define_insn "*sse_movsfcc_const0_3"
18221   [(set (match_operand:SF 0 "register_operand" "=&x")
18222         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18223                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18224                          (match_operand:SF 5 "register_operand" "0")])
18225                       (match_operand:SF 2 "register_operand" "x")
18226                       (match_operand:SF 3 "const0_operand" "X")))]
18227   "TARGET_SSE"
18228   "#")
18229
18230 (define_insn "*sse_movsfcc_const0_4"
18231   [(set (match_operand:SF 0 "register_operand" "=&x")
18232         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18233                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18234                          (match_operand:SF 5 "register_operand" "0")])
18235                       (match_operand:SF 2 "const0_operand" "X")
18236                       (match_operand:SF 3 "register_operand" "x")))]
18237   "TARGET_SSE"
18238   "#")
18239
18240 (define_insn "*sse_movdfcc_const0_1"
18241   [(set (match_operand:DF 0 "register_operand" "=&Y")
18242         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18243                         [(match_operand:DF 4 "register_operand" "0")
18244                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18245                       (match_operand:DF 2 "register_operand" "Y")
18246                       (match_operand:DF 3 "const0_operand" "X")))]
18247   "TARGET_SSE2"
18248   "#")
18249
18250 (define_insn "*sse_movdfcc_const0_2"
18251   [(set (match_operand:DF 0 "register_operand" "=&Y")
18252         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18253                         [(match_operand:DF 4 "register_operand" "0")
18254                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18255                       (match_operand:DF 2 "const0_operand" "X")
18256                       (match_operand:DF 3 "register_operand" "Y")))]
18257   "TARGET_SSE2"
18258   "#")
18259
18260 (define_insn "*sse_movdfcc_const0_3"
18261   [(set (match_operand:DF 0 "register_operand" "=&Y")
18262         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18263                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18264                          (match_operand:DF 5 "register_operand" "0")])
18265                       (match_operand:DF 2 "register_operand" "Y")
18266                       (match_operand:DF 3 "const0_operand" "X")))]
18267   "TARGET_SSE2"
18268   "#")
18269
18270 (define_insn "*sse_movdfcc_const0_4"
18271   [(set (match_operand:DF 0 "register_operand" "=&Y")
18272         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18273                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18274                          (match_operand:DF 5 "register_operand" "0")])
18275                       (match_operand:DF 2 "const0_operand" "X")
18276                       (match_operand:DF 3 "register_operand" "Y")))]
18277   "TARGET_SSE2"
18278   "#")
18279
18280 (define_split
18281   [(set (match_operand:SF 0 "register_operand" "")
18282         (if_then_else (match_operator 1 "comparison_operator"
18283                         [(match_operand:SF 4 "nonimmediate_operand" "")
18284                          (match_operand:SF 5 "nonimmediate_operand" "")])
18285                       (match_operand:SF 2 "nonmemory_operand" "")
18286                       (match_operand:SF 3 "nonmemory_operand" "")))]
18287   "SSE_REG_P (operands[0]) && reload_completed
18288    && (const0_operand (operands[2], GET_MODE (operands[0]))
18289        || const0_operand (operands[3], GET_MODE (operands[0])))"
18290   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18291    (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18292 {
18293   PUT_MODE (operands[1], GET_MODE (operands[0]));
18294   if (!sse_comparison_operator (operands[1], VOIDmode)
18295       || !rtx_equal_p (operands[0], operands[4]))
18296     {
18297       rtx tmp = operands[5];
18298       operands[5] = operands[4];
18299       operands[4] = tmp;
18300       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18301     }
18302   if (!rtx_equal_p (operands[0], operands[4]))
18303     abort ();
18304   operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18305   if (const0_operand (operands[2], GET_MODE (operands[2])))
18306     {
18307       operands[7] = operands[3];
18308       operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18309     }
18310   else
18311     {
18312       operands[7] = operands[2];
18313       operands[6] = operands[8];
18314     }
18315   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18316 })
18317
18318 (define_split
18319   [(set (match_operand:DF 0 "register_operand" "")
18320         (if_then_else (match_operator 1 "comparison_operator"
18321                         [(match_operand:DF 4 "nonimmediate_operand" "")
18322                          (match_operand:DF 5 "nonimmediate_operand" "")])
18323                       (match_operand:DF 2 "nonmemory_operand" "")
18324                       (match_operand:DF 3 "nonmemory_operand" "")))]
18325   "SSE_REG_P (operands[0]) && reload_completed
18326    && (const0_operand (operands[2], GET_MODE (operands[0]))
18327        || const0_operand (operands[3], GET_MODE (operands[0])))"
18328   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18329    (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18330 {
18331   if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18332       && GET_MODE (operands[2]) == DFmode)
18333     {
18334       if (REG_P (operands[2]))
18335         {
18336           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18337           emit_insn (gen_sse2_unpcklpd (op, op, op));
18338         }
18339       if (REG_P (operands[3]))
18340         {
18341           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18342           emit_insn (gen_sse2_unpcklpd (op, op, op));
18343         }
18344     }
18345   PUT_MODE (operands[1], GET_MODE (operands[0]));
18346   if (!sse_comparison_operator (operands[1], VOIDmode)
18347       || !rtx_equal_p (operands[0], operands[4]))
18348     {
18349       rtx tmp = operands[5];
18350       operands[5] = operands[4];
18351       operands[4] = tmp;
18352       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18353     }
18354   if (!rtx_equal_p (operands[0], operands[4]))
18355     abort ();
18356   operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18357   if (const0_operand (operands[2], GET_MODE (operands[2])))
18358     {
18359       operands[7] = operands[3];
18360       operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18361     }
18362   else
18363     {
18364       operands[7] = operands[2];
18365       operands[6] = operands[8];
18366     }
18367   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18368 })
18369
18370 (define_expand "allocate_stack_worker"
18371   [(match_operand:SI 0 "register_operand" "")]
18372   "TARGET_STACK_PROBE"
18373 {
18374   if (reload_completed)
18375     {
18376       if (TARGET_64BIT)
18377         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18378       else
18379         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18380     }
18381   else
18382     {
18383       if (TARGET_64BIT)
18384         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18385       else
18386         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18387     }
18388   DONE;
18389 })
18390
18391 (define_insn "allocate_stack_worker_1"
18392   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18393     UNSPECV_STACK_PROBE)
18394    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18395    (clobber (match_scratch:SI 1 "=0"))
18396    (clobber (reg:CC FLAGS_REG))]
18397   "!TARGET_64BIT && TARGET_STACK_PROBE"
18398   "call\t__alloca"
18399   [(set_attr "type" "multi")
18400    (set_attr "length" "5")])
18401
18402 (define_expand "allocate_stack_worker_postreload"
18403   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18404                                     UNSPECV_STACK_PROBE)
18405               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18406               (clobber (match_dup 0))
18407               (clobber (reg:CC FLAGS_REG))])]
18408   ""
18409   "")
18410
18411 (define_insn "allocate_stack_worker_rex64"
18412   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18413     UNSPECV_STACK_PROBE)
18414    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18415    (clobber (match_scratch:DI 1 "=0"))
18416    (clobber (reg:CC FLAGS_REG))]
18417   "TARGET_64BIT && TARGET_STACK_PROBE"
18418   "call\t__alloca"
18419   [(set_attr "type" "multi")
18420    (set_attr "length" "5")])
18421
18422 (define_expand "allocate_stack_worker_rex64_postreload"
18423   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18424                                     UNSPECV_STACK_PROBE)
18425               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18426               (clobber (match_dup 0))
18427               (clobber (reg:CC FLAGS_REG))])]
18428   ""
18429   "")
18430
18431 (define_expand "allocate_stack"
18432   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18433                    (minus:SI (reg:SI SP_REG)
18434                              (match_operand:SI 1 "general_operand" "")))
18435               (clobber (reg:CC FLAGS_REG))])
18436    (parallel [(set (reg:SI SP_REG)
18437                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18438               (clobber (reg:CC FLAGS_REG))])]
18439   "TARGET_STACK_PROBE"
18440 {
18441 #ifdef CHECK_STACK_LIMIT
18442   if (GET_CODE (operands[1]) == CONST_INT
18443       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18444     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18445                            operands[1]));
18446   else 
18447 #endif
18448     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18449                                                             operands[1])));
18450
18451   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18452   DONE;
18453 })
18454
18455 (define_expand "builtin_setjmp_receiver"
18456   [(label_ref (match_operand 0 "" ""))]
18457   "!TARGET_64BIT && flag_pic"
18458 {
18459   emit_insn (gen_set_got (pic_offset_table_rtx));
18460   DONE;
18461 })
18462 \f
18463 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18464
18465 (define_split
18466   [(set (match_operand 0 "register_operand" "")
18467         (match_operator 3 "promotable_binary_operator"
18468            [(match_operand 1 "register_operand" "")
18469             (match_operand 2 "aligned_operand" "")]))
18470    (clobber (reg:CC FLAGS_REG))]
18471   "! TARGET_PARTIAL_REG_STALL && reload_completed
18472    && ((GET_MODE (operands[0]) == HImode 
18473         && ((!optimize_size && !TARGET_FAST_PREFIX)
18474             || GET_CODE (operands[2]) != CONST_INT
18475             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18476        || (GET_MODE (operands[0]) == QImode 
18477            && (TARGET_PROMOTE_QImode || optimize_size)))"
18478   [(parallel [(set (match_dup 0)
18479                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18480               (clobber (reg:CC FLAGS_REG))])]
18481   "operands[0] = gen_lowpart (SImode, operands[0]);
18482    operands[1] = gen_lowpart (SImode, operands[1]);
18483    if (GET_CODE (operands[3]) != ASHIFT)
18484      operands[2] = gen_lowpart (SImode, operands[2]);
18485    PUT_MODE (operands[3], SImode);")
18486
18487 ; Promote the QImode tests, as i386 has encoding of the AND
18488 ; instruction with 32-bit sign-extended immediate and thus the
18489 ; instruction size is unchanged, except in the %eax case for
18490 ; which it is increased by one byte, hence the ! optimize_size.
18491 (define_split
18492   [(set (reg 17)
18493         (compare (and (match_operand 1 "aligned_operand" "")
18494                       (match_operand 2 "const_int_operand" ""))
18495                  (const_int 0)))
18496    (set (match_operand 0 "register_operand" "")
18497         (and (match_dup 1) (match_dup 2)))]
18498   "! TARGET_PARTIAL_REG_STALL && reload_completed
18499    /* Ensure that the operand will remain sign-extended immediate.  */
18500    && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
18501    && ! optimize_size
18502    && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
18503        || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
18504   [(parallel [(set (reg:CCNO FLAGS_REG)
18505                    (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
18506                                  (const_int 0)))
18507               (set (match_dup 0)
18508                    (and:SI (match_dup 1) (match_dup 2)))])]
18509   "operands[2]
18510      = gen_int_mode (INTVAL (operands[2])
18511                      & GET_MODE_MASK (GET_MODE (operands[0])),
18512                      SImode);
18513    operands[0] = gen_lowpart (SImode, operands[0]);
18514    operands[1] = gen_lowpart (SImode, operands[1]);")
18515
18516 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18517 ; the TEST instruction with 32-bit sign-extended immediate and thus
18518 ; the instruction size would at least double, which is not what we
18519 ; want even with ! optimize_size.
18520 (define_split
18521   [(set (reg 17)
18522         (compare (and (match_operand:HI 0 "aligned_operand" "")
18523                       (match_operand:HI 1 "const_int_operand" ""))
18524                  (const_int 0)))]
18525   "! TARGET_PARTIAL_REG_STALL && reload_completed
18526    /* Ensure that the operand will remain sign-extended immediate.  */
18527    && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
18528    && ! TARGET_FAST_PREFIX
18529    && ! optimize_size"
18530   [(set (reg:CCNO FLAGS_REG)
18531         (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
18532                       (const_int 0)))]
18533   "operands[1]
18534      = gen_int_mode (INTVAL (operands[1])
18535                      & GET_MODE_MASK (GET_MODE (operands[0])),
18536                      SImode);
18537    operands[0] = gen_lowpart (SImode, operands[0]);")
18538
18539 (define_split
18540   [(set (match_operand 0 "register_operand" "")
18541         (neg (match_operand 1 "register_operand" "")))
18542    (clobber (reg:CC FLAGS_REG))]
18543   "! TARGET_PARTIAL_REG_STALL && reload_completed
18544    && (GET_MODE (operands[0]) == HImode
18545        || (GET_MODE (operands[0]) == QImode 
18546            && (TARGET_PROMOTE_QImode || optimize_size)))"
18547   [(parallel [(set (match_dup 0)
18548                    (neg:SI (match_dup 1)))
18549               (clobber (reg:CC FLAGS_REG))])]
18550   "operands[0] = gen_lowpart (SImode, operands[0]);
18551    operands[1] = gen_lowpart (SImode, operands[1]);")
18552
18553 (define_split
18554   [(set (match_operand 0 "register_operand" "")
18555         (not (match_operand 1 "register_operand" "")))]
18556   "! TARGET_PARTIAL_REG_STALL && reload_completed
18557    && (GET_MODE (operands[0]) == HImode
18558        || (GET_MODE (operands[0]) == QImode 
18559            && (TARGET_PROMOTE_QImode || optimize_size)))"
18560   [(set (match_dup 0)
18561         (not:SI (match_dup 1)))]
18562   "operands[0] = gen_lowpart (SImode, operands[0]);
18563    operands[1] = gen_lowpart (SImode, operands[1]);")
18564
18565 (define_split 
18566   [(set (match_operand 0 "register_operand" "")
18567         (if_then_else (match_operator 1 "comparison_operator" 
18568                                 [(reg 17) (const_int 0)])
18569                       (match_operand 2 "register_operand" "")
18570                       (match_operand 3 "register_operand" "")))]
18571   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18572    && (GET_MODE (operands[0]) == HImode
18573        || (GET_MODE (operands[0]) == QImode 
18574            && (TARGET_PROMOTE_QImode || optimize_size)))"
18575   [(set (match_dup 0)
18576         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18577   "operands[0] = gen_lowpart (SImode, operands[0]);
18578    operands[2] = gen_lowpart (SImode, operands[2]);
18579    operands[3] = gen_lowpart (SImode, operands[3]);")
18580                         
18581 \f
18582 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18583 ;; transform a complex memory operation into two memory to register operations.
18584
18585 ;; Don't push memory operands
18586 (define_peephole2
18587   [(set (match_operand:SI 0 "push_operand" "")
18588         (match_operand:SI 1 "memory_operand" ""))
18589    (match_scratch:SI 2 "r")]
18590   "! optimize_size && ! TARGET_PUSH_MEMORY"
18591   [(set (match_dup 2) (match_dup 1))
18592    (set (match_dup 0) (match_dup 2))]
18593   "")
18594
18595 (define_peephole2
18596   [(set (match_operand:DI 0 "push_operand" "")
18597         (match_operand:DI 1 "memory_operand" ""))
18598    (match_scratch:DI 2 "r")]
18599   "! optimize_size && ! TARGET_PUSH_MEMORY"
18600   [(set (match_dup 2) (match_dup 1))
18601    (set (match_dup 0) (match_dup 2))]
18602   "")
18603
18604 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18605 ;; SImode pushes.
18606 (define_peephole2
18607   [(set (match_operand:SF 0 "push_operand" "")
18608         (match_operand:SF 1 "memory_operand" ""))
18609    (match_scratch:SF 2 "r")]
18610   "! optimize_size && ! TARGET_PUSH_MEMORY"
18611   [(set (match_dup 2) (match_dup 1))
18612    (set (match_dup 0) (match_dup 2))]
18613   "")
18614
18615 (define_peephole2
18616   [(set (match_operand:HI 0 "push_operand" "")
18617         (match_operand:HI 1 "memory_operand" ""))
18618    (match_scratch:HI 2 "r")]
18619   "! optimize_size && ! TARGET_PUSH_MEMORY"
18620   [(set (match_dup 2) (match_dup 1))
18621    (set (match_dup 0) (match_dup 2))]
18622   "")
18623
18624 (define_peephole2
18625   [(set (match_operand:QI 0 "push_operand" "")
18626         (match_operand:QI 1 "memory_operand" ""))
18627    (match_scratch:QI 2 "q")]
18628   "! optimize_size && ! TARGET_PUSH_MEMORY"
18629   [(set (match_dup 2) (match_dup 1))
18630    (set (match_dup 0) (match_dup 2))]
18631   "")
18632
18633 ;; Don't move an immediate directly to memory when the instruction
18634 ;; gets too big.
18635 (define_peephole2
18636   [(match_scratch:SI 1 "r")
18637    (set (match_operand:SI 0 "memory_operand" "")
18638         (const_int 0))]
18639   "! optimize_size
18640    && ! TARGET_USE_MOV0
18641    && TARGET_SPLIT_LONG_MOVES
18642    && get_attr_length (insn) >= ix86_cost->large_insn
18643    && peep2_regno_dead_p (0, FLAGS_REG)"
18644   [(parallel [(set (match_dup 1) (const_int 0))
18645               (clobber (reg:CC FLAGS_REG))])
18646    (set (match_dup 0) (match_dup 1))]
18647   "")
18648
18649 (define_peephole2
18650   [(match_scratch:HI 1 "r")
18651    (set (match_operand:HI 0 "memory_operand" "")
18652         (const_int 0))]
18653   "! optimize_size
18654    && ! TARGET_USE_MOV0
18655    && TARGET_SPLIT_LONG_MOVES
18656    && get_attr_length (insn) >= ix86_cost->large_insn
18657    && peep2_regno_dead_p (0, FLAGS_REG)"
18658   [(parallel [(set (match_dup 2) (const_int 0))
18659               (clobber (reg:CC FLAGS_REG))])
18660    (set (match_dup 0) (match_dup 1))]
18661   "operands[2] = gen_lowpart (SImode, operands[1]);")
18662
18663 (define_peephole2
18664   [(match_scratch:QI 1 "q")
18665    (set (match_operand:QI 0 "memory_operand" "")
18666         (const_int 0))]
18667   "! optimize_size
18668    && ! TARGET_USE_MOV0
18669    && TARGET_SPLIT_LONG_MOVES
18670    && get_attr_length (insn) >= ix86_cost->large_insn
18671    && peep2_regno_dead_p (0, FLAGS_REG)"
18672   [(parallel [(set (match_dup 2) (const_int 0))
18673               (clobber (reg:CC FLAGS_REG))])
18674    (set (match_dup 0) (match_dup 1))]
18675   "operands[2] = gen_lowpart (SImode, operands[1]);")
18676
18677 (define_peephole2
18678   [(match_scratch:SI 2 "r")
18679    (set (match_operand:SI 0 "memory_operand" "")
18680         (match_operand:SI 1 "immediate_operand" ""))]
18681   "! optimize_size
18682    && get_attr_length (insn) >= ix86_cost->large_insn
18683    && TARGET_SPLIT_LONG_MOVES"
18684   [(set (match_dup 2) (match_dup 1))
18685    (set (match_dup 0) (match_dup 2))]
18686   "")
18687
18688 (define_peephole2
18689   [(match_scratch:HI 2 "r")
18690    (set (match_operand:HI 0 "memory_operand" "")
18691         (match_operand:HI 1 "immediate_operand" ""))]
18692   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18693   && TARGET_SPLIT_LONG_MOVES"
18694   [(set (match_dup 2) (match_dup 1))
18695    (set (match_dup 0) (match_dup 2))]
18696   "")
18697
18698 (define_peephole2
18699   [(match_scratch:QI 2 "q")
18700    (set (match_operand:QI 0 "memory_operand" "")
18701         (match_operand:QI 1 "immediate_operand" ""))]
18702   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18703   && TARGET_SPLIT_LONG_MOVES"
18704   [(set (match_dup 2) (match_dup 1))
18705    (set (match_dup 0) (match_dup 2))]
18706   "")
18707
18708 ;; Don't compare memory with zero, load and use a test instead.
18709 (define_peephole2
18710   [(set (reg 17)
18711         (compare (match_operand:SI 0 "memory_operand" "")
18712                  (const_int 0)))
18713    (match_scratch:SI 3 "r")]
18714   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18715   [(set (match_dup 3) (match_dup 0))
18716    (set (reg:CCNO FLAGS_REG) (compare:CCNO (match_dup 3) (const_int 0)))]
18717   "")
18718
18719 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18720 ;; Don't split NOTs with a displacement operand, because resulting XOR
18721 ;; will not be pairable anyway.
18722 ;;
18723 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
18724 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18725 ;; so this split helps here as well.
18726 ;;
18727 ;; Note: Can't do this as a regular split because we can't get proper
18728 ;; lifetime information then.
18729
18730 (define_peephole2
18731   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18732         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18733   "!optimize_size
18734    && peep2_regno_dead_p (0, FLAGS_REG)
18735    && ((TARGET_PENTIUM 
18736         && (GET_CODE (operands[0]) != MEM
18737             || !memory_displacement_operand (operands[0], SImode)))
18738        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18739   [(parallel [(set (match_dup 0)
18740                    (xor:SI (match_dup 1) (const_int -1)))
18741               (clobber (reg:CC FLAGS_REG))])]
18742   "")
18743
18744 (define_peephole2
18745   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18746         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18747   "!optimize_size
18748    && peep2_regno_dead_p (0, FLAGS_REG)
18749    && ((TARGET_PENTIUM 
18750         && (GET_CODE (operands[0]) != MEM
18751             || !memory_displacement_operand (operands[0], HImode)))
18752        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18753   [(parallel [(set (match_dup 0)
18754                    (xor:HI (match_dup 1) (const_int -1)))
18755               (clobber (reg:CC FLAGS_REG))])]
18756   "")
18757
18758 (define_peephole2
18759   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18760         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18761   "!optimize_size
18762    && peep2_regno_dead_p (0, FLAGS_REG)
18763    && ((TARGET_PENTIUM 
18764         && (GET_CODE (operands[0]) != MEM
18765             || !memory_displacement_operand (operands[0], QImode)))
18766        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18767   [(parallel [(set (match_dup 0)
18768                    (xor:QI (match_dup 1) (const_int -1)))
18769               (clobber (reg:CC FLAGS_REG))])]
18770   "")
18771
18772 ;; Non pairable "test imm, reg" instructions can be translated to
18773 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18774 ;; byte opcode instead of two, have a short form for byte operands),
18775 ;; so do it for other CPUs as well.  Given that the value was dead,
18776 ;; this should not create any new dependencies.  Pass on the sub-word
18777 ;; versions if we're concerned about partial register stalls.
18778
18779 (define_peephole2
18780   [(set (reg 17)
18781         (compare (and:SI (match_operand:SI 0 "register_operand" "")
18782                          (match_operand:SI 1 "immediate_operand" ""))
18783                  (const_int 0)))]
18784   "ix86_match_ccmode (insn, CCNOmode)
18785    && (true_regnum (operands[0]) != 0
18786        || (GET_CODE (operands[1]) == CONST_INT
18787            && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
18788    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18789   [(parallel
18790      [(set (reg:CCNO FLAGS_REG)
18791            (compare:CCNO (and:SI (match_dup 0)
18792                                  (match_dup 1))
18793                          (const_int 0)))
18794       (set (match_dup 0)
18795            (and:SI (match_dup 0) (match_dup 1)))])]
18796   "")
18797
18798 ;; We don't need to handle HImode case, because it will be promoted to SImode
18799 ;; on ! TARGET_PARTIAL_REG_STALL
18800
18801 (define_peephole2
18802   [(set (reg 17)
18803         (compare (and:QI (match_operand:QI 0 "register_operand" "")
18804                          (match_operand:QI 1 "immediate_operand" ""))
18805                  (const_int 0)))]
18806   "! TARGET_PARTIAL_REG_STALL
18807    && ix86_match_ccmode (insn, CCNOmode)
18808    && true_regnum (operands[0]) != 0
18809    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18810   [(parallel
18811      [(set (reg:CCNO FLAGS_REG)
18812            (compare:CCNO (and:QI (match_dup 0)
18813                                  (match_dup 1))
18814                          (const_int 0)))
18815       (set (match_dup 0)
18816            (and:QI (match_dup 0) (match_dup 1)))])]
18817   "")
18818
18819 (define_peephole2
18820   [(set (reg 17)
18821         (compare
18822           (and:SI
18823             (zero_extract:SI
18824               (match_operand 0 "ext_register_operand" "")
18825               (const_int 8)
18826               (const_int 8))
18827             (match_operand 1 "const_int_operand" ""))
18828           (const_int 0)))]
18829   "! TARGET_PARTIAL_REG_STALL
18830    && ix86_match_ccmode (insn, CCNOmode)
18831    && true_regnum (operands[0]) != 0
18832    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18833   [(parallel [(set (reg:CCNO FLAGS_REG)
18834                    (compare:CCNO
18835                        (and:SI
18836                          (zero_extract:SI
18837                          (match_dup 0)
18838                          (const_int 8)
18839                          (const_int 8))
18840                         (match_dup 1))
18841                    (const_int 0)))
18842               (set (zero_extract:SI (match_dup 0)
18843                                     (const_int 8)
18844                                     (const_int 8))
18845                    (and:SI 
18846                      (zero_extract:SI
18847                        (match_dup 0)
18848                        (const_int 8)
18849                        (const_int 8))
18850                      (match_dup 1)))])]
18851   "")
18852
18853 ;; Don't do logical operations with memory inputs.
18854 (define_peephole2
18855   [(match_scratch:SI 2 "r")
18856    (parallel [(set (match_operand:SI 0 "register_operand" "")
18857                    (match_operator:SI 3 "arith_or_logical_operator"
18858                      [(match_dup 0)
18859                       (match_operand:SI 1 "memory_operand" "")]))
18860               (clobber (reg:CC FLAGS_REG))])]
18861   "! optimize_size && ! TARGET_READ_MODIFY"
18862   [(set (match_dup 2) (match_dup 1))
18863    (parallel [(set (match_dup 0)
18864                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18865               (clobber (reg:CC FLAGS_REG))])]
18866   "")
18867
18868 (define_peephole2
18869   [(match_scratch:SI 2 "r")
18870    (parallel [(set (match_operand:SI 0 "register_operand" "")
18871                    (match_operator:SI 3 "arith_or_logical_operator"
18872                      [(match_operand:SI 1 "memory_operand" "")
18873                       (match_dup 0)]))
18874               (clobber (reg:CC FLAGS_REG))])]
18875   "! optimize_size && ! TARGET_READ_MODIFY"
18876   [(set (match_dup 2) (match_dup 1))
18877    (parallel [(set (match_dup 0)
18878                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18879               (clobber (reg:CC FLAGS_REG))])]
18880   "")
18881
18882 ; Don't do logical operations with memory outputs
18883 ;
18884 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18885 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18886 ; the same decoder scheduling characteristics as the original.
18887
18888 (define_peephole2
18889   [(match_scratch:SI 2 "r")
18890    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18891                    (match_operator:SI 3 "arith_or_logical_operator"
18892                      [(match_dup 0)
18893                       (match_operand:SI 1 "nonmemory_operand" "")]))
18894               (clobber (reg:CC FLAGS_REG))])]
18895   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18896   [(set (match_dup 2) (match_dup 0))
18897    (parallel [(set (match_dup 2)
18898                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18899               (clobber (reg:CC FLAGS_REG))])
18900    (set (match_dup 0) (match_dup 2))]
18901   "")
18902
18903 (define_peephole2
18904   [(match_scratch:SI 2 "r")
18905    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18906                    (match_operator:SI 3 "arith_or_logical_operator"
18907                      [(match_operand:SI 1 "nonmemory_operand" "")
18908                       (match_dup 0)]))
18909               (clobber (reg:CC FLAGS_REG))])]
18910   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18911   [(set (match_dup 2) (match_dup 0))
18912    (parallel [(set (match_dup 2)
18913                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18914               (clobber (reg:CC FLAGS_REG))])
18915    (set (match_dup 0) (match_dup 2))]
18916   "")
18917
18918 ;; Attempt to always use XOR for zeroing registers.
18919 (define_peephole2
18920   [(set (match_operand 0 "register_operand" "")
18921         (const_int 0))]
18922   "(GET_MODE (operands[0]) == QImode
18923     || GET_MODE (operands[0]) == HImode
18924     || GET_MODE (operands[0]) == SImode
18925     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18926    && (! TARGET_USE_MOV0 || optimize_size)
18927    && peep2_regno_dead_p (0, FLAGS_REG)"
18928   [(parallel [(set (match_dup 0) (const_int 0))
18929               (clobber (reg:CC FLAGS_REG))])]
18930   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18931                               operands[0]);")
18932
18933 (define_peephole2
18934   [(set (strict_low_part (match_operand 0 "register_operand" ""))
18935         (const_int 0))]
18936   "(GET_MODE (operands[0]) == QImode
18937     || GET_MODE (operands[0]) == HImode)
18938    && (! TARGET_USE_MOV0 || optimize_size)
18939    && peep2_regno_dead_p (0, FLAGS_REG)"
18940   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18941               (clobber (reg:CC FLAGS_REG))])])
18942
18943 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18944 (define_peephole2
18945   [(set (match_operand 0 "register_operand" "")
18946         (const_int -1))]
18947   "(GET_MODE (operands[0]) == HImode
18948     || GET_MODE (operands[0]) == SImode 
18949     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18950    && (optimize_size || TARGET_PENTIUM)
18951    && peep2_regno_dead_p (0, FLAGS_REG)"
18952   [(parallel [(set (match_dup 0) (const_int -1))
18953               (clobber (reg:CC FLAGS_REG))])]
18954   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18955                               operands[0]);")
18956
18957 ;; Attempt to convert simple leas to adds. These can be created by
18958 ;; move expanders.
18959 (define_peephole2
18960   [(set (match_operand:SI 0 "register_operand" "")
18961         (plus:SI (match_dup 0)
18962                  (match_operand:SI 1 "nonmemory_operand" "")))]
18963   "peep2_regno_dead_p (0, FLAGS_REG)"
18964   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18965               (clobber (reg:CC FLAGS_REG))])]
18966   "")
18967
18968 (define_peephole2
18969   [(set (match_operand:SI 0 "register_operand" "")
18970         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18971                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18972   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18973   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18974               (clobber (reg:CC FLAGS_REG))])]
18975   "operands[2] = gen_lowpart (SImode, operands[2]);")
18976
18977 (define_peephole2
18978   [(set (match_operand:DI 0 "register_operand" "")
18979         (plus:DI (match_dup 0)
18980                  (match_operand:DI 1 "x86_64_general_operand" "")))]
18981   "peep2_regno_dead_p (0, FLAGS_REG)"
18982   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18983               (clobber (reg:CC FLAGS_REG))])]
18984   "")
18985
18986 (define_peephole2
18987   [(set (match_operand:SI 0 "register_operand" "")
18988         (mult:SI (match_dup 0)
18989                  (match_operand:SI 1 "const_int_operand" "")))]
18990   "exact_log2 (INTVAL (operands[1])) >= 0
18991    && peep2_regno_dead_p (0, FLAGS_REG)"
18992   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18993               (clobber (reg:CC FLAGS_REG))])]
18994   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18995
18996 (define_peephole2
18997   [(set (match_operand:DI 0 "register_operand" "")
18998         (mult:DI (match_dup 0)
18999                  (match_operand:DI 1 "const_int_operand" "")))]
19000   "exact_log2 (INTVAL (operands[1])) >= 0
19001    && peep2_regno_dead_p (0, FLAGS_REG)"
19002   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19003               (clobber (reg:CC FLAGS_REG))])]
19004   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19005
19006 (define_peephole2
19007   [(set (match_operand:SI 0 "register_operand" "")
19008         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19009                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19010   "exact_log2 (INTVAL (operands[2])) >= 0
19011    && REGNO (operands[0]) == REGNO (operands[1])
19012    && peep2_regno_dead_p (0, FLAGS_REG)"
19013   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19014               (clobber (reg:CC FLAGS_REG))])]
19015   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19016
19017 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19018 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19019 ;; many CPUs it is also faster, since special hardware to avoid esp
19020 ;; dependencies is present.
19021
19022 ;; While some of these conversions may be done using splitters, we use peepholes
19023 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19024
19025 ;; Convert prologue esp subtractions to push.
19026 ;; We need register to push.  In order to keep verify_flow_info happy we have
19027 ;; two choices
19028 ;; - use scratch and clobber it in order to avoid dependencies
19029 ;; - use already live register
19030 ;; We can't use the second way right now, since there is no reliable way how to
19031 ;; verify that given register is live.  First choice will also most likely in
19032 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19033 ;; call clobbered registers are dead.  We may want to use base pointer as an
19034 ;; alternative when no register is available later.
19035
19036 (define_peephole2
19037   [(match_scratch:SI 0 "r")
19038    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19039               (clobber (reg:CC FLAGS_REG))
19040               (clobber (mem:BLK (scratch)))])]
19041   "optimize_size || !TARGET_SUB_ESP_4"
19042   [(clobber (match_dup 0))
19043    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19044               (clobber (mem:BLK (scratch)))])])
19045
19046 (define_peephole2
19047   [(match_scratch:SI 0 "r")
19048    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19049               (clobber (reg:CC FLAGS_REG))
19050               (clobber (mem:BLK (scratch)))])]
19051   "optimize_size || !TARGET_SUB_ESP_8"
19052   [(clobber (match_dup 0))
19053    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19054    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19055               (clobber (mem:BLK (scratch)))])])
19056
19057 ;; Convert esp subtractions to push.
19058 (define_peephole2
19059   [(match_scratch:SI 0 "r")
19060    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19061               (clobber (reg:CC FLAGS_REG))])]
19062   "optimize_size || !TARGET_SUB_ESP_4"
19063   [(clobber (match_dup 0))
19064    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19065
19066 (define_peephole2
19067   [(match_scratch:SI 0 "r")
19068    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19069               (clobber (reg:CC FLAGS_REG))])]
19070   "optimize_size || !TARGET_SUB_ESP_8"
19071   [(clobber (match_dup 0))
19072    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19073    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19074
19075 ;; Convert epilogue deallocator to pop.
19076 (define_peephole2
19077   [(match_scratch:SI 0 "r")
19078    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19079               (clobber (reg:CC FLAGS_REG))
19080               (clobber (mem:BLK (scratch)))])]
19081   "optimize_size || !TARGET_ADD_ESP_4"
19082   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19083               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19084               (clobber (mem:BLK (scratch)))])]
19085   "")
19086
19087 ;; Two pops case is tricky, since pop causes dependency on destination register.
19088 ;; We use two registers if available.
19089 (define_peephole2
19090   [(match_scratch:SI 0 "r")
19091    (match_scratch:SI 1 "r")
19092    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19093               (clobber (reg:CC FLAGS_REG))
19094               (clobber (mem:BLK (scratch)))])]
19095   "optimize_size || !TARGET_ADD_ESP_8"
19096   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19097               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19098               (clobber (mem:BLK (scratch)))])
19099    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19100               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19101   "")
19102
19103 (define_peephole2
19104   [(match_scratch:SI 0 "r")
19105    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19106               (clobber (reg:CC FLAGS_REG))
19107               (clobber (mem:BLK (scratch)))])]
19108   "optimize_size"
19109   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19110               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19111               (clobber (mem:BLK (scratch)))])
19112    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19113               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19114   "")
19115
19116 ;; Convert esp additions to pop.
19117 (define_peephole2
19118   [(match_scratch:SI 0 "r")
19119    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19120               (clobber (reg:CC FLAGS_REG))])]
19121   ""
19122   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19123               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19124   "")
19125
19126 ;; Two pops case is tricky, since pop causes dependency on destination register.
19127 ;; We use two registers if available.
19128 (define_peephole2
19129   [(match_scratch:SI 0 "r")
19130    (match_scratch:SI 1 "r")
19131    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19132               (clobber (reg:CC FLAGS_REG))])]
19133   ""
19134   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19135               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19136    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19137               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19138   "")
19139
19140 (define_peephole2
19141   [(match_scratch:SI 0 "r")
19142    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19143               (clobber (reg:CC FLAGS_REG))])]
19144   "optimize_size"
19145   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19146               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19147    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19148               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19149   "")
19150 \f
19151 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19152 ;; required and register dies.
19153 (define_peephole2
19154   [(set (reg 17)
19155         (compare (match_operand:SI 0 "register_operand" "")
19156                  (match_operand:SI 1 "incdec_operand" "")))]
19157   "ix86_match_ccmode (insn, CCGCmode)
19158    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19159   [(parallel [(set (reg:CCGC FLAGS_REG)
19160                    (compare:CCGC (match_dup 0)
19161                                  (match_dup 1)))
19162               (clobber (match_dup 0))])]
19163   "")
19164
19165 (define_peephole2
19166   [(set (reg 17)
19167         (compare (match_operand:HI 0 "register_operand" "")
19168                  (match_operand:HI 1 "incdec_operand" "")))]
19169   "ix86_match_ccmode (insn, CCGCmode)
19170    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19171   [(parallel [(set (reg:CCGC FLAGS_REG)
19172                    (compare:CCGC (match_dup 0)
19173                                  (match_dup 1)))
19174               (clobber (match_dup 0))])]
19175   "")
19176
19177 (define_peephole2
19178   [(set (reg 17)
19179         (compare (match_operand:QI 0 "register_operand" "")
19180                  (match_operand:QI 1 "incdec_operand" "")))]
19181   "ix86_match_ccmode (insn, CCGCmode)
19182    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19183   [(parallel [(set (reg:CCGC FLAGS_REG)
19184                    (compare:CCGC (match_dup 0)
19185                                  (match_dup 1)))
19186               (clobber (match_dup 0))])]
19187   "")
19188
19189 ;; Convert compares with 128 to shorter add -128
19190 (define_peephole2
19191   [(set (reg 17)
19192         (compare (match_operand:SI 0 "register_operand" "")
19193                  (const_int 128)))]
19194   "ix86_match_ccmode (insn, CCGCmode)
19195    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19196   [(parallel [(set (reg:CCGC FLAGS_REG)
19197                    (compare:CCGC (match_dup 0)
19198                                  (const_int 128)))
19199               (clobber (match_dup 0))])]
19200   "")
19201
19202 (define_peephole2
19203   [(set (reg 17)
19204         (compare (match_operand:HI 0 "register_operand" "")
19205                  (const_int 128)))]
19206   "ix86_match_ccmode (insn, CCGCmode)
19207    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19208   [(parallel [(set (reg:CCGC FLAGS_REG)
19209                    (compare:CCGC (match_dup 0)
19210                                  (const_int 128)))
19211               (clobber (match_dup 0))])]
19212   "")
19213 \f
19214 (define_peephole2
19215   [(match_scratch:DI 0 "r")
19216    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19217               (clobber (reg:CC FLAGS_REG))
19218               (clobber (mem:BLK (scratch)))])]
19219   "optimize_size || !TARGET_SUB_ESP_4"
19220   [(clobber (match_dup 0))
19221    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19222               (clobber (mem:BLK (scratch)))])])
19223
19224 (define_peephole2
19225   [(match_scratch:DI 0 "r")
19226    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19227               (clobber (reg:CC FLAGS_REG))
19228               (clobber (mem:BLK (scratch)))])]
19229   "optimize_size || !TARGET_SUB_ESP_8"
19230   [(clobber (match_dup 0))
19231    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19232    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19233               (clobber (mem:BLK (scratch)))])])
19234
19235 ;; Convert esp subtractions to push.
19236 (define_peephole2
19237   [(match_scratch:DI 0 "r")
19238    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19239               (clobber (reg:CC FLAGS_REG))])]
19240   "optimize_size || !TARGET_SUB_ESP_4"
19241   [(clobber (match_dup 0))
19242    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19243
19244 (define_peephole2
19245   [(match_scratch:DI 0 "r")
19246    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19247               (clobber (reg:CC FLAGS_REG))])]
19248   "optimize_size || !TARGET_SUB_ESP_8"
19249   [(clobber (match_dup 0))
19250    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19251    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19252
19253 ;; Convert epilogue deallocator to pop.
19254 (define_peephole2
19255   [(match_scratch:DI 0 "r")
19256    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19257               (clobber (reg:CC FLAGS_REG))
19258               (clobber (mem:BLK (scratch)))])]
19259   "optimize_size || !TARGET_ADD_ESP_4"
19260   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19261               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19262               (clobber (mem:BLK (scratch)))])]
19263   "")
19264
19265 ;; Two pops case is tricky, since pop causes dependency on destination register.
19266 ;; We use two registers if available.
19267 (define_peephole2
19268   [(match_scratch:DI 0 "r")
19269    (match_scratch:DI 1 "r")
19270    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19271               (clobber (reg:CC FLAGS_REG))
19272               (clobber (mem:BLK (scratch)))])]
19273   "optimize_size || !TARGET_ADD_ESP_8"
19274   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19275               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19276               (clobber (mem:BLK (scratch)))])
19277    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19278               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19279   "")
19280
19281 (define_peephole2
19282   [(match_scratch:DI 0 "r")
19283    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19284               (clobber (reg:CC FLAGS_REG))
19285               (clobber (mem:BLK (scratch)))])]
19286   "optimize_size"
19287   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19288               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19289               (clobber (mem:BLK (scratch)))])
19290    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19291               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19292   "")
19293
19294 ;; Convert esp additions to pop.
19295 (define_peephole2
19296   [(match_scratch:DI 0 "r")
19297    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19298               (clobber (reg:CC FLAGS_REG))])]
19299   ""
19300   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19301               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19302   "")
19303
19304 ;; Two pops case is tricky, since pop causes dependency on destination register.
19305 ;; We use two registers if available.
19306 (define_peephole2
19307   [(match_scratch:DI 0 "r")
19308    (match_scratch:DI 1 "r")
19309    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19310               (clobber (reg:CC FLAGS_REG))])]
19311   ""
19312   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19313               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19314    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19315               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19316   "")
19317
19318 (define_peephole2
19319   [(match_scratch:DI 0 "r")
19320    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19321               (clobber (reg:CC FLAGS_REG))])]
19322   "optimize_size"
19323   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19324               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19325    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19326               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19327   "")
19328 \f
19329 ;; Convert imul by three, five and nine into lea
19330 (define_peephole2
19331   [(parallel
19332     [(set (match_operand:SI 0 "register_operand" "")
19333           (mult:SI (match_operand:SI 1 "register_operand" "")
19334                    (match_operand:SI 2 "const_int_operand" "")))
19335      (clobber (reg:CC FLAGS_REG))])]
19336   "INTVAL (operands[2]) == 3
19337    || INTVAL (operands[2]) == 5
19338    || INTVAL (operands[2]) == 9"
19339   [(set (match_dup 0)
19340         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19341                  (match_dup 1)))]
19342   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19343
19344 (define_peephole2
19345   [(parallel
19346     [(set (match_operand:SI 0 "register_operand" "")
19347           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19348                    (match_operand:SI 2 "const_int_operand" "")))
19349      (clobber (reg:CC FLAGS_REG))])]
19350   "!optimize_size 
19351    && (INTVAL (operands[2]) == 3
19352        || INTVAL (operands[2]) == 5
19353        || INTVAL (operands[2]) == 9)"
19354   [(set (match_dup 0) (match_dup 1))
19355    (set (match_dup 0)
19356         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19357                  (match_dup 0)))]
19358   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19359
19360 (define_peephole2
19361   [(parallel
19362     [(set (match_operand:DI 0 "register_operand" "")
19363           (mult:DI (match_operand:DI 1 "register_operand" "")
19364                    (match_operand:DI 2 "const_int_operand" "")))
19365      (clobber (reg:CC FLAGS_REG))])]
19366   "TARGET_64BIT
19367    && (INTVAL (operands[2]) == 3
19368        || INTVAL (operands[2]) == 5
19369        || INTVAL (operands[2]) == 9)"
19370   [(set (match_dup 0)
19371         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19372                  (match_dup 1)))]
19373   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19374
19375 (define_peephole2
19376   [(parallel
19377     [(set (match_operand:DI 0 "register_operand" "")
19378           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19379                    (match_operand:DI 2 "const_int_operand" "")))
19380      (clobber (reg:CC FLAGS_REG))])]
19381   "TARGET_64BIT
19382    && !optimize_size 
19383    && (INTVAL (operands[2]) == 3
19384        || INTVAL (operands[2]) == 5
19385        || INTVAL (operands[2]) == 9)"
19386   [(set (match_dup 0) (match_dup 1))
19387    (set (match_dup 0)
19388         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19389                  (match_dup 0)))]
19390   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19391
19392 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19393 ;; imul $32bit_imm, reg, reg is direct decoded.
19394 (define_peephole2
19395   [(match_scratch:DI 3 "r")
19396    (parallel [(set (match_operand:DI 0 "register_operand" "")
19397                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19398                             (match_operand:DI 2 "immediate_operand" "")))
19399               (clobber (reg:CC FLAGS_REG))])]
19400   "TARGET_K8 && !optimize_size
19401    && (GET_CODE (operands[2]) != CONST_INT
19402        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19403   [(set (match_dup 3) (match_dup 1))
19404    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19405               (clobber (reg:CC FLAGS_REG))])]
19406 "")
19407
19408 (define_peephole2
19409   [(match_scratch:SI 3 "r")
19410    (parallel [(set (match_operand:SI 0 "register_operand" "")
19411                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19412                             (match_operand:SI 2 "immediate_operand" "")))
19413               (clobber (reg:CC FLAGS_REG))])]
19414   "TARGET_K8 && !optimize_size
19415    && (GET_CODE (operands[2]) != CONST_INT
19416        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19417   [(set (match_dup 3) (match_dup 1))
19418    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19419               (clobber (reg:CC FLAGS_REG))])]
19420 "")
19421
19422 (define_peephole2
19423   [(match_scratch:SI 3 "r")
19424    (parallel [(set (match_operand:DI 0 "register_operand" "")
19425                    (zero_extend:DI
19426                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19427                               (match_operand:SI 2 "immediate_operand" ""))))
19428               (clobber (reg:CC FLAGS_REG))])]
19429   "TARGET_K8 && !optimize_size
19430    && (GET_CODE (operands[2]) != CONST_INT
19431        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19432   [(set (match_dup 3) (match_dup 1))
19433    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19434               (clobber (reg:CC FLAGS_REG))])]
19435 "")
19436
19437 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19438 ;; Convert it into imul reg, reg
19439 ;; It would be better to force assembler to encode instruction using long
19440 ;; immediate, but there is apparently no way to do so.
19441 (define_peephole2
19442   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19443                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19444                             (match_operand:DI 2 "const_int_operand" "")))
19445               (clobber (reg:CC FLAGS_REG))])
19446    (match_scratch:DI 3 "r")]
19447   "TARGET_K8 && !optimize_size
19448    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19449   [(set (match_dup 3) (match_dup 2))
19450    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19451               (clobber (reg:CC FLAGS_REG))])]
19452 {
19453   if (!rtx_equal_p (operands[0], operands[1]))
19454     emit_move_insn (operands[0], operands[1]);
19455 })
19456
19457 (define_peephole2
19458   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19459                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19460                             (match_operand:SI 2 "const_int_operand" "")))
19461               (clobber (reg:CC FLAGS_REG))])
19462    (match_scratch:SI 3 "r")]
19463   "TARGET_K8 && !optimize_size
19464    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19465   [(set (match_dup 3) (match_dup 2))
19466    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19467               (clobber (reg:CC FLAGS_REG))])]
19468 {
19469   if (!rtx_equal_p (operands[0], operands[1]))
19470     emit_move_insn (operands[0], operands[1]);
19471 })
19472
19473 (define_peephole2
19474   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19475                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19476                             (match_operand:HI 2 "immediate_operand" "")))
19477               (clobber (reg:CC FLAGS_REG))])
19478    (match_scratch:HI 3 "r")]
19479   "TARGET_K8 && !optimize_size"
19480   [(set (match_dup 3) (match_dup 2))
19481    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19482               (clobber (reg:CC FLAGS_REG))])]
19483 {
19484   if (!rtx_equal_p (operands[0], operands[1]))
19485     emit_move_insn (operands[0], operands[1]);
19486 })
19487 \f
19488 ;; Call-value patterns last so that the wildcard operand does not
19489 ;; disrupt insn-recog's switch tables.
19490
19491 (define_insn "*call_value_pop_0"
19492   [(set (match_operand 0 "" "")
19493         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19494               (match_operand:SI 2 "" "")))
19495    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19496                             (match_operand:SI 3 "immediate_operand" "")))]
19497   "!TARGET_64BIT"
19498 {
19499   if (SIBLING_CALL_P (insn))
19500     return "jmp\t%P1";
19501   else
19502     return "call\t%P1";
19503 }
19504   [(set_attr "type" "callv")])
19505
19506 (define_insn "*call_value_pop_1"
19507   [(set (match_operand 0 "" "")
19508         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19509               (match_operand:SI 2 "" "")))
19510    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19511                             (match_operand:SI 3 "immediate_operand" "i")))]
19512   "!TARGET_64BIT"
19513 {
19514   if (constant_call_address_operand (operands[1], QImode))
19515     {
19516       if (SIBLING_CALL_P (insn))
19517         return "jmp\t%P1";
19518       else
19519         return "call\t%P1";
19520     }
19521   if (SIBLING_CALL_P (insn))
19522     return "jmp\t%A1";
19523   else
19524     return "call\t%A1";
19525 }
19526   [(set_attr "type" "callv")])
19527
19528 (define_insn "*call_value_0"
19529   [(set (match_operand 0 "" "")
19530         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19531               (match_operand:SI 2 "" "")))]
19532   "!TARGET_64BIT"
19533 {
19534   if (SIBLING_CALL_P (insn))
19535     return "jmp\t%P1";
19536   else
19537     return "call\t%P1";
19538 }
19539   [(set_attr "type" "callv")])
19540
19541 (define_insn "*call_value_0_rex64"
19542   [(set (match_operand 0 "" "")
19543         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19544               (match_operand:DI 2 "const_int_operand" "")))]
19545   "TARGET_64BIT"
19546 {
19547   if (SIBLING_CALL_P (insn))
19548     return "jmp\t%P1";
19549   else
19550     return "call\t%P1";
19551 }
19552   [(set_attr "type" "callv")])
19553
19554 (define_insn "*call_value_1"
19555   [(set (match_operand 0 "" "")
19556         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19557               (match_operand:SI 2 "" "")))]
19558   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19559 {
19560   if (constant_call_address_operand (operands[1], QImode))
19561     return "call\t%P1";
19562   return "call\t%*%1";
19563 }
19564   [(set_attr "type" "callv")])
19565
19566 (define_insn "*sibcall_value_1"
19567   [(set (match_operand 0 "" "")
19568         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19569               (match_operand:SI 2 "" "")))]
19570   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19571 {
19572   if (constant_call_address_operand (operands[1], QImode))
19573     return "jmp\t%P1";
19574   return "jmp\t%*%1";
19575 }
19576   [(set_attr "type" "callv")])
19577
19578 (define_insn "*call_value_1_rex64"
19579   [(set (match_operand 0 "" "")
19580         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19581               (match_operand:DI 2 "" "")))]
19582   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19583 {
19584   if (constant_call_address_operand (operands[1], QImode))
19585     return "call\t%P1";
19586   return "call\t%A1";
19587 }
19588   [(set_attr "type" "callv")])
19589
19590 (define_insn "*sibcall_value_1_rex64"
19591   [(set (match_operand 0 "" "")
19592         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19593               (match_operand:DI 2 "" "")))]
19594   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19595   "jmp\t%P1"
19596   [(set_attr "type" "callv")])
19597
19598 (define_insn "*sibcall_value_1_rex64_v"
19599   [(set (match_operand 0 "" "")
19600         (call (mem:QI (reg:DI 40))
19601               (match_operand:DI 1 "" "")))]
19602   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19603   "jmp\t*%%r11"
19604   [(set_attr "type" "callv")])
19605 \f
19606 (define_insn "trap"
19607   [(trap_if (const_int 1) (const_int 5))]
19608   ""
19609   "int\t$5")
19610
19611 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19612 ;;; for the sake of bounds checking.  By emitting bounds checks as
19613 ;;; conditional traps rather than as conditional jumps around
19614 ;;; unconditional traps we avoid introducing spurious basic-block
19615 ;;; boundaries and facilitate elimination of redundant checks.  In
19616 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19617 ;;; interrupt 5.
19618 ;;; 
19619 ;;; FIXME: Static branch prediction rules for ix86 are such that
19620 ;;; forward conditional branches predict as untaken.  As implemented
19621 ;;; below, pseudo conditional traps violate that rule.  We should use
19622 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19623 ;;; section loaded at the end of the text segment and branch forward
19624 ;;; there on bounds-failure, and then jump back immediately (in case
19625 ;;; the system chooses to ignore bounds violations, or to report
19626 ;;; violations and continue execution).
19627
19628 (define_expand "conditional_trap"
19629   [(trap_if (match_operator 0 "comparison_operator"
19630              [(match_dup 2) (const_int 0)])
19631             (match_operand 1 "const_int_operand" ""))]
19632   ""
19633 {
19634   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19635                               ix86_expand_compare (GET_CODE (operands[0]),
19636                                                    NULL, NULL),
19637                               operands[1]));
19638   DONE;
19639 })
19640
19641 (define_insn "*conditional_trap_1"
19642   [(trap_if (match_operator 0 "comparison_operator"
19643              [(reg 17) (const_int 0)])
19644             (match_operand 1 "const_int_operand" ""))]
19645   ""
19646 {
19647   operands[2] = gen_label_rtx ();
19648   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19649   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19650                              CODE_LABEL_NUMBER (operands[2]));
19651   RET;
19652 })
19653
19654         ;; Pentium III SIMD instructions.
19655
19656 ;; Moves for SSE/MMX regs.
19657
19658 (define_insn "movv4sf_internal"
19659   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19660         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19661   "TARGET_SSE"
19662   "@
19663     xorps\t%0, %0
19664     movaps\t{%1, %0|%0, %1}
19665     movaps\t{%1, %0|%0, %1}"
19666   [(set_attr "type" "ssemov")
19667    (set_attr "mode" "V4SF")])
19668
19669 (define_split
19670   [(set (match_operand:V4SF 0 "register_operand" "")
19671         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19672   "TARGET_SSE"
19673   [(set (match_dup 0)
19674         (vec_merge:V4SF
19675          (vec_duplicate:V4SF (match_dup 1))
19676          (match_dup 2)
19677          (const_int 1)))]
19678 {
19679   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19680   operands[2] = CONST0_RTX (V4SFmode);
19681 })
19682
19683 (define_insn "movv4si_internal"
19684   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
19685         (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
19686   "TARGET_SSE"
19687 {
19688   switch (which_alternative)
19689     {
19690     case 0:
19691       if (get_attr_mode (insn) == MODE_V4SF)
19692         return "xorps\t%0, %0";
19693       else
19694         return "pxor\t%0, %0";
19695     case 1:
19696     case 2:
19697       if (get_attr_mode (insn) == MODE_V4SF)
19698         return "movaps\t{%1, %0|%0, %1}";
19699       else
19700         return "movdqa\t{%1, %0|%0, %1}";
19701     default:
19702       abort ();
19703     }
19704 }
19705   [(set_attr "type" "ssemov")
19706    (set (attr "mode")
19707         (cond [(eq_attr "alternative" "0,1")
19708                  (if_then_else
19709                    (ne (symbol_ref "optimize_size")
19710                        (const_int 0))
19711                    (const_string "V4SF")
19712                    (const_string "TI"))
19713                (eq_attr "alternative" "2")
19714                  (if_then_else
19715                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19716                             (const_int 0))
19717                         (ne (symbol_ref "optimize_size")
19718                             (const_int 0)))
19719                    (const_string "V4SF")
19720                    (const_string "TI"))]
19721                (const_string "TI")))])
19722
19723 (define_insn "movv2di_internal"
19724   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
19725         (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
19726   "TARGET_SSE"
19727 {
19728   switch (which_alternative)
19729     {
19730     case 0:
19731       if (get_attr_mode (insn) == MODE_V4SF)
19732         return "xorps\t%0, %0";
19733       else
19734         return "pxor\t%0, %0";
19735     case 1:
19736     case 2:
19737       if (get_attr_mode (insn) == MODE_V4SF)
19738         return "movaps\t{%1, %0|%0, %1}";
19739       else
19740         return "movdqa\t{%1, %0|%0, %1}";
19741     default:
19742       abort ();
19743     }
19744 }
19745   [(set_attr "type" "ssemov")
19746    (set (attr "mode")
19747         (cond [(eq_attr "alternative" "0,1")
19748                  (if_then_else
19749                    (ne (symbol_ref "optimize_size")
19750                        (const_int 0))
19751                    (const_string "V4SF")
19752                    (const_string "TI"))
19753                (eq_attr "alternative" "2")
19754                  (if_then_else
19755                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19756                             (const_int 0))
19757                         (ne (symbol_ref "optimize_size")
19758                             (const_int 0)))
19759                    (const_string "V4SF")
19760                    (const_string "TI"))]
19761                (const_string "TI")))])
19762
19763 (define_split
19764   [(set (match_operand:V2DF 0 "register_operand" "")
19765         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19766   "TARGET_SSE2"
19767   [(set (match_dup 0)
19768         (vec_merge:V2DF
19769          (vec_duplicate:V2DF (match_dup 1))
19770          (match_dup 2)
19771          (const_int 1)))]
19772 {
19773   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19774   operands[2] = CONST0_RTX (V2DFmode);
19775 })
19776
19777 (define_insn "movv8qi_internal"
19778   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19779         (match_operand:V8QI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19780   "TARGET_MMX
19781    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19782   "@
19783     pxor\t%0, %0
19784     movq\t{%1, %0|%0, %1}
19785     movq\t{%1, %0|%0, %1}
19786     movdq2q\t{%1, %0|%0, %1}
19787     movq2dq\t{%1, %0|%0, %1}
19788     movq\t{%1, %0|%0, %1}
19789     movq\t{%1, %0|%0, %1}"
19790   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19791    (set_attr "mode" "DI")])
19792
19793 (define_insn "movv4hi_internal"
19794   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19795         (match_operand:V4HI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19796   "TARGET_MMX
19797    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19798   "@
19799     pxor\t%0, %0
19800     movq\t{%1, %0|%0, %1}
19801     movq\t{%1, %0|%0, %1}
19802     movdq2q\t{%1, %0|%0, %1}
19803     movq2dq\t{%1, %0|%0, %1}
19804     movq\t{%1, %0|%0, %1}
19805     movq\t{%1, %0|%0, %1}"
19806   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19807    (set_attr "mode" "DI")])
19808
19809 (define_insn "*movv2si_internal"
19810   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19811         (match_operand:V2SI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19812   "TARGET_MMX
19813    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19814   "@
19815     pxor\t%0, %0
19816     movq\t{%1, %0|%0, %1}
19817     movq\t{%1, %0|%0, %1}
19818     movdq2q\t{%1, %0|%0, %1}
19819     movq2dq\t{%1, %0|%0, %1}
19820     movq\t{%1, %0|%0, %1}
19821     movq\t{%1, %0|%0, %1}"
19822   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19823    (set_attr "mode" "DI")])
19824
19825 (define_insn "movv2sf_internal"
19826   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*x,?m")
19827         (match_operand:V2SF 1 "vector_move_operand" "C,ym,y,*Y,y,*xm,*x"))]
19828   "TARGET_3DNOW
19829    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19830   "@
19831     pxor\t%0, %0
19832     movq\t{%1, %0|%0, %1}
19833     movq\t{%1, %0|%0, %1}
19834     movdq2q\t{%1, %0|%0, %1}
19835     movq2dq\t{%1, %0|%0, %1}
19836     movlps\t{%1, %0|%0, %1}
19837     movlps\t{%1, %0|%0, %1}"
19838   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19839    (set_attr "mode" "DI,DI,DI,DI,DI,V2SF,V2SF")])
19840
19841 (define_expand "movti"
19842   [(set (match_operand:TI 0 "nonimmediate_operand" "")
19843         (match_operand:TI 1 "nonimmediate_operand" ""))]
19844   "TARGET_SSE || TARGET_64BIT"
19845 {
19846   if (TARGET_64BIT)
19847     ix86_expand_move (TImode, operands);
19848   else
19849     ix86_expand_vector_move (TImode, operands);
19850   DONE;
19851 })
19852
19853 (define_expand "movtf"
19854   [(set (match_operand:TF 0 "nonimmediate_operand" "")
19855         (match_operand:TF 1 "nonimmediate_operand" ""))]
19856   "TARGET_64BIT"
19857 {
19858   if (TARGET_64BIT)
19859     ix86_expand_move (TFmode, operands);
19860   else
19861     ix86_expand_vector_move (TFmode, operands);
19862   DONE;
19863 })
19864
19865 (define_insn "movv2df_internal"
19866   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19867         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19868   "TARGET_SSE2
19869    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19870 {
19871   switch (which_alternative)
19872     {
19873     case 0:
19874       if (get_attr_mode (insn) == MODE_V4SF)
19875         return "xorps\t%0, %0";
19876       else
19877         return "xorpd\t%0, %0";
19878     case 1:
19879     case 2:
19880       if (get_attr_mode (insn) == MODE_V4SF)
19881         return "movaps\t{%1, %0|%0, %1}";
19882       else
19883         return "movapd\t{%1, %0|%0, %1}";
19884     default:
19885       abort ();
19886     }
19887 }
19888   [(set_attr "type" "ssemov")
19889    (set (attr "mode")
19890         (cond [(eq_attr "alternative" "0,1")
19891                  (if_then_else
19892                    (ne (symbol_ref "optimize_size")
19893                        (const_int 0))
19894                    (const_string "V4SF")
19895                    (const_string "V2DF"))
19896                (eq_attr "alternative" "2")
19897                  (if_then_else
19898                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19899                             (const_int 0))
19900                         (ne (symbol_ref "optimize_size")
19901                             (const_int 0)))
19902                    (const_string "V4SF")
19903                    (const_string "V2DF"))]
19904                (const_string "V2DF")))])
19905
19906 (define_insn "movv8hi_internal"
19907   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
19908         (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
19909   "TARGET_SSE2
19910    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19911 {
19912   switch (which_alternative)
19913     {
19914     case 0:
19915       if (get_attr_mode (insn) == MODE_V4SF)
19916         return "xorps\t%0, %0";
19917       else
19918         return "pxor\t%0, %0";
19919     case 1:
19920     case 2:
19921       if (get_attr_mode (insn) == MODE_V4SF)
19922         return "movaps\t{%1, %0|%0, %1}";
19923       else
19924         return "movdqa\t{%1, %0|%0, %1}";
19925     default:
19926       abort ();
19927     }
19928 }
19929   [(set_attr "type" "ssemov")
19930    (set (attr "mode")
19931         (cond [(eq_attr "alternative" "0,1")
19932                  (if_then_else
19933                    (ne (symbol_ref "optimize_size")
19934                        (const_int 0))
19935                    (const_string "V4SF")
19936                    (const_string "TI"))
19937                (eq_attr "alternative" "2")
19938                  (if_then_else
19939                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19940                             (const_int 0))
19941                         (ne (symbol_ref "optimize_size")
19942                             (const_int 0)))
19943                    (const_string "V4SF")
19944                    (const_string "TI"))]
19945                (const_string "TI")))])
19946
19947 (define_insn "movv16qi_internal"
19948   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
19949         (match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
19950   "TARGET_SSE2
19951    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19952 {
19953   switch (which_alternative)
19954     {
19955     case 0:
19956       if (get_attr_mode (insn) == MODE_V4SF)
19957         return "xorps\t%0, %0";
19958       else
19959         return "pxor\t%0, %0";
19960     case 1:
19961     case 2:
19962       if (get_attr_mode (insn) == MODE_V4SF)
19963         return "movaps\t{%1, %0|%0, %1}";
19964       else
19965         return "movdqa\t{%1, %0|%0, %1}";
19966     default:
19967       abort ();
19968     }
19969 }
19970   [(set_attr "type" "ssemov")
19971    (set (attr "mode")
19972         (cond [(eq_attr "alternative" "0,1")
19973                  (if_then_else
19974                    (ne (symbol_ref "optimize_size")
19975                        (const_int 0))
19976                    (const_string "V4SF")
19977                    (const_string "TI"))
19978                (eq_attr "alternative" "2")
19979                  (if_then_else
19980                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19981                             (const_int 0))
19982                         (ne (symbol_ref "optimize_size")
19983                             (const_int 0)))
19984                    (const_string "V4SF")
19985                    (const_string "TI"))]
19986                (const_string "TI")))])
19987
19988 (define_expand "movv2df"
19989   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19990         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19991   "TARGET_SSE2"
19992 {
19993   ix86_expand_vector_move (V2DFmode, operands);
19994   DONE;
19995 })
19996
19997 (define_expand "movv8hi"
19998   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
19999         (match_operand:V8HI 1 "nonimmediate_operand" ""))]
20000   "TARGET_SSE2"
20001 {
20002   ix86_expand_vector_move (V8HImode, operands);
20003   DONE;
20004 })
20005
20006 (define_expand "movv16qi"
20007   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
20008         (match_operand:V16QI 1 "nonimmediate_operand" ""))]
20009   "TARGET_SSE2"
20010 {
20011   ix86_expand_vector_move (V16QImode, operands);
20012   DONE;
20013 })
20014
20015 (define_expand "movv4sf"
20016   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20017         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
20018   "TARGET_SSE"
20019 {
20020   ix86_expand_vector_move (V4SFmode, operands);
20021   DONE;
20022 })
20023
20024 (define_expand "movv4si"
20025   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
20026         (match_operand:V4SI 1 "nonimmediate_operand" ""))]
20027   "TARGET_SSE"
20028 {
20029   ix86_expand_vector_move (V4SImode, operands);
20030   DONE;
20031 })
20032
20033 (define_expand "movv2di"
20034   [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
20035         (match_operand:V2DI 1 "nonimmediate_operand" ""))]
20036   "TARGET_SSE"
20037 {
20038   ix86_expand_vector_move (V2DImode, operands);
20039   DONE;
20040 })
20041
20042 (define_expand "movv2si"
20043   [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
20044         (match_operand:V2SI 1 "nonimmediate_operand" ""))]
20045   "TARGET_MMX"
20046 {
20047   ix86_expand_vector_move (V2SImode, operands);
20048   DONE;
20049 })
20050
20051 (define_expand "movv4hi"
20052   [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
20053         (match_operand:V4HI 1 "nonimmediate_operand" ""))]
20054   "TARGET_MMX"
20055 {
20056   ix86_expand_vector_move (V4HImode, operands);
20057   DONE;
20058 })
20059
20060 (define_expand "movv8qi"
20061   [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
20062         (match_operand:V8QI 1 "nonimmediate_operand" ""))]
20063   "TARGET_MMX"
20064 {
20065   ix86_expand_vector_move (V8QImode, operands);
20066   DONE;
20067 })
20068
20069 (define_expand "movv2sf"
20070   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
20071         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
20072    "TARGET_3DNOW"
20073 {
20074   ix86_expand_vector_move (V2SFmode, operands);
20075   DONE;
20076 })
20077
20078 (define_insn "*pushti"
20079   [(set (match_operand:TI 0 "push_operand" "=<")
20080         (match_operand:TI 1 "register_operand" "x"))]
20081   "TARGET_SSE"
20082   "#")
20083
20084 (define_insn "*pushv2df"
20085   [(set (match_operand:V2DF 0 "push_operand" "=<")
20086         (match_operand:V2DF 1 "register_operand" "x"))]
20087   "TARGET_SSE"
20088   "#")
20089
20090 (define_insn "*pushv2di"
20091   [(set (match_operand:V2DI 0 "push_operand" "=<")
20092         (match_operand:V2DI 1 "register_operand" "x"))]
20093   "TARGET_SSE2"
20094   "#")
20095
20096 (define_insn "*pushv8hi"
20097   [(set (match_operand:V8HI 0 "push_operand" "=<")
20098         (match_operand:V8HI 1 "register_operand" "x"))]
20099   "TARGET_SSE2"
20100   "#")
20101
20102 (define_insn "*pushv16qi"
20103   [(set (match_operand:V16QI 0 "push_operand" "=<")
20104         (match_operand:V16QI 1 "register_operand" "x"))]
20105   "TARGET_SSE2"
20106   "#")
20107
20108 (define_insn "*pushv4sf"
20109   [(set (match_operand:V4SF 0 "push_operand" "=<")
20110         (match_operand:V4SF 1 "register_operand" "x"))]
20111   "TARGET_SSE"
20112   "#")
20113
20114 (define_insn "*pushv4si"
20115   [(set (match_operand:V4SI 0 "push_operand" "=<")
20116         (match_operand:V4SI 1 "register_operand" "x"))]
20117   "TARGET_SSE2"
20118   "#")
20119
20120 (define_insn "*pushv2si"
20121   [(set (match_operand:V2SI 0 "push_operand" "=<")
20122         (match_operand:V2SI 1 "register_operand" "y"))]
20123   "TARGET_MMX"
20124   "#")
20125
20126 (define_insn "*pushv4hi"
20127   [(set (match_operand:V4HI 0 "push_operand" "=<")
20128         (match_operand:V4HI 1 "register_operand" "y"))]
20129   "TARGET_MMX"
20130   "#")
20131
20132 (define_insn "*pushv8qi"
20133   [(set (match_operand:V8QI 0 "push_operand" "=<")
20134         (match_operand:V8QI 1 "register_operand" "y"))]
20135   "TARGET_MMX"
20136   "#")
20137
20138 (define_insn "*pushv2sf"
20139   [(set (match_operand:V2SF 0 "push_operand" "=<")
20140         (match_operand:V2SF 1 "register_operand" "y"))]
20141   "TARGET_3DNOW"
20142   "#")
20143
20144 (define_split
20145   [(set (match_operand 0 "push_operand" "")
20146         (match_operand 1 "register_operand" ""))]
20147   "!TARGET_64BIT && reload_completed
20148    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20149   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20150    (set (match_dup 2) (match_dup 1))]
20151   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20152                                  stack_pointer_rtx);
20153    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20154
20155 (define_split
20156   [(set (match_operand 0 "push_operand" "")
20157         (match_operand 1 "register_operand" ""))]
20158   "TARGET_64BIT && reload_completed
20159    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20160   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20161    (set (match_dup 2) (match_dup 1))]
20162   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20163                                  stack_pointer_rtx);
20164    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20165
20166
20167 (define_insn "movti_internal"
20168   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
20169         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
20170   "TARGET_SSE && !TARGET_64BIT
20171    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20172 {
20173   switch (which_alternative)
20174     {
20175     case 0:
20176       if (get_attr_mode (insn) == MODE_V4SF)
20177         return "xorps\t%0, %0";
20178       else
20179         return "pxor\t%0, %0";
20180     case 1:
20181     case 2:
20182       if (get_attr_mode (insn) == MODE_V4SF)
20183         return "movaps\t{%1, %0|%0, %1}";
20184       else
20185         return "movdqa\t{%1, %0|%0, %1}";
20186     default:
20187       abort ();
20188     }
20189 }
20190   [(set_attr "type" "ssemov,ssemov,ssemov")
20191    (set (attr "mode")
20192         (cond [(eq_attr "alternative" "0,1")
20193                  (if_then_else
20194                    (ne (symbol_ref "optimize_size")
20195                        (const_int 0))
20196                    (const_string "V4SF")
20197                    (const_string "TI"))
20198                (eq_attr "alternative" "2")
20199                  (if_then_else
20200                    (ne (symbol_ref "optimize_size")
20201                        (const_int 0))
20202                    (const_string "V4SF")
20203                    (const_string "TI"))]
20204                (const_string "TI")))])
20205
20206 (define_insn "*movti_rex64"
20207   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
20208         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
20209   "TARGET_64BIT
20210    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20211 {
20212   switch (which_alternative)
20213     {
20214     case 0:
20215     case 1:
20216       return "#";
20217     case 2:
20218       if (get_attr_mode (insn) == MODE_V4SF)
20219         return "xorps\t%0, %0";
20220       else
20221         return "pxor\t%0, %0";
20222     case 3:
20223     case 4:
20224       if (get_attr_mode (insn) == MODE_V4SF)
20225         return "movaps\t{%1, %0|%0, %1}";
20226       else
20227         return "movdqa\t{%1, %0|%0, %1}";
20228     default:
20229       abort ();
20230     }
20231 }
20232   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20233    (set (attr "mode")
20234         (cond [(eq_attr "alternative" "2,3")
20235                  (if_then_else
20236                    (ne (symbol_ref "optimize_size")
20237                        (const_int 0))
20238                    (const_string "V4SF")
20239                    (const_string "TI"))
20240                (eq_attr "alternative" "4")
20241                  (if_then_else
20242                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20243                             (const_int 0))
20244                         (ne (symbol_ref "optimize_size")
20245                             (const_int 0)))
20246                    (const_string "V4SF")
20247                    (const_string "TI"))]
20248                (const_string "DI")))])
20249
20250 (define_insn "*movtf_rex64"
20251   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20252         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20253   "TARGET_64BIT
20254    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20255 {
20256   switch (which_alternative)
20257     {
20258     case 0:
20259     case 1:
20260       return "#";
20261     case 2:
20262       if (get_attr_mode (insn) == MODE_V4SF)
20263         return "xorps\t%0, %0";
20264       else
20265         return "pxor\t%0, %0";
20266     case 3:
20267     case 4:
20268       if (get_attr_mode (insn) == MODE_V4SF)
20269         return "movaps\t{%1, %0|%0, %1}";
20270       else
20271         return "movdqa\t{%1, %0|%0, %1}";
20272     default:
20273       abort ();
20274     }
20275 }
20276   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20277    (set (attr "mode")
20278         (cond [(eq_attr "alternative" "2,3")
20279                  (if_then_else
20280                    (ne (symbol_ref "optimize_size")
20281                        (const_int 0))
20282                    (const_string "V4SF")
20283                    (const_string "TI"))
20284                (eq_attr "alternative" "4")
20285                  (if_then_else
20286                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20287                             (const_int 0))
20288                         (ne (symbol_ref "optimize_size")
20289                             (const_int 0)))
20290                    (const_string "V4SF")
20291                    (const_string "TI"))]
20292                (const_string "DI")))])
20293
20294 (define_split
20295   [(set (match_operand:TI 0 "nonimmediate_operand" "")
20296         (match_operand:TI 1 "general_operand" ""))]
20297   "reload_completed && !SSE_REG_P (operands[0])
20298    && !SSE_REG_P (operands[1])"
20299   [(const_int 0)]
20300   "ix86_split_long_move (operands); DONE;")
20301
20302 (define_split
20303   [(set (match_operand:TF 0 "nonimmediate_operand" "")
20304         (match_operand:TF 1 "general_operand" ""))]
20305   "reload_completed && !SSE_REG_P (operands[0])
20306    && !SSE_REG_P (operands[1])"
20307   [(const_int 0)]
20308   "ix86_split_long_move (operands); DONE;")
20309
20310 ;; These two patterns are useful for specifying exactly whether to use
20311 ;; movaps or movups
20312 (define_expand "sse_movaps"
20313   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20314         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20315                      UNSPEC_MOVA))]
20316   "TARGET_SSE"
20317 {
20318   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20319     {
20320       rtx tmp = gen_reg_rtx (V4SFmode);
20321       emit_insn (gen_sse_movaps (tmp, operands[1]));
20322       emit_move_insn (operands[0], tmp);
20323       DONE;
20324     }
20325 })
20326
20327 (define_insn "*sse_movaps_1"
20328   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20329         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20330                      UNSPEC_MOVA))]
20331   "TARGET_SSE
20332    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20333   "movaps\t{%1, %0|%0, %1}"
20334   [(set_attr "type" "ssemov,ssemov")
20335    (set_attr "mode" "V4SF")])
20336
20337 (define_expand "sse_movups"
20338   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20339         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20340                      UNSPEC_MOVU))]
20341   "TARGET_SSE"
20342 {
20343   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20344     {
20345       rtx tmp = gen_reg_rtx (V4SFmode);
20346       emit_insn (gen_sse_movups (tmp, operands[1]));
20347       emit_move_insn (operands[0], tmp);
20348       DONE;
20349     }
20350 })
20351
20352 (define_insn "*sse_movups_1"
20353   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20354         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20355                      UNSPEC_MOVU))]
20356   "TARGET_SSE
20357    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20358   "movups\t{%1, %0|%0, %1}"
20359   [(set_attr "type" "ssecvt,ssecvt")
20360    (set_attr "mode" "V4SF")])
20361
20362 ;; SSE Strange Moves.
20363
20364 (define_insn "sse_movmskps"
20365   [(set (match_operand:SI 0 "register_operand" "=r")
20366         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20367                    UNSPEC_MOVMSK))]
20368   "TARGET_SSE"
20369   "movmskps\t{%1, %0|%0, %1}"
20370   [(set_attr "type" "ssecvt")
20371    (set_attr "mode" "V4SF")])
20372
20373 (define_insn "mmx_pmovmskb"
20374   [(set (match_operand:SI 0 "register_operand" "=r")
20375         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20376                    UNSPEC_MOVMSK))]
20377   "TARGET_SSE || TARGET_3DNOW_A"
20378   "pmovmskb\t{%1, %0|%0, %1}"
20379   [(set_attr "type" "ssecvt")
20380    (set_attr "mode" "V4SF")])
20381
20382
20383 (define_insn "mmx_maskmovq"
20384   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20385         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20386                       (match_operand:V8QI 2 "register_operand" "y")]
20387                      UNSPEC_MASKMOV))]
20388   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20389   ;; @@@ check ordering of operands in intel/nonintel syntax
20390   "maskmovq\t{%2, %1|%1, %2}"
20391   [(set_attr "type" "mmxcvt")
20392    (set_attr "mode" "DI")])
20393
20394 (define_insn "mmx_maskmovq_rex"
20395   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20396         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20397                       (match_operand:V8QI 2 "register_operand" "y")]
20398                      UNSPEC_MASKMOV))]
20399   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20400   ;; @@@ check ordering of operands in intel/nonintel syntax
20401   "maskmovq\t{%2, %1|%1, %2}"
20402   [(set_attr "type" "mmxcvt")
20403    (set_attr "mode" "DI")])
20404
20405 (define_insn "sse_movntv4sf"
20406   [(set (match_operand:V4SF 0 "memory_operand" "=m")
20407         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20408                      UNSPEC_MOVNT))]
20409   "TARGET_SSE"
20410   "movntps\t{%1, %0|%0, %1}"
20411   [(set_attr "type" "ssemov")
20412    (set_attr "mode" "V4SF")])
20413
20414 (define_insn "sse_movntdi"
20415   [(set (match_operand:DI 0 "memory_operand" "=m")
20416         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20417                    UNSPEC_MOVNT))]
20418   "TARGET_SSE || TARGET_3DNOW_A"
20419   "movntq\t{%1, %0|%0, %1}"
20420   [(set_attr "type" "mmxmov")
20421    (set_attr "mode" "DI")])
20422
20423 (define_insn "sse_movhlps"
20424   [(set (match_operand:V4SF 0 "register_operand" "=x")
20425         (vec_merge:V4SF
20426          (match_operand:V4SF 1 "register_operand" "0")
20427          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20428                           (parallel [(const_int 2)
20429                                      (const_int 3)
20430                                      (const_int 0)
20431                                      (const_int 1)]))
20432          (const_int 3)))]
20433   "TARGET_SSE"
20434   "movhlps\t{%2, %0|%0, %2}"
20435   [(set_attr "type" "ssecvt")
20436    (set_attr "mode" "V4SF")])
20437
20438 (define_insn "sse_movlhps"
20439   [(set (match_operand:V4SF 0 "register_operand" "=x")
20440         (vec_merge:V4SF
20441          (match_operand:V4SF 1 "register_operand" "0")
20442          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20443                           (parallel [(const_int 2)
20444                                      (const_int 3)
20445                                      (const_int 0)
20446                                      (const_int 1)]))
20447          (const_int 12)))]
20448   "TARGET_SSE"
20449   "movlhps\t{%2, %0|%0, %2}"
20450   [(set_attr "type" "ssecvt")
20451    (set_attr "mode" "V4SF")])
20452
20453 (define_insn "sse_movhps"
20454   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20455         (vec_merge:V4SF
20456          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20457          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20458          (const_int 12)))]
20459   "TARGET_SSE
20460    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20461   "movhps\t{%2, %0|%0, %2}"
20462   [(set_attr "type" "ssecvt")
20463    (set_attr "mode" "V4SF")])
20464
20465 (define_insn "sse_movlps"
20466   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20467         (vec_merge:V4SF
20468          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20469          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20470          (const_int 3)))]
20471   "TARGET_SSE
20472    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20473   "movlps\t{%2, %0|%0, %2}"
20474   [(set_attr "type" "ssecvt")
20475    (set_attr "mode" "V4SF")])
20476
20477 (define_expand "sse_loadss"
20478   [(match_operand:V4SF 0 "register_operand" "")
20479    (match_operand:SF 1 "memory_operand" "")]
20480   "TARGET_SSE"
20481 {
20482   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20483                                CONST0_RTX (V4SFmode)));
20484   DONE;
20485 })
20486
20487 (define_insn "sse_loadss_1"
20488   [(set (match_operand:V4SF 0 "register_operand" "=x")
20489         (vec_merge:V4SF
20490          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20491          (match_operand:V4SF 2 "const0_operand" "X")
20492          (const_int 1)))]
20493   "TARGET_SSE"
20494   "movss\t{%1, %0|%0, %1}"
20495   [(set_attr "type" "ssemov")
20496    (set_attr "mode" "SF")])
20497
20498 (define_insn "sse_movss"
20499   [(set (match_operand:V4SF 0 "register_operand" "=x")
20500         (vec_merge:V4SF
20501          (match_operand:V4SF 1 "register_operand" "0")
20502          (match_operand:V4SF 2 "register_operand" "x")
20503          (const_int 1)))]
20504   "TARGET_SSE"
20505   "movss\t{%2, %0|%0, %2}"
20506   [(set_attr "type" "ssemov")
20507    (set_attr "mode" "SF")])
20508
20509 (define_insn "sse_storess"
20510   [(set (match_operand:SF 0 "memory_operand" "=m")
20511         (vec_select:SF
20512          (match_operand:V4SF 1 "register_operand" "x")
20513          (parallel [(const_int 0)])))]
20514   "TARGET_SSE"
20515   "movss\t{%1, %0|%0, %1}"
20516   [(set_attr "type" "ssemov")
20517    (set_attr "mode" "SF")])
20518
20519 (define_insn "sse_shufps"
20520   [(set (match_operand:V4SF 0 "register_operand" "=x")
20521         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20522                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20523                       (match_operand:SI 3 "immediate_operand" "i")]
20524                      UNSPEC_SHUFFLE))]
20525   "TARGET_SSE"
20526   ;; @@@ check operand order for intel/nonintel syntax
20527   "shufps\t{%3, %2, %0|%0, %2, %3}"
20528   [(set_attr "type" "ssecvt")
20529    (set_attr "mode" "V4SF")])
20530
20531
20532 ;; SSE arithmetic
20533
20534 (define_insn "addv4sf3"
20535   [(set (match_operand:V4SF 0 "register_operand" "=x")
20536         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20537                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20538   "TARGET_SSE"
20539   "addps\t{%2, %0|%0, %2}"
20540   [(set_attr "type" "sseadd")
20541    (set_attr "mode" "V4SF")])
20542
20543 (define_insn "vmaddv4sf3"
20544   [(set (match_operand:V4SF 0 "register_operand" "=x")
20545         (vec_merge:V4SF
20546          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20547                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20548          (match_dup 1)
20549          (const_int 1)))]
20550   "TARGET_SSE"
20551   "addss\t{%2, %0|%0, %2}"
20552   [(set_attr "type" "sseadd")
20553    (set_attr "mode" "SF")])
20554
20555 (define_insn "subv4sf3"
20556   [(set (match_operand:V4SF 0 "register_operand" "=x")
20557         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20558                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20559   "TARGET_SSE"
20560   "subps\t{%2, %0|%0, %2}"
20561   [(set_attr "type" "sseadd")
20562    (set_attr "mode" "V4SF")])
20563
20564 (define_insn "vmsubv4sf3"
20565   [(set (match_operand:V4SF 0 "register_operand" "=x")
20566         (vec_merge:V4SF
20567          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20568                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20569          (match_dup 1)
20570          (const_int 1)))]
20571   "TARGET_SSE"
20572   "subss\t{%2, %0|%0, %2}"
20573   [(set_attr "type" "sseadd")
20574    (set_attr "mode" "SF")])
20575
20576 ;; ??? Should probably be done by generic code instead.
20577 (define_expand "negv4sf2"
20578   [(set (match_operand:V4SF 0 "register_operand" "")
20579         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20580                   (match_dup 2)))]
20581   "TARGET_SSE"
20582 {
20583   rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20584   rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20585   operands[2] = force_reg (V4SFmode, vm0);
20586 })
20587
20588 (define_insn "mulv4sf3"
20589   [(set (match_operand:V4SF 0 "register_operand" "=x")
20590         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20591                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20592   "TARGET_SSE"
20593   "mulps\t{%2, %0|%0, %2}"
20594   [(set_attr "type" "ssemul")
20595    (set_attr "mode" "V4SF")])
20596
20597 (define_insn "vmmulv4sf3"
20598   [(set (match_operand:V4SF 0 "register_operand" "=x")
20599         (vec_merge:V4SF
20600          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20601                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20602          (match_dup 1)
20603          (const_int 1)))]
20604   "TARGET_SSE"
20605   "mulss\t{%2, %0|%0, %2}"
20606   [(set_attr "type" "ssemul")
20607    (set_attr "mode" "SF")])
20608
20609 (define_insn "divv4sf3"
20610   [(set (match_operand:V4SF 0 "register_operand" "=x")
20611         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20612                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20613   "TARGET_SSE"
20614   "divps\t{%2, %0|%0, %2}"
20615   [(set_attr "type" "ssediv")
20616    (set_attr "mode" "V4SF")])
20617
20618 (define_insn "vmdivv4sf3"
20619   [(set (match_operand:V4SF 0 "register_operand" "=x")
20620         (vec_merge:V4SF
20621          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20622                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20623          (match_dup 1)
20624          (const_int 1)))]
20625   "TARGET_SSE"
20626   "divss\t{%2, %0|%0, %2}"
20627   [(set_attr "type" "ssediv")
20628    (set_attr "mode" "SF")])
20629
20630
20631 ;; SSE square root/reciprocal
20632
20633 (define_insn "rcpv4sf2"
20634   [(set (match_operand:V4SF 0 "register_operand" "=x")
20635         (unspec:V4SF
20636          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20637   "TARGET_SSE"
20638   "rcpps\t{%1, %0|%0, %1}"
20639   [(set_attr "type" "sse")
20640    (set_attr "mode" "V4SF")])
20641
20642 (define_insn "vmrcpv4sf2"
20643   [(set (match_operand:V4SF 0 "register_operand" "=x")
20644         (vec_merge:V4SF
20645          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20646                       UNSPEC_RCP)
20647          (match_operand:V4SF 2 "register_operand" "0")
20648          (const_int 1)))]
20649   "TARGET_SSE"
20650   "rcpss\t{%1, %0|%0, %1}"
20651   [(set_attr "type" "sse")
20652    (set_attr "mode" "SF")])
20653
20654 (define_insn "rsqrtv4sf2"
20655   [(set (match_operand:V4SF 0 "register_operand" "=x")
20656         (unspec:V4SF
20657          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20658   "TARGET_SSE"
20659   "rsqrtps\t{%1, %0|%0, %1}"
20660   [(set_attr "type" "sse")
20661    (set_attr "mode" "V4SF")])
20662
20663 (define_insn "vmrsqrtv4sf2"
20664   [(set (match_operand:V4SF 0 "register_operand" "=x")
20665         (vec_merge:V4SF
20666          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20667                       UNSPEC_RSQRT)
20668          (match_operand:V4SF 2 "register_operand" "0")
20669          (const_int 1)))]
20670   "TARGET_SSE"
20671   "rsqrtss\t{%1, %0|%0, %1}"
20672   [(set_attr "type" "sse")
20673    (set_attr "mode" "SF")])
20674
20675 (define_insn "sqrtv4sf2"
20676   [(set (match_operand:V4SF 0 "register_operand" "=x")
20677         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20678   "TARGET_SSE"
20679   "sqrtps\t{%1, %0|%0, %1}"
20680   [(set_attr "type" "sse")
20681    (set_attr "mode" "V4SF")])
20682
20683 (define_insn "vmsqrtv4sf2"
20684   [(set (match_operand:V4SF 0 "register_operand" "=x")
20685         (vec_merge:V4SF
20686          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20687          (match_operand:V4SF 2 "register_operand" "0")
20688          (const_int 1)))]
20689   "TARGET_SSE"
20690   "sqrtss\t{%1, %0|%0, %1}"
20691   [(set_attr "type" "sse")
20692    (set_attr "mode" "SF")])
20693
20694 ;; SSE logical operations.
20695
20696 ;; SSE defines logical operations on floating point values.  This brings
20697 ;; interesting challenge to RTL representation where logicals are only valid
20698 ;; on integral types.  We deal with this by representing the floating point
20699 ;; logical as logical on arguments casted to TImode as this is what hardware
20700 ;; really does.  Unfortunately hardware requires the type information to be
20701 ;; present and thus we must avoid subregs from being simplified and eliminated
20702 ;; in later compilation phases.
20703 ;;
20704 ;; We have following variants from each instruction:
20705 ;; sse_andsf3 - the operation taking V4SF vector operands
20706 ;;              and doing TImode cast on them
20707 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20708 ;;                      TImode, since backend insist on eliminating casts
20709 ;;                      on memory operands
20710 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20711 ;;                   We can not accept memory operand here as instruction reads
20712 ;;                   whole scalar.  This is generated only post reload by GCC
20713 ;;                   scalar float operations that expands to logicals (fabs)
20714 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20715 ;;                   memory operand.  Eventually combine can be able
20716 ;;                   to synthesize these using splitter.
20717 ;; sse2_anddf3, *sse2_anddf3_memory
20718 ;;              
20719 ;; 
20720 ;; These are not called andti3 etc. because we really really don't want
20721 ;; the compiler to widen DImode ands to TImode ands and then try to move
20722 ;; into DImode subregs of SSE registers, and them together, and move out
20723 ;; of DImode subregs again!
20724 ;; SSE1 single precision floating point logical operation
20725 (define_expand "sse_andv4sf3"
20726   [(set (match_operand:V4SF 0 "register_operand" "")
20727         (and:V4SF (match_operand:V4SF 1 "register_operand" "")
20728                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20729   "TARGET_SSE"
20730   "")
20731
20732 (define_insn "*sse_andv4sf3"
20733   [(set (match_operand:V4SF 0 "register_operand" "=x")
20734         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20735                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20736   "TARGET_SSE
20737    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20738   "andps\t{%2, %0|%0, %2}"
20739   [(set_attr "type" "sselog")
20740    (set_attr "mode" "V4SF")])
20741
20742 (define_expand "sse_nandv4sf3"
20743   [(set (match_operand:V4SF 0 "register_operand" "")
20744         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
20745                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20746   "TARGET_SSE"
20747   "")
20748
20749 (define_insn "*sse_nandv4sf3"
20750   [(set (match_operand:V4SF 0 "register_operand" "=x")
20751         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
20752                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20753   "TARGET_SSE"
20754   "andnps\t{%2, %0|%0, %2}"
20755   [(set_attr "type" "sselog")
20756    (set_attr "mode" "V4SF")])
20757
20758 (define_expand "sse_iorv4sf3"
20759   [(set (match_operand:V4SF 0 "register_operand" "")
20760         (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
20761                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20762   "TARGET_SSE"
20763   "")
20764
20765 (define_insn "*sse_iorv4sf3"
20766   [(set (match_operand:V4SF 0 "register_operand" "=x")
20767         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20768                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20769   "TARGET_SSE
20770    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20771   "orps\t{%2, %0|%0, %2}"
20772   [(set_attr "type" "sselog")
20773    (set_attr "mode" "V4SF")])
20774
20775 (define_expand "sse_xorv4sf3"
20776   [(set (match_operand:V4SF 0 "register_operand" "")
20777         (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
20778                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20779   "TARGET_SSE"
20780   "")
20781
20782 (define_insn "*sse_xorv4sf3"
20783   [(set (match_operand:V4SF 0 "register_operand" "=x")
20784         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20785                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20786   "TARGET_SSE
20787    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20788   "xorps\t{%2, %0|%0, %2}"
20789   [(set_attr "type" "sselog")
20790    (set_attr "mode" "V4SF")])
20791
20792 ;; SSE2 double precision floating point logical operation
20793
20794 (define_expand "sse2_andv2df3"
20795   [(set (match_operand:V2DF 0 "register_operand" "")
20796         (and:V2DF (match_operand:V2DF 1 "register_operand" "")
20797                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20798   "TARGET_SSE2"
20799   "")
20800
20801 (define_insn "*sse2_andv2df3"
20802   [(set (match_operand:V2DF 0 "register_operand" "=x")
20803         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20804                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20805   "TARGET_SSE2
20806    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20807   "andpd\t{%2, %0|%0, %2}"
20808   [(set_attr "type" "sselog")
20809    (set_attr "mode" "V2DF")])
20810
20811 (define_expand "sse2_nandv2df3"
20812   [(set (match_operand:V2DF 0 "register_operand" "")
20813         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
20814                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20815   "TARGET_SSE2"
20816   "")
20817
20818 (define_insn "*sse2_nandv2df3"
20819   [(set (match_operand:V2DF 0 "register_operand" "=x")
20820         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
20821                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20822   "TARGET_SSE2"
20823   "andnpd\t{%2, %0|%0, %2}"
20824   [(set_attr "type" "sselog")
20825    (set_attr "mode" "V2DF")])
20826
20827 (define_expand "sse2_iorv2df3"
20828   [(set (match_operand:V2DF 0 "register_operand" "")
20829         (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
20830                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20831   "TARGET_SSE2"
20832   "")
20833
20834 (define_insn "*sse2_iorv2df3"
20835   [(set (match_operand:V2DF 0 "register_operand" "=x")
20836         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20837                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20838   "TARGET_SSE2
20839    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20840   "orpd\t{%2, %0|%0, %2}"
20841   [(set_attr "type" "sselog")
20842    (set_attr "mode" "V2DF")])
20843
20844 (define_expand "sse2_xorv2df3"
20845   [(set (match_operand:V2DF 0 "register_operand" "")
20846         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
20847                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20848   "TARGET_SSE2"
20849   "")
20850
20851 (define_insn "*sse2_xorv2df3"
20852   [(set (match_operand:V2DF 0 "register_operand" "=x")
20853         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20854                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20855   "TARGET_SSE2
20856    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20857   "xorpd\t{%2, %0|%0, %2}"
20858   [(set_attr "type" "sselog")
20859    (set_attr "mode" "V2DF")])
20860
20861 ;; SSE2 integral logicals.  These patterns must always come after floating
20862 ;; point ones since we don't want compiler to use integer opcodes on floating
20863 ;; point SSE values to avoid matching of subregs in the match_operand.
20864 (define_insn "*sse2_andti3"
20865   [(set (match_operand:TI 0 "register_operand" "=x")
20866         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20867                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20868   "TARGET_SSE2
20869    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20870   "pand\t{%2, %0|%0, %2}"
20871   [(set_attr "type" "sselog")
20872    (set_attr "mode" "TI")])
20873
20874 (define_insn "sse2_andv2di3"
20875   [(set (match_operand:V2DI 0 "register_operand" "=x")
20876         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20877                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20878   "TARGET_SSE2
20879    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20880   "pand\t{%2, %0|%0, %2}"
20881   [(set_attr "type" "sselog")
20882    (set_attr "mode" "TI")])
20883
20884 (define_insn "*sse2_nandti3"
20885   [(set (match_operand:TI 0 "register_operand" "=x")
20886         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20887                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20888   "TARGET_SSE2"
20889   "pandn\t{%2, %0|%0, %2}"
20890   [(set_attr "type" "sselog")
20891    (set_attr "mode" "TI")])
20892
20893 (define_insn "sse2_nandv2di3"
20894   [(set (match_operand:V2DI 0 "register_operand" "=x")
20895         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20896                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20897   "TARGET_SSE2
20898    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20899   "pandn\t{%2, %0|%0, %2}"
20900   [(set_attr "type" "sselog")
20901    (set_attr "mode" "TI")])
20902
20903 (define_insn "*sse2_iorti3"
20904   [(set (match_operand:TI 0 "register_operand" "=x")
20905         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20906                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20907   "TARGET_SSE2
20908    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20909   "por\t{%2, %0|%0, %2}"
20910   [(set_attr "type" "sselog")
20911    (set_attr "mode" "TI")])
20912
20913 (define_insn "sse2_iorv2di3"
20914   [(set (match_operand:V2DI 0 "register_operand" "=x")
20915         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20916                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20917   "TARGET_SSE2
20918    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20919   "por\t{%2, %0|%0, %2}"
20920   [(set_attr "type" "sselog")
20921    (set_attr "mode" "TI")])
20922
20923 (define_insn "*sse2_xorti3"
20924   [(set (match_operand:TI 0 "register_operand" "=x")
20925         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20926                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20927   "TARGET_SSE2
20928    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20929   "pxor\t{%2, %0|%0, %2}"
20930   [(set_attr "type" "sselog")
20931    (set_attr "mode" "TI")])
20932
20933 (define_insn "sse2_xorv2di3"
20934   [(set (match_operand:V2DI 0 "register_operand" "=x")
20935         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20936                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20937   "TARGET_SSE2
20938    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20939   "pxor\t{%2, %0|%0, %2}"
20940   [(set_attr "type" "sselog")
20941    (set_attr "mode" "TI")])
20942
20943 ;; Use xor, but don't show input operands so they aren't live before
20944 ;; this insn.
20945 (define_insn "sse_clrv4sf"
20946   [(set (match_operand:V4SF 0 "register_operand" "=x")
20947         (match_operand:V4SF 1 "const0_operand" "X"))]
20948   "TARGET_SSE"
20949 {
20950   if (get_attr_mode (insn) == MODE_TI)
20951     return "pxor\t{%0, %0|%0, %0}";
20952   else
20953     return "xorps\t{%0, %0|%0, %0}";
20954 }
20955   [(set_attr "type" "sselog")
20956    (set_attr "memory" "none")
20957    (set (attr "mode")
20958         (if_then_else
20959            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
20960                          (const_int 0))
20961                      (ne (symbol_ref "TARGET_SSE2")
20962                          (const_int 0)))
20963                 (eq (symbol_ref "optimize_size")
20964                     (const_int 0)))
20965          (const_string "TI")
20966          (const_string "V4SF")))])
20967
20968 ;; Use xor, but don't show input operands so they aren't live before
20969 ;; this insn.
20970 (define_insn "sse_clrv2df"
20971   [(set (match_operand:V2DF 0 "register_operand" "=x")
20972         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
20973   "TARGET_SSE2"
20974   "xorpd\t{%0, %0|%0, %0}"
20975   [(set_attr "type" "sselog")
20976    (set_attr "memory" "none")
20977    (set_attr "mode" "V4SF")])
20978
20979 ;; SSE mask-generating compares
20980
20981 (define_insn "maskcmpv4sf3"
20982   [(set (match_operand:V4SI 0 "register_operand" "=x")
20983         (match_operator:V4SI 3 "sse_comparison_operator"
20984                 [(match_operand:V4SF 1 "register_operand" "0")
20985                  (match_operand:V4SF 2 "register_operand" "x")]))]
20986   "TARGET_SSE"
20987   "cmp%D3ps\t{%2, %0|%0, %2}"
20988   [(set_attr "type" "ssecmp")
20989    (set_attr "mode" "V4SF")])
20990
20991 (define_insn "maskncmpv4sf3"
20992   [(set (match_operand:V4SI 0 "register_operand" "=x")
20993         (not:V4SI
20994          (match_operator:V4SI 3 "sse_comparison_operator"
20995                 [(match_operand:V4SF 1 "register_operand" "0")
20996                  (match_operand:V4SF 2 "register_operand" "x")])))]
20997   "TARGET_SSE"
20998 {
20999   if (GET_CODE (operands[3]) == UNORDERED)
21000     return "cmpordps\t{%2, %0|%0, %2}";
21001   else
21002     return "cmpn%D3ps\t{%2, %0|%0, %2}";
21003 }
21004   [(set_attr "type" "ssecmp")
21005    (set_attr "mode" "V4SF")])
21006
21007 (define_insn "vmmaskcmpv4sf3"
21008   [(set (match_operand:V4SI 0 "register_operand" "=x")
21009         (vec_merge:V4SI
21010          (match_operator:V4SI 3 "sse_comparison_operator"
21011                 [(match_operand:V4SF 1 "register_operand" "0")
21012                  (match_operand:V4SF 2 "register_operand" "x")])
21013          (subreg:V4SI (match_dup 1) 0)
21014          (const_int 1)))]
21015   "TARGET_SSE"
21016   "cmp%D3ss\t{%2, %0|%0, %2}"
21017   [(set_attr "type" "ssecmp")
21018    (set_attr "mode" "SF")])
21019
21020 (define_insn "vmmaskncmpv4sf3"
21021   [(set (match_operand:V4SI 0 "register_operand" "=x")
21022         (vec_merge:V4SI
21023          (not:V4SI
21024           (match_operator:V4SI 3 "sse_comparison_operator"
21025                 [(match_operand:V4SF 1 "register_operand" "0")
21026                  (match_operand:V4SF 2 "register_operand" "x")]))
21027          (subreg:V4SI (match_dup 1) 0)
21028          (const_int 1)))]
21029   "TARGET_SSE"
21030 {
21031   if (GET_CODE (operands[3]) == UNORDERED)
21032     return "cmpordss\t{%2, %0|%0, %2}";
21033   else
21034     return "cmpn%D3ss\t{%2, %0|%0, %2}";
21035 }
21036   [(set_attr "type" "ssecmp")
21037    (set_attr "mode" "SF")])
21038
21039 (define_insn "sse_comi"
21040   [(set (reg:CCFP FLAGS_REG)
21041         (compare:CCFP (vec_select:SF
21042                        (match_operand:V4SF 0 "register_operand" "x")
21043                        (parallel [(const_int 0)]))
21044                       (vec_select:SF
21045                        (match_operand:V4SF 1 "register_operand" "x")
21046                        (parallel [(const_int 0)]))))]
21047   "TARGET_SSE"
21048   "comiss\t{%1, %0|%0, %1}"
21049   [(set_attr "type" "ssecomi")
21050    (set_attr "mode" "SF")])
21051
21052 (define_insn "sse_ucomi"
21053   [(set (reg:CCFPU FLAGS_REG)
21054         (compare:CCFPU (vec_select:SF
21055                         (match_operand:V4SF 0 "register_operand" "x")
21056                         (parallel [(const_int 0)]))
21057                        (vec_select:SF
21058                         (match_operand:V4SF 1 "register_operand" "x")
21059                         (parallel [(const_int 0)]))))]
21060   "TARGET_SSE"
21061   "ucomiss\t{%1, %0|%0, %1}"
21062   [(set_attr "type" "ssecomi")
21063    (set_attr "mode" "SF")])
21064
21065
21066 ;; SSE unpack
21067
21068 (define_insn "sse_unpckhps"
21069   [(set (match_operand:V4SF 0 "register_operand" "=x")
21070         (vec_merge:V4SF
21071          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21072                           (parallel [(const_int 2)
21073                                      (const_int 0)
21074                                      (const_int 3)
21075                                      (const_int 1)]))
21076          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21077                           (parallel [(const_int 0)
21078                                      (const_int 2)
21079                                      (const_int 1)
21080                                      (const_int 3)]))
21081          (const_int 5)))]
21082   "TARGET_SSE"
21083   "unpckhps\t{%2, %0|%0, %2}"
21084   [(set_attr "type" "ssecvt")
21085    (set_attr "mode" "V4SF")])
21086
21087 (define_insn "sse_unpcklps"
21088   [(set (match_operand:V4SF 0 "register_operand" "=x")
21089         (vec_merge:V4SF
21090          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21091                           (parallel [(const_int 0)
21092                                      (const_int 2)
21093                                      (const_int 1)
21094                                      (const_int 3)]))
21095          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21096                           (parallel [(const_int 2)
21097                                      (const_int 0)
21098                                      (const_int 3)
21099                                      (const_int 1)]))
21100          (const_int 5)))]
21101   "TARGET_SSE"
21102   "unpcklps\t{%2, %0|%0, %2}"
21103   [(set_attr "type" "ssecvt")
21104    (set_attr "mode" "V4SF")])
21105
21106
21107 ;; SSE min/max
21108
21109 (define_insn "smaxv4sf3"
21110   [(set (match_operand:V4SF 0 "register_operand" "=x")
21111         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21112                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21113   "TARGET_SSE"
21114   "maxps\t{%2, %0|%0, %2}"
21115   [(set_attr "type" "sse")
21116    (set_attr "mode" "V4SF")])
21117
21118 (define_insn "vmsmaxv4sf3"
21119   [(set (match_operand:V4SF 0 "register_operand" "=x")
21120         (vec_merge:V4SF
21121          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21122                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21123          (match_dup 1)
21124          (const_int 1)))]
21125   "TARGET_SSE"
21126   "maxss\t{%2, %0|%0, %2}"
21127   [(set_attr "type" "sse")
21128    (set_attr "mode" "SF")])
21129
21130 (define_insn "sminv4sf3"
21131   [(set (match_operand:V4SF 0 "register_operand" "=x")
21132         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21133                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21134   "TARGET_SSE"
21135   "minps\t{%2, %0|%0, %2}"
21136   [(set_attr "type" "sse")
21137    (set_attr "mode" "V4SF")])
21138
21139 (define_insn "vmsminv4sf3"
21140   [(set (match_operand:V4SF 0 "register_operand" "=x")
21141         (vec_merge:V4SF
21142          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21143                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21144          (match_dup 1)
21145          (const_int 1)))]
21146   "TARGET_SSE"
21147   "minss\t{%2, %0|%0, %2}"
21148   [(set_attr "type" "sse")
21149    (set_attr "mode" "SF")])
21150
21151 ;; SSE <-> integer/MMX conversions
21152
21153 (define_insn "cvtpi2ps"
21154   [(set (match_operand:V4SF 0 "register_operand" "=x")
21155         (vec_merge:V4SF
21156          (match_operand:V4SF 1 "register_operand" "0")
21157          (vec_duplicate:V4SF
21158           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
21159          (const_int 12)))]
21160   "TARGET_SSE"
21161   "cvtpi2ps\t{%2, %0|%0, %2}"
21162   [(set_attr "type" "ssecvt")
21163    (set_attr "mode" "V4SF")])
21164
21165 (define_insn "cvtps2pi"
21166   [(set (match_operand:V2SI 0 "register_operand" "=y")
21167         (vec_select:V2SI
21168          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21169          (parallel [(const_int 0) (const_int 1)])))]
21170   "TARGET_SSE"
21171   "cvtps2pi\t{%1, %0|%0, %1}"
21172   [(set_attr "type" "ssecvt")
21173    (set_attr "mode" "V4SF")])
21174
21175 (define_insn "cvttps2pi"
21176   [(set (match_operand:V2SI 0 "register_operand" "=y")
21177         (vec_select:V2SI
21178          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21179                       UNSPEC_FIX)
21180          (parallel [(const_int 0) (const_int 1)])))]
21181   "TARGET_SSE"
21182   "cvttps2pi\t{%1, %0|%0, %1}"
21183   [(set_attr "type" "ssecvt")
21184    (set_attr "mode" "SF")])
21185
21186 (define_insn "cvtsi2ss"
21187   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21188         (vec_merge:V4SF
21189          (match_operand:V4SF 1 "register_operand" "0,0")
21190          (vec_duplicate:V4SF
21191           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21192          (const_int 14)))]
21193   "TARGET_SSE"
21194   "cvtsi2ss\t{%2, %0|%0, %2}"
21195   [(set_attr "type" "sseicvt")
21196    (set_attr "athlon_decode" "vector,double")
21197    (set_attr "mode" "SF")])
21198
21199 (define_insn "cvtsi2ssq"
21200   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21201         (vec_merge:V4SF
21202          (match_operand:V4SF 1 "register_operand" "0,0")
21203          (vec_duplicate:V4SF
21204           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21205          (const_int 14)))]
21206   "TARGET_SSE && TARGET_64BIT"
21207   "cvtsi2ssq\t{%2, %0|%0, %2}"
21208   [(set_attr "type" "sseicvt")
21209    (set_attr "athlon_decode" "vector,double")
21210    (set_attr "mode" "SF")])
21211
21212 (define_insn "cvtss2si"
21213   [(set (match_operand:SI 0 "register_operand" "=r,r")
21214         (vec_select:SI
21215          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21216          (parallel [(const_int 0)])))]
21217   "TARGET_SSE"
21218   "cvtss2si\t{%1, %0|%0, %1}"
21219   [(set_attr "type" "sseicvt")
21220    (set_attr "athlon_decode" "double,vector")
21221    (set_attr "mode" "SI")])
21222
21223 (define_insn "cvtss2siq"
21224   [(set (match_operand:DI 0 "register_operand" "=r,r")
21225         (vec_select:DI
21226          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21227          (parallel [(const_int 0)])))]
21228   "TARGET_SSE"
21229   "cvtss2siq\t{%1, %0|%0, %1}"
21230   [(set_attr "type" "sseicvt")
21231    (set_attr "athlon_decode" "double,vector")
21232    (set_attr "mode" "DI")])
21233
21234 (define_insn "cvttss2si"
21235   [(set (match_operand:SI 0 "register_operand" "=r,r")
21236         (vec_select:SI
21237          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21238                       UNSPEC_FIX)
21239          (parallel [(const_int 0)])))]
21240   "TARGET_SSE"
21241   "cvttss2si\t{%1, %0|%0, %1}"
21242   [(set_attr "type" "sseicvt")
21243    (set_attr "mode" "SF")
21244    (set_attr "athlon_decode" "double,vector")])
21245
21246 (define_insn "cvttss2siq"
21247   [(set (match_operand:DI 0 "register_operand" "=r,r")
21248         (vec_select:DI
21249          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21250                       UNSPEC_FIX)
21251          (parallel [(const_int 0)])))]
21252   "TARGET_SSE && TARGET_64BIT"
21253   "cvttss2siq\t{%1, %0|%0, %1}"
21254   [(set_attr "type" "sseicvt")
21255    (set_attr "mode" "SF")
21256    (set_attr "athlon_decode" "double,vector")])
21257
21258
21259 ;; MMX insns
21260
21261 ;; MMX arithmetic
21262
21263 (define_insn "addv8qi3"
21264   [(set (match_operand:V8QI 0 "register_operand" "=y")
21265         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21266                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21267   "TARGET_MMX"
21268   "paddb\t{%2, %0|%0, %2}"
21269   [(set_attr "type" "mmxadd")
21270    (set_attr "mode" "DI")])
21271
21272 (define_insn "addv4hi3"
21273   [(set (match_operand:V4HI 0 "register_operand" "=y")
21274         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21275                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21276   "TARGET_MMX"
21277   "paddw\t{%2, %0|%0, %2}"
21278   [(set_attr "type" "mmxadd")
21279    (set_attr "mode" "DI")])
21280
21281 (define_insn "addv2si3"
21282   [(set (match_operand:V2SI 0 "register_operand" "=y")
21283         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21284                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21285   "TARGET_MMX"
21286   "paddd\t{%2, %0|%0, %2}"
21287   [(set_attr "type" "mmxadd")
21288    (set_attr "mode" "DI")])
21289
21290 (define_insn "mmx_adddi3"
21291   [(set (match_operand:DI 0 "register_operand" "=y")
21292         (unspec:DI
21293          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21294                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21295          UNSPEC_NOP))]
21296   "TARGET_MMX"
21297   "paddq\t{%2, %0|%0, %2}"
21298   [(set_attr "type" "mmxadd")
21299    (set_attr "mode" "DI")])
21300
21301 (define_insn "ssaddv8qi3"
21302   [(set (match_operand:V8QI 0 "register_operand" "=y")
21303         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21304                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21305   "TARGET_MMX"
21306   "paddsb\t{%2, %0|%0, %2}"
21307   [(set_attr "type" "mmxadd")
21308    (set_attr "mode" "DI")])
21309
21310 (define_insn "ssaddv4hi3"
21311   [(set (match_operand:V4HI 0 "register_operand" "=y")
21312         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21313                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21314   "TARGET_MMX"
21315   "paddsw\t{%2, %0|%0, %2}"
21316   [(set_attr "type" "mmxadd")
21317    (set_attr "mode" "DI")])
21318
21319 (define_insn "usaddv8qi3"
21320   [(set (match_operand:V8QI 0 "register_operand" "=y")
21321         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21322                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21323   "TARGET_MMX"
21324   "paddusb\t{%2, %0|%0, %2}"
21325   [(set_attr "type" "mmxadd")
21326    (set_attr "mode" "DI")])
21327
21328 (define_insn "usaddv4hi3"
21329   [(set (match_operand:V4HI 0 "register_operand" "=y")
21330         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21331                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21332   "TARGET_MMX"
21333   "paddusw\t{%2, %0|%0, %2}"
21334   [(set_attr "type" "mmxadd")
21335    (set_attr "mode" "DI")])
21336
21337 (define_insn "subv8qi3"
21338   [(set (match_operand:V8QI 0 "register_operand" "=y")
21339         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21340                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21341   "TARGET_MMX"
21342   "psubb\t{%2, %0|%0, %2}"
21343   [(set_attr "type" "mmxadd")
21344    (set_attr "mode" "DI")])
21345
21346 (define_insn "subv4hi3"
21347   [(set (match_operand:V4HI 0 "register_operand" "=y")
21348         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21349                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21350   "TARGET_MMX"
21351   "psubw\t{%2, %0|%0, %2}"
21352   [(set_attr "type" "mmxadd")
21353    (set_attr "mode" "DI")])
21354
21355 (define_insn "subv2si3"
21356   [(set (match_operand:V2SI 0 "register_operand" "=y")
21357         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21358                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21359   "TARGET_MMX"
21360   "psubd\t{%2, %0|%0, %2}"
21361   [(set_attr "type" "mmxadd")
21362    (set_attr "mode" "DI")])
21363
21364 (define_insn "mmx_subdi3"
21365   [(set (match_operand:DI 0 "register_operand" "=y")
21366         (unspec:DI
21367          [(minus:DI (match_operand:DI 1 "register_operand" "0")
21368                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21369          UNSPEC_NOP))]
21370   "TARGET_MMX"
21371   "psubq\t{%2, %0|%0, %2}"
21372   [(set_attr "type" "mmxadd")
21373    (set_attr "mode" "DI")])
21374
21375 (define_insn "sssubv8qi3"
21376   [(set (match_operand:V8QI 0 "register_operand" "=y")
21377         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21378                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21379   "TARGET_MMX"
21380   "psubsb\t{%2, %0|%0, %2}"
21381   [(set_attr "type" "mmxadd")
21382    (set_attr "mode" "DI")])
21383
21384 (define_insn "sssubv4hi3"
21385   [(set (match_operand:V4HI 0 "register_operand" "=y")
21386         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21387                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21388   "TARGET_MMX"
21389   "psubsw\t{%2, %0|%0, %2}"
21390   [(set_attr "type" "mmxadd")
21391    (set_attr "mode" "DI")])
21392
21393 (define_insn "ussubv8qi3"
21394   [(set (match_operand:V8QI 0 "register_operand" "=y")
21395         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21396                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21397   "TARGET_MMX"
21398   "psubusb\t{%2, %0|%0, %2}"
21399   [(set_attr "type" "mmxadd")
21400    (set_attr "mode" "DI")])
21401
21402 (define_insn "ussubv4hi3"
21403   [(set (match_operand:V4HI 0 "register_operand" "=y")
21404         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21405                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21406   "TARGET_MMX"
21407   "psubusw\t{%2, %0|%0, %2}"
21408   [(set_attr "type" "mmxadd")
21409    (set_attr "mode" "DI")])
21410
21411 (define_insn "mulv4hi3"
21412   [(set (match_operand:V4HI 0 "register_operand" "=y")
21413         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21414                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21415   "TARGET_MMX"
21416   "pmullw\t{%2, %0|%0, %2}"
21417   [(set_attr "type" "mmxmul")
21418    (set_attr "mode" "DI")])
21419
21420 (define_insn "smulv4hi3_highpart"
21421   [(set (match_operand:V4HI 0 "register_operand" "=y")
21422         (truncate:V4HI
21423          (lshiftrt:V4SI
21424           (mult:V4SI (sign_extend:V4SI
21425                       (match_operand:V4HI 1 "register_operand" "0"))
21426                      (sign_extend:V4SI
21427                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21428           (const_int 16))))]
21429   "TARGET_MMX"
21430   "pmulhw\t{%2, %0|%0, %2}"
21431   [(set_attr "type" "mmxmul")
21432    (set_attr "mode" "DI")])
21433
21434 (define_insn "umulv4hi3_highpart"
21435   [(set (match_operand:V4HI 0 "register_operand" "=y")
21436         (truncate:V4HI
21437          (lshiftrt:V4SI
21438           (mult:V4SI (zero_extend:V4SI
21439                       (match_operand:V4HI 1 "register_operand" "0"))
21440                      (zero_extend:V4SI
21441                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21442           (const_int 16))))]
21443   "TARGET_SSE || TARGET_3DNOW_A"
21444   "pmulhuw\t{%2, %0|%0, %2}"
21445   [(set_attr "type" "mmxmul")
21446    (set_attr "mode" "DI")])
21447
21448 (define_insn "mmx_pmaddwd"
21449   [(set (match_operand:V2SI 0 "register_operand" "=y")
21450         (plus:V2SI
21451          (mult:V2SI
21452           (sign_extend:V2SI
21453            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21454                             (parallel [(const_int 0) (const_int 2)])))
21455           (sign_extend:V2SI
21456            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21457                             (parallel [(const_int 0) (const_int 2)]))))
21458          (mult:V2SI
21459           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21460                                              (parallel [(const_int 1)
21461                                                         (const_int 3)])))
21462           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21463                                              (parallel [(const_int 1)
21464                                                         (const_int 3)]))))))]
21465   "TARGET_MMX"
21466   "pmaddwd\t{%2, %0|%0, %2}"
21467   [(set_attr "type" "mmxmul")
21468    (set_attr "mode" "DI")])
21469
21470
21471 ;; MMX logical operations
21472 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21473 ;; normal code that also wants to use the FPU from getting broken.
21474 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21475 (define_insn "mmx_iordi3"
21476   [(set (match_operand:DI 0 "register_operand" "=y")
21477         (unspec:DI
21478          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21479                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21480          UNSPEC_NOP))]
21481   "TARGET_MMX"
21482   "por\t{%2, %0|%0, %2}"
21483   [(set_attr "type" "mmxadd")
21484    (set_attr "mode" "DI")])
21485
21486 (define_insn "mmx_xordi3"
21487   [(set (match_operand:DI 0 "register_operand" "=y")
21488         (unspec:DI
21489          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21490                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21491          UNSPEC_NOP))]
21492   "TARGET_MMX"
21493   "pxor\t{%2, %0|%0, %2}"
21494   [(set_attr "type" "mmxadd")
21495    (set_attr "mode" "DI")
21496    (set_attr "memory" "none")])
21497
21498 ;; Same as pxor, but don't show input operands so that we don't think
21499 ;; they are live.
21500 (define_insn "mmx_clrdi"
21501   [(set (match_operand:DI 0 "register_operand" "=y")
21502         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21503   "TARGET_MMX"
21504   "pxor\t{%0, %0|%0, %0}"
21505   [(set_attr "type" "mmxadd")
21506    (set_attr "mode" "DI")
21507    (set_attr "memory" "none")])
21508
21509 (define_insn "mmx_anddi3"
21510   [(set (match_operand:DI 0 "register_operand" "=y")
21511         (unspec:DI
21512          [(and:DI (match_operand:DI 1 "register_operand" "%0")
21513                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21514          UNSPEC_NOP))]
21515   "TARGET_MMX"
21516   "pand\t{%2, %0|%0, %2}"
21517   [(set_attr "type" "mmxadd")
21518    (set_attr "mode" "DI")])
21519
21520 (define_insn "mmx_nanddi3"
21521   [(set (match_operand:DI 0 "register_operand" "=y")
21522         (unspec:DI
21523          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21524                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21525          UNSPEC_NOP))]
21526   "TARGET_MMX"
21527   "pandn\t{%2, %0|%0, %2}"
21528   [(set_attr "type" "mmxadd")
21529    (set_attr "mode" "DI")])
21530
21531
21532 ;; MMX unsigned averages/sum of absolute differences
21533
21534 (define_insn "mmx_uavgv8qi3"
21535   [(set (match_operand:V8QI 0 "register_operand" "=y")
21536         (ashiftrt:V8QI
21537          (plus:V8QI (plus:V8QI
21538                      (match_operand:V8QI 1 "register_operand" "0")
21539                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21540                     (const_vector:V8QI [(const_int 1)
21541                                         (const_int 1)
21542                                         (const_int 1)
21543                                         (const_int 1)
21544                                         (const_int 1)
21545                                         (const_int 1)
21546                                         (const_int 1)
21547                                         (const_int 1)]))
21548          (const_int 1)))]
21549   "TARGET_SSE || TARGET_3DNOW_A"
21550   "pavgb\t{%2, %0|%0, %2}"
21551   [(set_attr "type" "mmxshft")
21552    (set_attr "mode" "DI")])
21553
21554 (define_insn "mmx_uavgv4hi3"
21555   [(set (match_operand:V4HI 0 "register_operand" "=y")
21556         (ashiftrt:V4HI
21557          (plus:V4HI (plus:V4HI
21558                      (match_operand:V4HI 1 "register_operand" "0")
21559                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21560                     (const_vector:V4HI [(const_int 1)
21561                                         (const_int 1)
21562                                         (const_int 1)
21563                                         (const_int 1)]))
21564          (const_int 1)))]
21565   "TARGET_SSE || TARGET_3DNOW_A"
21566   "pavgw\t{%2, %0|%0, %2}"
21567   [(set_attr "type" "mmxshft")
21568    (set_attr "mode" "DI")])
21569
21570 (define_insn "mmx_psadbw"
21571   [(set (match_operand:DI 0 "register_operand" "=y")
21572         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21573                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21574                    UNSPEC_PSADBW))]
21575   "TARGET_SSE || TARGET_3DNOW_A"
21576   "psadbw\t{%2, %0|%0, %2}"
21577   [(set_attr "type" "mmxshft")
21578    (set_attr "mode" "DI")])
21579
21580
21581 ;; MMX insert/extract/shuffle
21582
21583 (define_insn "mmx_pinsrw"
21584   [(set (match_operand:V4HI 0 "register_operand" "=y")
21585         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21586                         (vec_duplicate:V4HI
21587                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21588                         (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21589   "TARGET_SSE || TARGET_3DNOW_A"
21590   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21591   [(set_attr "type" "mmxcvt")
21592    (set_attr "mode" "DI")])
21593
21594 (define_insn "mmx_pextrw"
21595   [(set (match_operand:SI 0 "register_operand" "=r")
21596         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21597                                        (parallel
21598                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21599   "TARGET_SSE || TARGET_3DNOW_A"
21600   "pextrw\t{%2, %1, %0|%0, %1, %2}"
21601   [(set_attr "type" "mmxcvt")
21602    (set_attr "mode" "DI")])
21603
21604 (define_insn "mmx_pshufw"
21605   [(set (match_operand:V4HI 0 "register_operand" "=y")
21606         (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21607                       (match_operand:SI 2 "immediate_operand" "i")]
21608                      UNSPEC_SHUFFLE))]
21609   "TARGET_SSE || TARGET_3DNOW_A"
21610   "pshufw\t{%2, %1, %0|%0, %1, %2}"
21611   [(set_attr "type" "mmxcvt")
21612    (set_attr "mode" "DI")])
21613
21614
21615 ;; MMX mask-generating comparisons
21616
21617 (define_insn "eqv8qi3"
21618   [(set (match_operand:V8QI 0 "register_operand" "=y")
21619         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21620                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21621   "TARGET_MMX"
21622   "pcmpeqb\t{%2, %0|%0, %2}"
21623   [(set_attr "type" "mmxcmp")
21624    (set_attr "mode" "DI")])
21625
21626 (define_insn "eqv4hi3"
21627   [(set (match_operand:V4HI 0 "register_operand" "=y")
21628         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21629                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21630   "TARGET_MMX"
21631   "pcmpeqw\t{%2, %0|%0, %2}"
21632   [(set_attr "type" "mmxcmp")
21633    (set_attr "mode" "DI")])
21634
21635 (define_insn "eqv2si3"
21636   [(set (match_operand:V2SI 0 "register_operand" "=y")
21637         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21638                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21639   "TARGET_MMX"
21640   "pcmpeqd\t{%2, %0|%0, %2}"
21641   [(set_attr "type" "mmxcmp")
21642    (set_attr "mode" "DI")])
21643
21644 (define_insn "gtv8qi3"
21645   [(set (match_operand:V8QI 0 "register_operand" "=y")
21646         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21647                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21648   "TARGET_MMX"
21649   "pcmpgtb\t{%2, %0|%0, %2}"
21650   [(set_attr "type" "mmxcmp")
21651    (set_attr "mode" "DI")])
21652
21653 (define_insn "gtv4hi3"
21654   [(set (match_operand:V4HI 0 "register_operand" "=y")
21655         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21656                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21657   "TARGET_MMX"
21658   "pcmpgtw\t{%2, %0|%0, %2}"
21659   [(set_attr "type" "mmxcmp")
21660    (set_attr "mode" "DI")])
21661
21662 (define_insn "gtv2si3"
21663   [(set (match_operand:V2SI 0 "register_operand" "=y")
21664         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21665                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21666   "TARGET_MMX"
21667   "pcmpgtd\t{%2, %0|%0, %2}"
21668   [(set_attr "type" "mmxcmp")
21669    (set_attr "mode" "DI")])
21670
21671
21672 ;; MMX max/min insns
21673
21674 (define_insn "umaxv8qi3"
21675   [(set (match_operand:V8QI 0 "register_operand" "=y")
21676         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21677                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21678   "TARGET_SSE || TARGET_3DNOW_A"
21679   "pmaxub\t{%2, %0|%0, %2}"
21680   [(set_attr "type" "mmxadd")
21681    (set_attr "mode" "DI")])
21682
21683 (define_insn "smaxv4hi3"
21684   [(set (match_operand:V4HI 0 "register_operand" "=y")
21685         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21686                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21687   "TARGET_SSE || TARGET_3DNOW_A"
21688   "pmaxsw\t{%2, %0|%0, %2}"
21689   [(set_attr "type" "mmxadd")
21690    (set_attr "mode" "DI")])
21691
21692 (define_insn "uminv8qi3"
21693   [(set (match_operand:V8QI 0 "register_operand" "=y")
21694         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21695                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21696   "TARGET_SSE || TARGET_3DNOW_A"
21697   "pminub\t{%2, %0|%0, %2}"
21698   [(set_attr "type" "mmxadd")
21699    (set_attr "mode" "DI")])
21700
21701 (define_insn "sminv4hi3"
21702   [(set (match_operand:V4HI 0 "register_operand" "=y")
21703         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21704                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21705   "TARGET_SSE || TARGET_3DNOW_A"
21706   "pminsw\t{%2, %0|%0, %2}"
21707   [(set_attr "type" "mmxadd")
21708    (set_attr "mode" "DI")])
21709
21710
21711 ;; MMX shifts
21712
21713 (define_insn "ashrv4hi3"
21714   [(set (match_operand:V4HI 0 "register_operand" "=y")
21715         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21716                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21717   "TARGET_MMX"
21718   "psraw\t{%2, %0|%0, %2}"
21719   [(set_attr "type" "mmxshft")
21720    (set_attr "mode" "DI")])
21721
21722 (define_insn "ashrv2si3"
21723   [(set (match_operand:V2SI 0 "register_operand" "=y")
21724         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21725                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21726   "TARGET_MMX"
21727   "psrad\t{%2, %0|%0, %2}"
21728   [(set_attr "type" "mmxshft")
21729    (set_attr "mode" "DI")])
21730
21731 (define_insn "lshrv4hi3"
21732   [(set (match_operand:V4HI 0 "register_operand" "=y")
21733         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21734                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21735   "TARGET_MMX"
21736   "psrlw\t{%2, %0|%0, %2}"
21737   [(set_attr "type" "mmxshft")
21738    (set_attr "mode" "DI")])
21739
21740 (define_insn "lshrv2si3"
21741   [(set (match_operand:V2SI 0 "register_operand" "=y")
21742         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21743                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21744   "TARGET_MMX"
21745   "psrld\t{%2, %0|%0, %2}"
21746   [(set_attr "type" "mmxshft")
21747    (set_attr "mode" "DI")])
21748
21749 ;; See logical MMX insns.
21750 (define_insn "mmx_lshrdi3"
21751   [(set (match_operand:DI 0 "register_operand" "=y")
21752         (unspec:DI
21753           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21754                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
21755           UNSPEC_NOP))]
21756   "TARGET_MMX"
21757   "psrlq\t{%2, %0|%0, %2}"
21758   [(set_attr "type" "mmxshft")
21759    (set_attr "mode" "DI")])
21760
21761 (define_insn "ashlv4hi3"
21762   [(set (match_operand:V4HI 0 "register_operand" "=y")
21763         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21764                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21765   "TARGET_MMX"
21766   "psllw\t{%2, %0|%0, %2}"
21767   [(set_attr "type" "mmxshft")
21768    (set_attr "mode" "DI")])
21769
21770 (define_insn "ashlv2si3"
21771   [(set (match_operand:V2SI 0 "register_operand" "=y")
21772         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21773                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21774   "TARGET_MMX"
21775   "pslld\t{%2, %0|%0, %2}"
21776   [(set_attr "type" "mmxshft")
21777    (set_attr "mode" "DI")])
21778
21779 ;; See logical MMX insns.
21780 (define_insn "mmx_ashldi3"
21781   [(set (match_operand:DI 0 "register_operand" "=y")
21782         (unspec:DI
21783          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21784                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
21785          UNSPEC_NOP))]
21786   "TARGET_MMX"
21787   "psllq\t{%2, %0|%0, %2}"
21788   [(set_attr "type" "mmxshft")
21789    (set_attr "mode" "DI")])
21790
21791
21792 ;; MMX pack/unpack insns.
21793
21794 (define_insn "mmx_packsswb"
21795   [(set (match_operand:V8QI 0 "register_operand" "=y")
21796         (vec_concat:V8QI
21797          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21798          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21799   "TARGET_MMX"
21800   "packsswb\t{%2, %0|%0, %2}"
21801   [(set_attr "type" "mmxshft")
21802    (set_attr "mode" "DI")])
21803
21804 (define_insn "mmx_packssdw"
21805   [(set (match_operand:V4HI 0 "register_operand" "=y")
21806         (vec_concat:V4HI
21807          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21808          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21809   "TARGET_MMX"
21810   "packssdw\t{%2, %0|%0, %2}"
21811   [(set_attr "type" "mmxshft")
21812    (set_attr "mode" "DI")])
21813
21814 (define_insn "mmx_packuswb"
21815   [(set (match_operand:V8QI 0 "register_operand" "=y")
21816         (vec_concat:V8QI
21817          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21818          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21819   "TARGET_MMX"
21820   "packuswb\t{%2, %0|%0, %2}"
21821   [(set_attr "type" "mmxshft")
21822    (set_attr "mode" "DI")])
21823
21824 (define_insn "mmx_punpckhbw"
21825   [(set (match_operand:V8QI 0 "register_operand" "=y")
21826         (vec_merge:V8QI
21827          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21828                           (parallel [(const_int 4)
21829                                      (const_int 0)
21830                                      (const_int 5)
21831                                      (const_int 1)
21832                                      (const_int 6)
21833                                      (const_int 2)
21834                                      (const_int 7)
21835                                      (const_int 3)]))
21836          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21837                           (parallel [(const_int 0)
21838                                      (const_int 4)
21839                                      (const_int 1)
21840                                      (const_int 5)
21841                                      (const_int 2)
21842                                      (const_int 6)
21843                                      (const_int 3)
21844                                      (const_int 7)]))
21845          (const_int 85)))]
21846   "TARGET_MMX"
21847   "punpckhbw\t{%2, %0|%0, %2}"
21848   [(set_attr "type" "mmxcvt")
21849    (set_attr "mode" "DI")])
21850
21851 (define_insn "mmx_punpckhwd"
21852   [(set (match_operand:V4HI 0 "register_operand" "=y")
21853         (vec_merge:V4HI
21854          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21855                           (parallel [(const_int 0)
21856                                      (const_int 2)
21857                                      (const_int 1)
21858                                      (const_int 3)]))
21859          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21860                           (parallel [(const_int 2)
21861                                      (const_int 0)
21862                                      (const_int 3)
21863                                      (const_int 1)]))
21864          (const_int 5)))]
21865   "TARGET_MMX"
21866   "punpckhwd\t{%2, %0|%0, %2}"
21867   [(set_attr "type" "mmxcvt")
21868    (set_attr "mode" "DI")])
21869
21870 (define_insn "mmx_punpckhdq"
21871   [(set (match_operand:V2SI 0 "register_operand" "=y")
21872         (vec_merge:V2SI
21873          (match_operand:V2SI 1 "register_operand" "0")
21874          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21875                           (parallel [(const_int 1)
21876                                      (const_int 0)]))
21877          (const_int 1)))]
21878   "TARGET_MMX"
21879   "punpckhdq\t{%2, %0|%0, %2}"
21880   [(set_attr "type" "mmxcvt")
21881    (set_attr "mode" "DI")])
21882
21883 (define_insn "mmx_punpcklbw"
21884   [(set (match_operand:V8QI 0 "register_operand" "=y")
21885         (vec_merge:V8QI
21886          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21887                           (parallel [(const_int 0)
21888                                      (const_int 4)
21889                                      (const_int 1)
21890                                      (const_int 5)
21891                                      (const_int 2)
21892                                      (const_int 6)
21893                                      (const_int 3)
21894                                      (const_int 7)]))
21895          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21896                           (parallel [(const_int 4)
21897                                      (const_int 0)
21898                                      (const_int 5)
21899                                      (const_int 1)
21900                                      (const_int 6)
21901                                      (const_int 2)
21902                                      (const_int 7)
21903                                      (const_int 3)]))
21904          (const_int 85)))]
21905   "TARGET_MMX"
21906   "punpcklbw\t{%2, %0|%0, %2}"
21907   [(set_attr "type" "mmxcvt")
21908    (set_attr "mode" "DI")])
21909
21910 (define_insn "mmx_punpcklwd"
21911   [(set (match_operand:V4HI 0 "register_operand" "=y")
21912         (vec_merge:V4HI
21913          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21914                           (parallel [(const_int 2)
21915                                      (const_int 0)
21916                                      (const_int 3)
21917                                      (const_int 1)]))
21918          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21919                           (parallel [(const_int 0)
21920                                      (const_int 2)
21921                                      (const_int 1)
21922                                      (const_int 3)]))
21923          (const_int 5)))]
21924   "TARGET_MMX"
21925   "punpcklwd\t{%2, %0|%0, %2}"
21926   [(set_attr "type" "mmxcvt")
21927    (set_attr "mode" "DI")])
21928
21929 (define_insn "mmx_punpckldq"
21930   [(set (match_operand:V2SI 0 "register_operand" "=y")
21931         (vec_merge:V2SI
21932          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
21933                            (parallel [(const_int 1)
21934                                       (const_int 0)]))
21935          (match_operand:V2SI 2 "register_operand" "y")
21936          (const_int 1)))]
21937   "TARGET_MMX"
21938   "punpckldq\t{%2, %0|%0, %2}"
21939   [(set_attr "type" "mmxcvt")
21940    (set_attr "mode" "DI")])
21941
21942
21943 ;; Miscellaneous stuff
21944
21945 (define_insn "emms"
21946   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
21947    (clobber (reg:XF 8))
21948    (clobber (reg:XF 9))
21949    (clobber (reg:XF 10))
21950    (clobber (reg:XF 11))
21951    (clobber (reg:XF 12))
21952    (clobber (reg:XF 13))
21953    (clobber (reg:XF 14))
21954    (clobber (reg:XF 15))
21955    (clobber (reg:DI 29))
21956    (clobber (reg:DI 30))
21957    (clobber (reg:DI 31))
21958    (clobber (reg:DI 32))
21959    (clobber (reg:DI 33))
21960    (clobber (reg:DI 34))
21961    (clobber (reg:DI 35))
21962    (clobber (reg:DI 36))]
21963   "TARGET_MMX"
21964   "emms"
21965   [(set_attr "type" "mmx")
21966    (set_attr "memory" "unknown")])
21967
21968 (define_insn "ldmxcsr"
21969   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
21970                     UNSPECV_LDMXCSR)]
21971   "TARGET_SSE"
21972   "ldmxcsr\t%0"
21973   [(set_attr "type" "sse")
21974    (set_attr "memory" "load")])
21975
21976 (define_insn "stmxcsr"
21977   [(set (match_operand:SI 0 "memory_operand" "=m")
21978         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21979   "TARGET_SSE"
21980   "stmxcsr\t%0"
21981   [(set_attr "type" "sse")
21982    (set_attr "memory" "store")])
21983
21984 (define_expand "sfence"
21985   [(set (match_dup 0)
21986         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21987   "TARGET_SSE || TARGET_3DNOW_A"
21988 {
21989   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21990   MEM_VOLATILE_P (operands[0]) = 1;
21991 })
21992
21993 (define_insn "*sfence_insn"
21994   [(set (match_operand:BLK 0 "" "")
21995         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21996   "TARGET_SSE || TARGET_3DNOW_A"
21997   "sfence"
21998   [(set_attr "type" "sse")
21999    (set_attr "memory" "unknown")])
22000
22001 (define_expand "sse_prologue_save"
22002   [(parallel [(set (match_operand:BLK 0 "" "")
22003                    (unspec:BLK [(reg:DI 21)
22004                                 (reg:DI 22)
22005                                 (reg:DI 23)
22006                                 (reg:DI 24)
22007                                 (reg:DI 25)
22008                                 (reg:DI 26)
22009                                 (reg:DI 27)
22010                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22011               (use (match_operand:DI 1 "register_operand" ""))
22012               (use (match_operand:DI 2 "immediate_operand" ""))
22013               (use (label_ref:DI (match_operand 3 "" "")))])]
22014   "TARGET_64BIT"
22015   "")
22016
22017 (define_insn "*sse_prologue_save_insn"
22018   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22019                           (match_operand:DI 4 "const_int_operand" "n")))
22020         (unspec:BLK [(reg:DI 21)
22021                      (reg:DI 22)
22022                      (reg:DI 23)
22023                      (reg:DI 24)
22024                      (reg:DI 25)
22025                      (reg:DI 26)
22026                      (reg:DI 27)
22027                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22028    (use (match_operand:DI 1 "register_operand" "r"))
22029    (use (match_operand:DI 2 "const_int_operand" "i"))
22030    (use (label_ref:DI (match_operand 3 "" "X")))]
22031   "TARGET_64BIT
22032    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
22033    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22034   "*
22035 {
22036   int i;
22037   operands[0] = gen_rtx_MEM (Pmode,
22038                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22039   output_asm_insn (\"jmp\\t%A1\", operands);
22040   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22041     {
22042       operands[4] = adjust_address (operands[0], DImode, i*16);
22043       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22044       PUT_MODE (operands[4], TImode);
22045       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22046         output_asm_insn (\"rex\", operands);
22047       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
22048     }
22049   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
22050                              CODE_LABEL_NUMBER (operands[3]));
22051   RET;
22052 }
22053   "
22054   [(set_attr "type" "other")
22055    (set_attr "length_immediate" "0")
22056    (set_attr "length_address" "0")
22057    (set_attr "length" "135")
22058    (set_attr "memory" "store")
22059    (set_attr "modrm" "0")
22060    (set_attr "mode" "DI")])
22061
22062 ;; 3Dnow! instructions
22063
22064 (define_insn "addv2sf3"
22065   [(set (match_operand:V2SF 0 "register_operand" "=y")
22066         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22067                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22068   "TARGET_3DNOW"
22069   "pfadd\\t{%2, %0|%0, %2}"
22070   [(set_attr "type" "mmxadd")
22071    (set_attr "mode" "V2SF")])
22072
22073 (define_insn "subv2sf3"
22074   [(set (match_operand:V2SF 0 "register_operand" "=y")
22075         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22076                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22077   "TARGET_3DNOW"
22078   "pfsub\\t{%2, %0|%0, %2}"
22079   [(set_attr "type" "mmxadd")
22080    (set_attr "mode" "V2SF")])
22081
22082 (define_insn "subrv2sf3"
22083   [(set (match_operand:V2SF 0 "register_operand" "=y")
22084         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
22085                     (match_operand:V2SF 1 "register_operand" "0")))]
22086   "TARGET_3DNOW"
22087   "pfsubr\\t{%2, %0|%0, %2}"
22088   [(set_attr "type" "mmxadd")
22089    (set_attr "mode" "V2SF")])
22090
22091 (define_insn "gtv2sf3"
22092   [(set (match_operand:V2SI 0 "register_operand" "=y")
22093         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
22094                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22095  "TARGET_3DNOW"
22096   "pfcmpgt\\t{%2, %0|%0, %2}"
22097   [(set_attr "type" "mmxcmp")
22098    (set_attr "mode" "V2SF")])
22099
22100 (define_insn "gev2sf3"
22101   [(set (match_operand:V2SI 0 "register_operand" "=y")
22102         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
22103                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22104   "TARGET_3DNOW"
22105   "pfcmpge\\t{%2, %0|%0, %2}"
22106   [(set_attr "type" "mmxcmp")
22107    (set_attr "mode" "V2SF")])
22108
22109 (define_insn "eqv2sf3"
22110   [(set (match_operand:V2SI 0 "register_operand" "=y")
22111         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
22112                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22113   "TARGET_3DNOW"
22114   "pfcmpeq\\t{%2, %0|%0, %2}"
22115   [(set_attr "type" "mmxcmp")
22116    (set_attr "mode" "V2SF")])
22117
22118 (define_insn "pfmaxv2sf3"
22119   [(set (match_operand:V2SF 0 "register_operand" "=y")
22120         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
22121                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22122   "TARGET_3DNOW"
22123   "pfmax\\t{%2, %0|%0, %2}"
22124   [(set_attr "type" "mmxadd")
22125    (set_attr "mode" "V2SF")])
22126
22127 (define_insn "pfminv2sf3"
22128   [(set (match_operand:V2SF 0 "register_operand" "=y")
22129         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
22130                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22131   "TARGET_3DNOW"
22132   "pfmin\\t{%2, %0|%0, %2}"
22133   [(set_attr "type" "mmxadd")
22134    (set_attr "mode" "V2SF")])
22135
22136 (define_insn "mulv2sf3"
22137   [(set (match_operand:V2SF 0 "register_operand" "=y")
22138         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
22139                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22140   "TARGET_3DNOW"
22141   "pfmul\\t{%2, %0|%0, %2}"
22142   [(set_attr "type" "mmxmul")
22143    (set_attr "mode" "V2SF")])
22144
22145 (define_insn "femms"
22146   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
22147    (clobber (reg:XF 8))
22148    (clobber (reg:XF 9))
22149    (clobber (reg:XF 10))
22150    (clobber (reg:XF 11))
22151    (clobber (reg:XF 12))
22152    (clobber (reg:XF 13))
22153    (clobber (reg:XF 14))
22154    (clobber (reg:XF 15))
22155    (clobber (reg:DI 29))
22156    (clobber (reg:DI 30))
22157    (clobber (reg:DI 31))
22158    (clobber (reg:DI 32))
22159    (clobber (reg:DI 33))
22160    (clobber (reg:DI 34))
22161    (clobber (reg:DI 35))
22162    (clobber (reg:DI 36))]
22163   "TARGET_3DNOW"
22164   "femms"
22165   [(set_attr "type" "mmx")
22166    (set_attr "memory" "none")]) 
22167
22168 (define_insn "pf2id"
22169   [(set (match_operand:V2SI 0 "register_operand" "=y")
22170         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
22171   "TARGET_3DNOW"
22172   "pf2id\\t{%1, %0|%0, %1}"
22173   [(set_attr "type" "mmxcvt")
22174    (set_attr "mode" "V2SF")])
22175
22176 (define_insn "pf2iw"
22177   [(set (match_operand:V2SI 0 "register_operand" "=y")
22178         (sign_extend:V2SI
22179            (ss_truncate:V2HI
22180               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22181   "TARGET_3DNOW_A"
22182   "pf2iw\\t{%1, %0|%0, %1}"
22183   [(set_attr "type" "mmxcvt")
22184    (set_attr "mode" "V2SF")])
22185
22186 (define_insn "pfacc"
22187   [(set (match_operand:V2SF 0 "register_operand" "=y")
22188         (vec_concat:V2SF
22189            (plus:SF
22190               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22191                              (parallel [(const_int  0)]))
22192               (vec_select:SF (match_dup 1)
22193                              (parallel [(const_int 1)])))
22194            (plus:SF
22195               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22196                              (parallel [(const_int  0)]))
22197               (vec_select:SF (match_dup 2)
22198                              (parallel [(const_int 1)])))))]
22199   "TARGET_3DNOW"
22200   "pfacc\\t{%2, %0|%0, %2}"
22201   [(set_attr "type" "mmxadd")
22202    (set_attr "mode" "V2SF")])
22203
22204 (define_insn "pfnacc"
22205   [(set (match_operand:V2SF 0 "register_operand" "=y")
22206         (vec_concat:V2SF
22207            (minus:SF
22208               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22209                              (parallel [(const_int 0)]))
22210               (vec_select:SF (match_dup 1)
22211                              (parallel [(const_int 1)])))
22212            (minus:SF
22213               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22214                              (parallel [(const_int  0)]))
22215               (vec_select:SF (match_dup 2)
22216                              (parallel [(const_int 1)])))))]
22217   "TARGET_3DNOW_A"
22218   "pfnacc\\t{%2, %0|%0, %2}"
22219   [(set_attr "type" "mmxadd")
22220    (set_attr "mode" "V2SF")])
22221
22222 (define_insn "pfpnacc"
22223   [(set (match_operand:V2SF 0 "register_operand" "=y")
22224         (vec_concat:V2SF
22225            (minus:SF
22226               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22227                              (parallel [(const_int 0)]))
22228               (vec_select:SF (match_dup 1)
22229                              (parallel [(const_int 1)])))
22230            (plus:SF
22231               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22232                              (parallel [(const_int 0)]))
22233               (vec_select:SF (match_dup 2)
22234                              (parallel [(const_int 1)])))))]
22235   "TARGET_3DNOW_A"
22236   "pfpnacc\\t{%2, %0|%0, %2}"
22237   [(set_attr "type" "mmxadd")
22238    (set_attr "mode" "V2SF")])
22239
22240 (define_insn "pi2fw"
22241   [(set (match_operand:V2SF 0 "register_operand" "=y")
22242         (float:V2SF
22243            (vec_concat:V2SI
22244               (sign_extend:SI
22245                  (truncate:HI
22246                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22247                                    (parallel [(const_int 0)]))))
22248               (sign_extend:SI
22249                  (truncate:HI
22250                     (vec_select:SI (match_dup 1)
22251                                    (parallel [(const_int  1)])))))))]
22252   "TARGET_3DNOW_A"
22253   "pi2fw\\t{%1, %0|%0, %1}"
22254   [(set_attr "type" "mmxcvt")
22255    (set_attr "mode" "V2SF")])
22256
22257 (define_insn "floatv2si2"
22258   [(set (match_operand:V2SF 0 "register_operand" "=y")
22259         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22260   "TARGET_3DNOW"
22261   "pi2fd\\t{%1, %0|%0, %1}"
22262   [(set_attr "type" "mmxcvt")
22263    (set_attr "mode" "V2SF")])
22264
22265 ;; This insn is identical to pavgb in operation, but the opcode is
22266 ;; different.  To avoid accidentally matching pavgb, use an unspec.
22267
22268 (define_insn "pavgusb"
22269  [(set (match_operand:V8QI 0 "register_operand" "=y")
22270        (unspec:V8QI
22271           [(match_operand:V8QI 1 "register_operand" "0")
22272            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22273           UNSPEC_PAVGUSB))]
22274   "TARGET_3DNOW"
22275   "pavgusb\\t{%2, %0|%0, %2}"
22276   [(set_attr "type" "mmxshft")
22277    (set_attr "mode" "TI")])
22278
22279 ;; 3DNow reciprocal and sqrt
22280  
22281 (define_insn "pfrcpv2sf2"
22282   [(set (match_operand:V2SF 0 "register_operand" "=y")
22283         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22284         UNSPEC_PFRCP))]
22285   "TARGET_3DNOW"
22286   "pfrcp\\t{%1, %0|%0, %1}"
22287   [(set_attr "type" "mmx")
22288    (set_attr "mode" "TI")])
22289
22290 (define_insn "pfrcpit1v2sf3"
22291   [(set (match_operand:V2SF 0 "register_operand" "=y")
22292         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22293                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22294                      UNSPEC_PFRCPIT1))]
22295   "TARGET_3DNOW"
22296   "pfrcpit1\\t{%2, %0|%0, %2}"
22297   [(set_attr "type" "mmx")
22298    (set_attr "mode" "TI")])
22299
22300 (define_insn "pfrcpit2v2sf3"
22301   [(set (match_operand:V2SF 0 "register_operand" "=y")
22302         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22303                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22304                      UNSPEC_PFRCPIT2))]
22305   "TARGET_3DNOW"
22306   "pfrcpit2\\t{%2, %0|%0, %2}"
22307   [(set_attr "type" "mmx")
22308    (set_attr "mode" "TI")])
22309
22310 (define_insn "pfrsqrtv2sf2"
22311   [(set (match_operand:V2SF 0 "register_operand" "=y")
22312         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22313                      UNSPEC_PFRSQRT))]
22314   "TARGET_3DNOW"
22315   "pfrsqrt\\t{%1, %0|%0, %1}"
22316   [(set_attr "type" "mmx")
22317    (set_attr "mode" "TI")])
22318                 
22319 (define_insn "pfrsqit1v2sf3"
22320   [(set (match_operand:V2SF 0 "register_operand" "=y")
22321         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22322                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22323                      UNSPEC_PFRSQIT1))]
22324   "TARGET_3DNOW"
22325   "pfrsqit1\\t{%2, %0|%0, %2}"
22326   [(set_attr "type" "mmx")
22327    (set_attr "mode" "TI")])
22328
22329 (define_insn "pmulhrwv4hi3"
22330   [(set (match_operand:V4HI 0 "register_operand" "=y")
22331         (truncate:V4HI
22332            (lshiftrt:V4SI
22333               (plus:V4SI
22334                  (mult:V4SI
22335                     (sign_extend:V4SI
22336                        (match_operand:V4HI 1 "register_operand" "0"))
22337                     (sign_extend:V4SI
22338                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22339                  (const_vector:V4SI [(const_int 32768)
22340                                      (const_int 32768)
22341                                      (const_int 32768)
22342                                      (const_int 32768)]))
22343               (const_int 16))))]
22344   "TARGET_3DNOW"
22345   "pmulhrw\\t{%2, %0|%0, %2}"
22346   [(set_attr "type" "mmxmul")
22347    (set_attr "mode" "TI")])
22348
22349 (define_insn "pswapdv2si2"
22350   [(set (match_operand:V2SI 0 "register_operand" "=y")
22351         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22352                          (parallel [(const_int 1) (const_int 0)])))]
22353   "TARGET_3DNOW_A"
22354   "pswapd\\t{%1, %0|%0, %1}"
22355   [(set_attr "type" "mmxcvt")
22356    (set_attr "mode" "TI")])
22357
22358 (define_insn "pswapdv2sf2"
22359   [(set (match_operand:V2SF 0 "register_operand" "=y")
22360         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22361                          (parallel [(const_int 1) (const_int 0)])))]
22362   "TARGET_3DNOW_A"
22363   "pswapd\\t{%1, %0|%0, %1}"
22364   [(set_attr "type" "mmxcvt")
22365    (set_attr "mode" "TI")])
22366
22367 (define_expand "prefetch"
22368   [(prefetch (match_operand 0 "address_operand" "")
22369              (match_operand:SI 1 "const_int_operand" "")
22370              (match_operand:SI 2 "const_int_operand" ""))]
22371   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22372 {
22373   int rw = INTVAL (operands[1]);
22374   int locality = INTVAL (operands[2]);
22375
22376   if (rw != 0 && rw != 1)
22377     abort ();
22378   if (locality < 0 || locality > 3)
22379     abort ();
22380   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22381     abort ();
22382
22383   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22384      suported by SSE counterpart or the SSE prefetch is not available
22385      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22386      of locality.  */
22387   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22388     operands[2] = GEN_INT (3);
22389   else
22390     operands[1] = const0_rtx;
22391 })
22392
22393 (define_insn "*prefetch_sse"
22394   [(prefetch (match_operand:SI 0 "address_operand" "p")
22395              (const_int 0)
22396              (match_operand:SI 1 "const_int_operand" ""))]
22397   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22398 {
22399   static const char * const patterns[4] = {
22400    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22401   };
22402
22403   int locality = INTVAL (operands[1]);
22404   if (locality < 0 || locality > 3)
22405     abort ();
22406
22407   return patterns[locality];  
22408 }
22409   [(set_attr "type" "sse")
22410    (set_attr "memory" "none")])
22411
22412 (define_insn "*prefetch_sse_rex"
22413   [(prefetch (match_operand:DI 0 "address_operand" "p")
22414              (const_int 0)
22415              (match_operand:SI 1 "const_int_operand" ""))]
22416   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22417 {
22418   static const char * const patterns[4] = {
22419    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22420   };
22421
22422   int locality = INTVAL (operands[1]);
22423   if (locality < 0 || locality > 3)
22424     abort ();
22425
22426   return patterns[locality];  
22427 }
22428   [(set_attr "type" "sse")
22429    (set_attr "memory" "none")])
22430
22431 (define_insn "*prefetch_3dnow"
22432   [(prefetch (match_operand:SI 0 "address_operand" "p")
22433              (match_operand:SI 1 "const_int_operand" "n")
22434              (const_int 3))]
22435   "TARGET_3DNOW && !TARGET_64BIT"
22436 {
22437   if (INTVAL (operands[1]) == 0)
22438     return "prefetch\t%a0";
22439   else
22440     return "prefetchw\t%a0";
22441 }
22442   [(set_attr "type" "mmx")
22443    (set_attr "memory" "none")])
22444
22445 (define_insn "*prefetch_3dnow_rex"
22446   [(prefetch (match_operand:DI 0 "address_operand" "p")
22447              (match_operand:SI 1 "const_int_operand" "n")
22448              (const_int 3))]
22449   "TARGET_3DNOW && TARGET_64BIT"
22450 {
22451   if (INTVAL (operands[1]) == 0)
22452     return "prefetch\t%a0";
22453   else
22454     return "prefetchw\t%a0";
22455 }
22456   [(set_attr "type" "mmx")
22457    (set_attr "memory" "none")])
22458
22459 ;; SSE2 support
22460
22461 (define_insn "addv2df3"
22462   [(set (match_operand:V2DF 0 "register_operand" "=x")
22463         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22464                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22465   "TARGET_SSE2"
22466   "addpd\t{%2, %0|%0, %2}"
22467   [(set_attr "type" "sseadd")
22468    (set_attr "mode" "V2DF")])
22469
22470 (define_insn "vmaddv2df3"
22471   [(set (match_operand:V2DF 0 "register_operand" "=x")
22472         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22473                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22474                         (match_dup 1)
22475                         (const_int 1)))]
22476   "TARGET_SSE2"
22477   "addsd\t{%2, %0|%0, %2}"
22478   [(set_attr "type" "sseadd")
22479    (set_attr "mode" "DF")])
22480
22481 (define_insn "subv2df3"
22482   [(set (match_operand:V2DF 0 "register_operand" "=x")
22483         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22484                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22485   "TARGET_SSE2"
22486   "subpd\t{%2, %0|%0, %2}"
22487   [(set_attr "type" "sseadd")
22488    (set_attr "mode" "V2DF")])
22489
22490 (define_insn "vmsubv2df3"
22491   [(set (match_operand:V2DF 0 "register_operand" "=x")
22492         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22493                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22494                         (match_dup 1)
22495                         (const_int 1)))]
22496   "TARGET_SSE2"
22497   "subsd\t{%2, %0|%0, %2}"
22498   [(set_attr "type" "sseadd")
22499    (set_attr "mode" "DF")])
22500
22501 (define_insn "mulv2df3"
22502   [(set (match_operand:V2DF 0 "register_operand" "=x")
22503         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22504                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22505   "TARGET_SSE2"
22506   "mulpd\t{%2, %0|%0, %2}"
22507   [(set_attr "type" "ssemul")
22508    (set_attr "mode" "V2DF")])
22509
22510 (define_insn "vmmulv2df3"
22511   [(set (match_operand:V2DF 0 "register_operand" "=x")
22512         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22513                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22514                         (match_dup 1)
22515                         (const_int 1)))]
22516   "TARGET_SSE2"
22517   "mulsd\t{%2, %0|%0, %2}"
22518   [(set_attr "type" "ssemul")
22519    (set_attr "mode" "DF")])
22520
22521 (define_insn "divv2df3"
22522   [(set (match_operand:V2DF 0 "register_operand" "=x")
22523         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22524                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22525   "TARGET_SSE2"
22526   "divpd\t{%2, %0|%0, %2}"
22527   [(set_attr "type" "ssediv")
22528    (set_attr "mode" "V2DF")])
22529
22530 (define_insn "vmdivv2df3"
22531   [(set (match_operand:V2DF 0 "register_operand" "=x")
22532         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22533                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22534                         (match_dup 1)
22535                         (const_int 1)))]
22536   "TARGET_SSE2"
22537   "divsd\t{%2, %0|%0, %2}"
22538   [(set_attr "type" "ssediv")
22539    (set_attr "mode" "DF")])
22540
22541 ;; SSE min/max
22542
22543 (define_insn "smaxv2df3"
22544   [(set (match_operand:V2DF 0 "register_operand" "=x")
22545         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22546                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22547   "TARGET_SSE2"
22548   "maxpd\t{%2, %0|%0, %2}"
22549   [(set_attr "type" "sseadd")
22550    (set_attr "mode" "V2DF")])
22551
22552 (define_insn "vmsmaxv2df3"
22553   [(set (match_operand:V2DF 0 "register_operand" "=x")
22554         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22555                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22556                         (match_dup 1)
22557                         (const_int 1)))]
22558   "TARGET_SSE2"
22559   "maxsd\t{%2, %0|%0, %2}"
22560   [(set_attr "type" "sseadd")
22561    (set_attr "mode" "DF")])
22562
22563 (define_insn "sminv2df3"
22564   [(set (match_operand:V2DF 0 "register_operand" "=x")
22565         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22566                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22567   "TARGET_SSE2"
22568   "minpd\t{%2, %0|%0, %2}"
22569   [(set_attr "type" "sseadd")
22570    (set_attr "mode" "V2DF")])
22571
22572 (define_insn "vmsminv2df3"
22573   [(set (match_operand:V2DF 0 "register_operand" "=x")
22574         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22575                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22576                         (match_dup 1)
22577                         (const_int 1)))]
22578   "TARGET_SSE2"
22579   "minsd\t{%2, %0|%0, %2}"
22580   [(set_attr "type" "sseadd")
22581    (set_attr "mode" "DF")])
22582 ;; SSE2 square root.  There doesn't appear to be an extension for the
22583 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22584
22585 (define_insn "sqrtv2df2"
22586   [(set (match_operand:V2DF 0 "register_operand" "=x")
22587         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22588   "TARGET_SSE2"
22589   "sqrtpd\t{%1, %0|%0, %1}"
22590   [(set_attr "type" "sse")
22591    (set_attr "mode" "V2DF")])
22592
22593 (define_insn "vmsqrtv2df2"
22594   [(set (match_operand:V2DF 0 "register_operand" "=x")
22595         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22596                         (match_operand:V2DF 2 "register_operand" "0")
22597                         (const_int 1)))]
22598   "TARGET_SSE2"
22599   "sqrtsd\t{%1, %0|%0, %1}"
22600   [(set_attr "type" "sse")
22601    (set_attr "mode" "SF")])
22602
22603 ;; SSE mask-generating compares
22604
22605 (define_insn "maskcmpv2df3"
22606   [(set (match_operand:V2DI 0 "register_operand" "=x")
22607         (match_operator:V2DI 3 "sse_comparison_operator"
22608                              [(match_operand:V2DF 1 "register_operand" "0")
22609                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22610   "TARGET_SSE2"
22611   "cmp%D3pd\t{%2, %0|%0, %2}"
22612   [(set_attr "type" "ssecmp")
22613    (set_attr "mode" "V2DF")])
22614
22615 (define_insn "maskncmpv2df3"
22616   [(set (match_operand:V2DI 0 "register_operand" "=x")
22617         (not:V2DI
22618          (match_operator:V2DI 3 "sse_comparison_operator"
22619                               [(match_operand:V2DF 1 "register_operand" "0")
22620                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22621   "TARGET_SSE2"
22622 {
22623   if (GET_CODE (operands[3]) == UNORDERED)
22624     return "cmpordps\t{%2, %0|%0, %2}";
22625   else
22626     return "cmpn%D3pd\t{%2, %0|%0, %2}";
22627 }
22628   [(set_attr "type" "ssecmp")
22629    (set_attr "mode" "V2DF")])
22630
22631 (define_insn "vmmaskcmpv2df3"
22632   [(set (match_operand:V2DI 0 "register_operand" "=x")
22633         (vec_merge:V2DI
22634          (match_operator:V2DI 3 "sse_comparison_operator"
22635                               [(match_operand:V2DF 1 "register_operand" "0")
22636                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22637          (subreg:V2DI (match_dup 1) 0)
22638          (const_int 1)))]
22639   "TARGET_SSE2"
22640   "cmp%D3sd\t{%2, %0|%0, %2}"
22641   [(set_attr "type" "ssecmp")
22642    (set_attr "mode" "DF")])
22643
22644 (define_insn "vmmaskncmpv2df3"
22645   [(set (match_operand:V2DI 0 "register_operand" "=x")
22646         (vec_merge:V2DI
22647          (not:V2DI
22648           (match_operator:V2DI 3 "sse_comparison_operator"
22649                                [(match_operand:V2DF 1 "register_operand" "0")
22650                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22651          (subreg:V2DI (match_dup 1) 0)
22652          (const_int 1)))]
22653   "TARGET_SSE2"
22654 {
22655   if (GET_CODE (operands[3]) == UNORDERED)
22656     return "cmpordsd\t{%2, %0|%0, %2}";
22657   else
22658     return "cmpn%D3sd\t{%2, %0|%0, %2}";
22659 }
22660   [(set_attr "type" "ssecmp")
22661    (set_attr "mode" "DF")])
22662
22663 (define_insn "sse2_comi"
22664   [(set (reg:CCFP FLAGS_REG)
22665         (compare:CCFP (vec_select:DF
22666                        (match_operand:V2DF 0 "register_operand" "x")
22667                        (parallel [(const_int 0)]))
22668                       (vec_select:DF
22669                        (match_operand:V2DF 1 "register_operand" "x")
22670                        (parallel [(const_int 0)]))))]
22671   "TARGET_SSE2"
22672   "comisd\t{%1, %0|%0, %1}"
22673   [(set_attr "type" "ssecomi")
22674    (set_attr "mode" "DF")])
22675
22676 (define_insn "sse2_ucomi"
22677   [(set (reg:CCFPU FLAGS_REG)
22678         (compare:CCFPU (vec_select:DF
22679                          (match_operand:V2DF 0 "register_operand" "x")
22680                          (parallel [(const_int 0)]))
22681                         (vec_select:DF
22682                          (match_operand:V2DF 1 "register_operand" "x")
22683                          (parallel [(const_int 0)]))))]
22684   "TARGET_SSE2"
22685   "ucomisd\t{%1, %0|%0, %1}"
22686   [(set_attr "type" "ssecomi")
22687    (set_attr "mode" "DF")])
22688
22689 ;; SSE Strange Moves.
22690
22691 (define_insn "sse2_movmskpd"
22692   [(set (match_operand:SI 0 "register_operand" "=r")
22693         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22694                    UNSPEC_MOVMSK))]
22695   "TARGET_SSE2"
22696   "movmskpd\t{%1, %0|%0, %1}"
22697   [(set_attr "type" "ssecvt")
22698    (set_attr "mode" "V2DF")])
22699
22700 (define_insn "sse2_pmovmskb"
22701   [(set (match_operand:SI 0 "register_operand" "=r")
22702         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22703                    UNSPEC_MOVMSK))]
22704   "TARGET_SSE2"
22705   "pmovmskb\t{%1, %0|%0, %1}"
22706   [(set_attr "type" "ssecvt")
22707    (set_attr "mode" "V2DF")])
22708
22709 (define_insn "sse2_maskmovdqu"
22710   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22711         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22712                        (match_operand:V16QI 2 "register_operand" "x")]
22713                       UNSPEC_MASKMOV))]
22714   "TARGET_SSE2"
22715   ;; @@@ check ordering of operands in intel/nonintel syntax
22716   "maskmovdqu\t{%2, %1|%1, %2}"
22717   [(set_attr "type" "ssecvt")
22718    (set_attr "mode" "TI")])
22719
22720 (define_insn "sse2_maskmovdqu_rex64"
22721   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22722         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22723                        (match_operand:V16QI 2 "register_operand" "x")]
22724                       UNSPEC_MASKMOV))]
22725   "TARGET_SSE2"
22726   ;; @@@ check ordering of operands in intel/nonintel syntax
22727   "maskmovdqu\t{%2, %1|%1, %2}"
22728   [(set_attr "type" "ssecvt")
22729    (set_attr "mode" "TI")])
22730
22731 (define_insn "sse2_movntv2df"
22732   [(set (match_operand:V2DF 0 "memory_operand" "=m")
22733         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22734                      UNSPEC_MOVNT))]
22735   "TARGET_SSE2"
22736   "movntpd\t{%1, %0|%0, %1}"
22737   [(set_attr "type" "ssecvt")
22738    (set_attr "mode" "V2DF")])
22739
22740 (define_insn "sse2_movntv2di"
22741   [(set (match_operand:V2DI 0 "memory_operand" "=m")
22742         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22743                      UNSPEC_MOVNT))]
22744   "TARGET_SSE2"
22745   "movntdq\t{%1, %0|%0, %1}"
22746   [(set_attr "type" "ssecvt")
22747    (set_attr "mode" "TI")])
22748
22749 (define_insn "sse2_movntsi"
22750   [(set (match_operand:SI 0 "memory_operand" "=m")
22751         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22752                    UNSPEC_MOVNT))]
22753   "TARGET_SSE2"
22754   "movnti\t{%1, %0|%0, %1}"
22755   [(set_attr "type" "ssecvt")
22756    (set_attr "mode" "V2DF")])
22757
22758 ;; SSE <-> integer/MMX conversions
22759
22760 ;; Conversions between SI and SF
22761
22762 (define_insn "cvtdq2ps"
22763   [(set (match_operand:V4SF 0 "register_operand" "=x")
22764         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22765   "TARGET_SSE2"
22766   "cvtdq2ps\t{%1, %0|%0, %1}"
22767   [(set_attr "type" "ssecvt")
22768    (set_attr "mode" "V2DF")])
22769
22770 (define_insn "cvtps2dq"
22771   [(set (match_operand:V4SI 0 "register_operand" "=x")
22772         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22773   "TARGET_SSE2"
22774   "cvtps2dq\t{%1, %0|%0, %1}"
22775   [(set_attr "type" "ssecvt")
22776    (set_attr "mode" "TI")])
22777
22778 (define_insn "cvttps2dq"
22779   [(set (match_operand:V4SI 0 "register_operand" "=x")
22780         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22781                      UNSPEC_FIX))]
22782   "TARGET_SSE2"
22783   "cvttps2dq\t{%1, %0|%0, %1}"
22784   [(set_attr "type" "ssecvt")
22785    (set_attr "mode" "TI")])
22786
22787 ;; Conversions between SI and DF
22788
22789 (define_insn "cvtdq2pd"
22790   [(set (match_operand:V2DF 0 "register_operand" "=x")
22791         (float:V2DF (vec_select:V2SI
22792                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22793                      (parallel
22794                       [(const_int 0)
22795                        (const_int 1)]))))]
22796   "TARGET_SSE2"
22797   "cvtdq2pd\t{%1, %0|%0, %1}"
22798   [(set_attr "type" "ssecvt")
22799    (set_attr "mode" "V2DF")])
22800
22801 (define_insn "cvtpd2dq"
22802   [(set (match_operand:V4SI 0 "register_operand" "=x")
22803         (vec_concat:V4SI
22804          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22805          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22806   "TARGET_SSE2"
22807   "cvtpd2dq\t{%1, %0|%0, %1}"
22808   [(set_attr "type" "ssecvt")
22809    (set_attr "mode" "TI")])
22810
22811 (define_insn "cvttpd2dq"
22812   [(set (match_operand:V4SI 0 "register_operand" "=x")
22813         (vec_concat:V4SI
22814          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22815                       UNSPEC_FIX)
22816          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22817   "TARGET_SSE2"
22818   "cvttpd2dq\t{%1, %0|%0, %1}"
22819   [(set_attr "type" "ssecvt")
22820    (set_attr "mode" "TI")])
22821
22822 (define_insn "cvtpd2pi"
22823   [(set (match_operand:V2SI 0 "register_operand" "=y")
22824         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22825   "TARGET_SSE2"
22826   "cvtpd2pi\t{%1, %0|%0, %1}"
22827   [(set_attr "type" "ssecvt")
22828    (set_attr "mode" "TI")])
22829
22830 (define_insn "cvttpd2pi"
22831   [(set (match_operand:V2SI 0 "register_operand" "=y")
22832         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22833                      UNSPEC_FIX))]
22834   "TARGET_SSE2"
22835   "cvttpd2pi\t{%1, %0|%0, %1}"
22836   [(set_attr "type" "ssecvt")
22837    (set_attr "mode" "TI")])
22838
22839 (define_insn "cvtpi2pd"
22840   [(set (match_operand:V2DF 0 "register_operand" "=x")
22841         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22842   "TARGET_SSE2"
22843   "cvtpi2pd\t{%1, %0|%0, %1}"
22844   [(set_attr "type" "ssecvt")
22845    (set_attr "mode" "TI")])
22846
22847 ;; Conversions between SI and DF
22848
22849 (define_insn "cvtsd2si"
22850   [(set (match_operand:SI 0 "register_operand" "=r,r")
22851         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22852                                (parallel [(const_int 0)]))))]
22853   "TARGET_SSE2"
22854   "cvtsd2si\t{%1, %0|%0, %1}"
22855   [(set_attr "type" "sseicvt")
22856    (set_attr "athlon_decode" "double,vector")
22857    (set_attr "mode" "SI")])
22858
22859 (define_insn "cvtsd2siq"
22860   [(set (match_operand:DI 0 "register_operand" "=r,r")
22861         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22862                                (parallel [(const_int 0)]))))]
22863   "TARGET_SSE2 && TARGET_64BIT"
22864   "cvtsd2siq\t{%1, %0|%0, %1}"
22865   [(set_attr "type" "sseicvt")
22866    (set_attr "athlon_decode" "double,vector")
22867    (set_attr "mode" "DI")])
22868
22869 (define_insn "cvttsd2si"
22870   [(set (match_operand:SI 0 "register_operand" "=r,r")
22871         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22872                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22873   "TARGET_SSE2"
22874   "cvttsd2si\t{%1, %0|%0, %1}"
22875   [(set_attr "type" "sseicvt")
22876    (set_attr "mode" "SI")
22877    (set_attr "athlon_decode" "double,vector")])
22878
22879 (define_insn "cvttsd2siq"
22880   [(set (match_operand:DI 0 "register_operand" "=r,r")
22881         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22882                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22883   "TARGET_SSE2 && TARGET_64BIT"
22884   "cvttsd2siq\t{%1, %0|%0, %1}"
22885   [(set_attr "type" "sseicvt")
22886    (set_attr "mode" "DI")
22887    (set_attr "athlon_decode" "double,vector")])
22888
22889 (define_insn "cvtsi2sd"
22890   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22891         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22892                         (vec_duplicate:V2DF
22893                           (float:DF
22894                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22895                         (const_int 2)))]
22896   "TARGET_SSE2"
22897   "cvtsi2sd\t{%2, %0|%0, %2}"
22898   [(set_attr "type" "sseicvt")
22899    (set_attr "mode" "DF")
22900    (set_attr "athlon_decode" "double,direct")])
22901
22902 (define_insn "cvtsi2sdq"
22903   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22904         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22905                         (vec_duplicate:V2DF
22906                           (float:DF
22907                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22908                         (const_int 2)))]
22909   "TARGET_SSE2 && TARGET_64BIT"
22910   "cvtsi2sdq\t{%2, %0|%0, %2}"
22911   [(set_attr "type" "sseicvt")
22912    (set_attr "mode" "DF")
22913    (set_attr "athlon_decode" "double,direct")])
22914
22915 ;; Conversions between SF and DF
22916
22917 (define_insn "cvtsd2ss"
22918   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22919         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22920                         (vec_duplicate:V4SF
22921                           (float_truncate:V2SF
22922                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22923                         (const_int 14)))]
22924   "TARGET_SSE2"
22925   "cvtsd2ss\t{%2, %0|%0, %2}"
22926   [(set_attr "type" "ssecvt")
22927    (set_attr "athlon_decode" "vector,double")
22928    (set_attr "mode" "SF")])
22929
22930 (define_insn "cvtss2sd"
22931   [(set (match_operand:V2DF 0 "register_operand" "=x")
22932         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
22933                         (float_extend:V2DF
22934                           (vec_select:V2SF
22935                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
22936                             (parallel [(const_int 0)
22937                                        (const_int 1)])))
22938                         (const_int 2)))]
22939   "TARGET_SSE2"
22940   "cvtss2sd\t{%2, %0|%0, %2}"
22941   [(set_attr "type" "ssecvt")
22942    (set_attr "mode" "DF")])
22943
22944 (define_insn "cvtpd2ps"
22945   [(set (match_operand:V4SF 0 "register_operand" "=x")
22946         (subreg:V4SF
22947           (vec_concat:V4SI
22948             (subreg:V2SI (float_truncate:V2SF
22949                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
22950             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
22951   "TARGET_SSE2"
22952   "cvtpd2ps\t{%1, %0|%0, %1}"
22953   [(set_attr "type" "ssecvt")
22954    (set_attr "mode" "V4SF")])
22955
22956 (define_insn "cvtps2pd"
22957   [(set (match_operand:V2DF 0 "register_operand" "=x")
22958         (float_extend:V2DF
22959           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
22960                            (parallel [(const_int 0)
22961                                       (const_int 1)]))))]
22962   "TARGET_SSE2"
22963   "cvtps2pd\t{%1, %0|%0, %1}"
22964   [(set_attr "type" "ssecvt")
22965    (set_attr "mode" "V2DF")])
22966
22967 ;; SSE2 variants of MMX insns
22968
22969 ;; MMX arithmetic
22970
22971 (define_insn "addv16qi3"
22972   [(set (match_operand:V16QI 0 "register_operand" "=x")
22973         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22974                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22975   "TARGET_SSE2"
22976   "paddb\t{%2, %0|%0, %2}"
22977   [(set_attr "type" "sseiadd")
22978    (set_attr "mode" "TI")])
22979
22980 (define_insn "addv8hi3"
22981   [(set (match_operand:V8HI 0 "register_operand" "=x")
22982         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22983                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22984   "TARGET_SSE2"
22985   "paddw\t{%2, %0|%0, %2}"
22986   [(set_attr "type" "sseiadd")
22987    (set_attr "mode" "TI")])
22988
22989 (define_insn "addv4si3"
22990   [(set (match_operand:V4SI 0 "register_operand" "=x")
22991         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22992                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22993   "TARGET_SSE2"
22994   "paddd\t{%2, %0|%0, %2}"
22995   [(set_attr "type" "sseiadd")
22996    (set_attr "mode" "TI")])
22997
22998 (define_insn "addv2di3"
22999   [(set (match_operand:V2DI 0 "register_operand" "=x")
23000         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
23001                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23002   "TARGET_SSE2"
23003   "paddq\t{%2, %0|%0, %2}"
23004   [(set_attr "type" "sseiadd")
23005    (set_attr "mode" "TI")])
23006
23007 (define_insn "ssaddv16qi3"
23008   [(set (match_operand:V16QI 0 "register_operand" "=x")
23009         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23010                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23011   "TARGET_SSE2"
23012   "paddsb\t{%2, %0|%0, %2}"
23013   [(set_attr "type" "sseiadd")
23014    (set_attr "mode" "TI")])
23015
23016 (define_insn "ssaddv8hi3"
23017   [(set (match_operand:V8HI 0 "register_operand" "=x")
23018         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23019                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23020   "TARGET_SSE2"
23021   "paddsw\t{%2, %0|%0, %2}"
23022   [(set_attr "type" "sseiadd")
23023    (set_attr "mode" "TI")])
23024
23025 (define_insn "usaddv16qi3"
23026   [(set (match_operand:V16QI 0 "register_operand" "=x")
23027         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23028                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23029   "TARGET_SSE2"
23030   "paddusb\t{%2, %0|%0, %2}"
23031   [(set_attr "type" "sseiadd")
23032    (set_attr "mode" "TI")])
23033
23034 (define_insn "usaddv8hi3"
23035   [(set (match_operand:V8HI 0 "register_operand" "=x")
23036         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23037                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23038   "TARGET_SSE2"
23039   "paddusw\t{%2, %0|%0, %2}"
23040   [(set_attr "type" "sseiadd")
23041    (set_attr "mode" "TI")])
23042
23043 (define_insn "subv16qi3"
23044   [(set (match_operand:V16QI 0 "register_operand" "=x")
23045         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23046                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23047   "TARGET_SSE2"
23048   "psubb\t{%2, %0|%0, %2}"
23049   [(set_attr "type" "sseiadd")
23050    (set_attr "mode" "TI")])
23051
23052 (define_insn "subv8hi3"
23053   [(set (match_operand:V8HI 0 "register_operand" "=x")
23054         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23055                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23056   "TARGET_SSE2"
23057   "psubw\t{%2, %0|%0, %2}"
23058   [(set_attr "type" "sseiadd")
23059    (set_attr "mode" "TI")])
23060
23061 (define_insn "subv4si3"
23062   [(set (match_operand:V4SI 0 "register_operand" "=x")
23063         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
23064                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23065   "TARGET_SSE2"
23066   "psubd\t{%2, %0|%0, %2}"
23067   [(set_attr "type" "sseiadd")
23068    (set_attr "mode" "TI")])
23069
23070 (define_insn "subv2di3"
23071   [(set (match_operand:V2DI 0 "register_operand" "=x")
23072         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
23073                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23074   "TARGET_SSE2"
23075   "psubq\t{%2, %0|%0, %2}"
23076   [(set_attr "type" "sseiadd")
23077    (set_attr "mode" "TI")])
23078
23079 (define_insn "sssubv16qi3"
23080   [(set (match_operand:V16QI 0 "register_operand" "=x")
23081         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23082                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23083   "TARGET_SSE2"
23084   "psubsb\t{%2, %0|%0, %2}"
23085   [(set_attr "type" "sseiadd")
23086    (set_attr "mode" "TI")])
23087
23088 (define_insn "sssubv8hi3"
23089   [(set (match_operand:V8HI 0 "register_operand" "=x")
23090         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23091                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23092   "TARGET_SSE2"
23093   "psubsw\t{%2, %0|%0, %2}"
23094   [(set_attr "type" "sseiadd")
23095    (set_attr "mode" "TI")])
23096
23097 (define_insn "ussubv16qi3"
23098   [(set (match_operand:V16QI 0 "register_operand" "=x")
23099         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23100                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23101   "TARGET_SSE2"
23102   "psubusb\t{%2, %0|%0, %2}"
23103   [(set_attr "type" "sseiadd")
23104    (set_attr "mode" "TI")])
23105
23106 (define_insn "ussubv8hi3"
23107   [(set (match_operand:V8HI 0 "register_operand" "=x")
23108         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23109                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23110   "TARGET_SSE2"
23111   "psubusw\t{%2, %0|%0, %2}"
23112   [(set_attr "type" "sseiadd")
23113    (set_attr "mode" "TI")])
23114
23115 (define_insn "mulv8hi3"
23116   [(set (match_operand:V8HI 0 "register_operand" "=x")
23117         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
23118                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23119   "TARGET_SSE2"
23120   "pmullw\t{%2, %0|%0, %2}"
23121   [(set_attr "type" "sseimul")
23122    (set_attr "mode" "TI")])
23123
23124 (define_insn "smulv8hi3_highpart"
23125   [(set (match_operand:V8HI 0 "register_operand" "=x")
23126         (truncate:V8HI
23127          (lshiftrt:V8SI
23128           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23129                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23130           (const_int 16))))]
23131   "TARGET_SSE2"
23132   "pmulhw\t{%2, %0|%0, %2}"
23133   [(set_attr "type" "sseimul")
23134    (set_attr "mode" "TI")])
23135
23136 (define_insn "umulv8hi3_highpart"
23137   [(set (match_operand:V8HI 0 "register_operand" "=x")
23138         (truncate:V8HI
23139          (lshiftrt:V8SI
23140           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23141                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23142           (const_int 16))))]
23143   "TARGET_SSE2"
23144   "pmulhuw\t{%2, %0|%0, %2}"
23145   [(set_attr "type" "sseimul")
23146    (set_attr "mode" "TI")])
23147
23148 (define_insn "sse2_umulsidi3"
23149   [(set (match_operand:DI 0 "register_operand" "=y")
23150         (mult:DI (zero_extend:DI (vec_select:SI
23151                                   (match_operand:V2SI 1 "register_operand" "0")
23152                                   (parallel [(const_int 0)])))
23153                  (zero_extend:DI (vec_select:SI
23154                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
23155                                   (parallel [(const_int 0)])))))]
23156   "TARGET_SSE2"
23157   "pmuludq\t{%2, %0|%0, %2}"
23158   [(set_attr "type" "mmxmul")
23159    (set_attr "mode" "DI")])
23160
23161 (define_insn "sse2_umulv2siv2di3"
23162   [(set (match_operand:V2DI 0 "register_operand" "=x")
23163         (mult:V2DI (zero_extend:V2DI
23164                      (vec_select:V2SI
23165                        (match_operand:V4SI 1 "register_operand" "0")
23166                        (parallel [(const_int 0) (const_int 2)])))
23167                    (zero_extend:V2DI
23168                      (vec_select:V2SI
23169                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
23170                        (parallel [(const_int 0) (const_int 2)])))))]
23171   "TARGET_SSE2"
23172   "pmuludq\t{%2, %0|%0, %2}"
23173   [(set_attr "type" "sseimul")
23174    (set_attr "mode" "TI")])
23175
23176 (define_insn "sse2_pmaddwd"
23177   [(set (match_operand:V4SI 0 "register_operand" "=x")
23178         (plus:V4SI
23179          (mult:V4SI
23180           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23181                                              (parallel [(const_int 0)
23182                                                         (const_int 2)
23183                                                         (const_int 4)
23184                                                         (const_int 6)])))
23185           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23186                                              (parallel [(const_int 0)
23187                                                         (const_int 2)
23188                                                         (const_int 4)
23189                                                         (const_int 6)]))))
23190          (mult:V4SI
23191           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23192                                              (parallel [(const_int 1)
23193                                                         (const_int 3)
23194                                                         (const_int 5)
23195                                                         (const_int 7)])))
23196           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23197                                              (parallel [(const_int 1)
23198                                                         (const_int 3)
23199                                                         (const_int 5)
23200                                                         (const_int 7)]))))))]
23201   "TARGET_SSE2"
23202   "pmaddwd\t{%2, %0|%0, %2}"
23203   [(set_attr "type" "sseiadd")
23204    (set_attr "mode" "TI")])
23205
23206 ;; Same as pxor, but don't show input operands so that we don't think
23207 ;; they are live.
23208 (define_insn "sse2_clrti"
23209   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23210   "TARGET_SSE2"
23211 {
23212   if (get_attr_mode (insn) == MODE_TI)
23213     return "pxor\t%0, %0";
23214   else
23215     return "xorps\t%0, %0";
23216 }
23217   [(set_attr "type" "ssemov")
23218    (set_attr "memory" "none")
23219    (set (attr "mode")
23220               (if_then_else
23221                 (ne (symbol_ref "optimize_size")
23222                     (const_int 0))
23223                 (const_string "V4SF")
23224                 (const_string "TI")))])
23225
23226 ;; MMX unsigned averages/sum of absolute differences
23227
23228 (define_insn "sse2_uavgv16qi3"
23229   [(set (match_operand:V16QI 0 "register_operand" "=x")
23230         (ashiftrt:V16QI
23231          (plus:V16QI (plus:V16QI
23232                      (match_operand:V16QI 1 "register_operand" "0")
23233                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23234                      (const_vector:V16QI [(const_int 1) (const_int 1)
23235                                           (const_int 1) (const_int 1)
23236                                           (const_int 1) (const_int 1)
23237                                           (const_int 1) (const_int 1)
23238                                           (const_int 1) (const_int 1)
23239                                           (const_int 1) (const_int 1)
23240                                           (const_int 1) (const_int 1)
23241                                           (const_int 1) (const_int 1)]))
23242          (const_int 1)))]
23243   "TARGET_SSE2"
23244   "pavgb\t{%2, %0|%0, %2}"
23245   [(set_attr "type" "sseiadd")
23246    (set_attr "mode" "TI")])
23247
23248 (define_insn "sse2_uavgv8hi3"
23249   [(set (match_operand:V8HI 0 "register_operand" "=x")
23250         (ashiftrt:V8HI
23251          (plus:V8HI (plus:V8HI
23252                      (match_operand:V8HI 1 "register_operand" "0")
23253                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23254                     (const_vector:V8HI [(const_int 1) (const_int 1)
23255                                         (const_int 1) (const_int 1)
23256                                         (const_int 1) (const_int 1)
23257                                         (const_int 1) (const_int 1)]))
23258          (const_int 1)))]
23259   "TARGET_SSE2"
23260   "pavgw\t{%2, %0|%0, %2}"
23261   [(set_attr "type" "sseiadd")
23262    (set_attr "mode" "TI")])
23263
23264 ;; @@@ this isn't the right representation.
23265 (define_insn "sse2_psadbw"
23266   [(set (match_operand:V2DI 0 "register_operand" "=x")
23267         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23268                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23269                      UNSPEC_PSADBW))]
23270   "TARGET_SSE2"
23271   "psadbw\t{%2, %0|%0, %2}"
23272   [(set_attr "type" "sseiadd")
23273    (set_attr "mode" "TI")])
23274
23275
23276 ;; MMX insert/extract/shuffle
23277
23278 (define_insn "sse2_pinsrw"
23279   [(set (match_operand:V8HI 0 "register_operand" "=x")
23280         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
23281                         (vec_duplicate:V8HI
23282                          (truncate:HI
23283                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
23284                         (match_operand:SI 3 "const_0_to_255_operand" "N")))]
23285   "TARGET_SSE2"
23286   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
23287   [(set_attr "type" "ssecvt")
23288    (set_attr "mode" "TI")])
23289
23290 (define_insn "sse2_pextrw"
23291   [(set (match_operand:SI 0 "register_operand" "=r")
23292         (zero_extend:SI
23293           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23294                          (parallel
23295                           [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23296   "TARGET_SSE2"
23297   "pextrw\t{%2, %1, %0|%0, %1, %2}"
23298   [(set_attr "type" "ssecvt")
23299    (set_attr "mode" "TI")])
23300
23301 (define_insn "sse2_pshufd"
23302   [(set (match_operand:V4SI 0 "register_operand" "=x")
23303         (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23304                       (match_operand:SI 2 "immediate_operand" "i")]
23305                      UNSPEC_SHUFFLE))]
23306   "TARGET_SSE2"
23307   "pshufd\t{%2, %1, %0|%0, %1, %2}"
23308   [(set_attr "type" "ssecvt")
23309    (set_attr "mode" "TI")])
23310
23311 (define_insn "sse2_pshuflw"
23312   [(set (match_operand:V8HI 0 "register_operand" "=x")
23313         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23314                       (match_operand:SI 2 "immediate_operand" "i")]
23315                      UNSPEC_PSHUFLW))]
23316   "TARGET_SSE2"
23317   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23318   [(set_attr "type" "ssecvt")
23319    (set_attr "mode" "TI")])
23320
23321 (define_insn "sse2_pshufhw"
23322   [(set (match_operand:V8HI 0 "register_operand" "=x")
23323         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23324                       (match_operand:SI 2 "immediate_operand" "i")]
23325                      UNSPEC_PSHUFHW))]
23326   "TARGET_SSE2"
23327   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23328   [(set_attr "type" "ssecvt")
23329    (set_attr "mode" "TI")])
23330
23331 ;; MMX mask-generating comparisons
23332
23333 (define_insn "eqv16qi3"
23334   [(set (match_operand:V16QI 0 "register_operand" "=x")
23335         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23336                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23337   "TARGET_SSE2"
23338   "pcmpeqb\t{%2, %0|%0, %2}"
23339   [(set_attr "type" "ssecmp")
23340    (set_attr "mode" "TI")])
23341
23342 (define_insn "eqv8hi3"
23343   [(set (match_operand:V8HI 0 "register_operand" "=x")
23344         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23345                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23346   "TARGET_SSE2"
23347   "pcmpeqw\t{%2, %0|%0, %2}"
23348   [(set_attr "type" "ssecmp")
23349    (set_attr "mode" "TI")])
23350
23351 (define_insn "eqv4si3"
23352   [(set (match_operand:V4SI 0 "register_operand" "=x")
23353         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23354                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23355   "TARGET_SSE2"
23356   "pcmpeqd\t{%2, %0|%0, %2}"
23357   [(set_attr "type" "ssecmp")
23358    (set_attr "mode" "TI")])
23359
23360 (define_insn "gtv16qi3"
23361   [(set (match_operand:V16QI 0 "register_operand" "=x")
23362         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23363                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23364   "TARGET_SSE2"
23365   "pcmpgtb\t{%2, %0|%0, %2}"
23366   [(set_attr "type" "ssecmp")
23367    (set_attr "mode" "TI")])
23368
23369 (define_insn "gtv8hi3"
23370   [(set (match_operand:V8HI 0 "register_operand" "=x")
23371         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23372                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23373   "TARGET_SSE2"
23374   "pcmpgtw\t{%2, %0|%0, %2}"
23375   [(set_attr "type" "ssecmp")
23376    (set_attr "mode" "TI")])
23377
23378 (define_insn "gtv4si3"
23379   [(set (match_operand:V4SI 0 "register_operand" "=x")
23380         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23381                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23382   "TARGET_SSE2"
23383   "pcmpgtd\t{%2, %0|%0, %2}"
23384   [(set_attr "type" "ssecmp")
23385    (set_attr "mode" "TI")])
23386
23387
23388 ;; MMX max/min insns
23389
23390 (define_insn "umaxv16qi3"
23391   [(set (match_operand:V16QI 0 "register_operand" "=x")
23392         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23393                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23394   "TARGET_SSE2"
23395   "pmaxub\t{%2, %0|%0, %2}"
23396   [(set_attr "type" "sseiadd")
23397    (set_attr "mode" "TI")])
23398
23399 (define_insn "smaxv8hi3"
23400   [(set (match_operand:V8HI 0 "register_operand" "=x")
23401         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23402                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23403   "TARGET_SSE2"
23404   "pmaxsw\t{%2, %0|%0, %2}"
23405   [(set_attr "type" "sseiadd")
23406    (set_attr "mode" "TI")])
23407
23408 (define_insn "uminv16qi3"
23409   [(set (match_operand:V16QI 0 "register_operand" "=x")
23410         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23411                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23412   "TARGET_SSE2"
23413   "pminub\t{%2, %0|%0, %2}"
23414   [(set_attr "type" "sseiadd")
23415    (set_attr "mode" "TI")])
23416
23417 (define_insn "sminv8hi3"
23418   [(set (match_operand:V8HI 0 "register_operand" "=x")
23419         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23420                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23421   "TARGET_SSE2"
23422   "pminsw\t{%2, %0|%0, %2}"
23423   [(set_attr "type" "sseiadd")
23424    (set_attr "mode" "TI")])
23425
23426
23427 ;; MMX shifts
23428
23429 (define_insn "ashrv8hi3"
23430   [(set (match_operand:V8HI 0 "register_operand" "=x")
23431         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23432                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23433   "TARGET_SSE2"
23434   "psraw\t{%2, %0|%0, %2}"
23435   [(set_attr "type" "sseishft")
23436    (set_attr "mode" "TI")])
23437
23438 (define_insn "ashrv4si3"
23439   [(set (match_operand:V4SI 0 "register_operand" "=x")
23440         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23441                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23442   "TARGET_SSE2"
23443   "psrad\t{%2, %0|%0, %2}"
23444   [(set_attr "type" "sseishft")
23445    (set_attr "mode" "TI")])
23446
23447 (define_insn "lshrv8hi3"
23448   [(set (match_operand:V8HI 0 "register_operand" "=x")
23449         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23450                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23451   "TARGET_SSE2"
23452   "psrlw\t{%2, %0|%0, %2}"
23453   [(set_attr "type" "sseishft")
23454    (set_attr "mode" "TI")])
23455
23456 (define_insn "lshrv4si3"
23457   [(set (match_operand:V4SI 0 "register_operand" "=x")
23458         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23459                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23460   "TARGET_SSE2"
23461   "psrld\t{%2, %0|%0, %2}"
23462   [(set_attr "type" "sseishft")
23463    (set_attr "mode" "TI")])
23464
23465 (define_insn "lshrv2di3"
23466   [(set (match_operand:V2DI 0 "register_operand" "=x")
23467         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23468                        (match_operand:SI 2 "nonmemory_operand" "xi")))]
23469   "TARGET_SSE2"
23470   "psrlq\t{%2, %0|%0, %2}"
23471   [(set_attr "type" "sseishft")
23472    (set_attr "mode" "TI")])
23473
23474 (define_insn "ashlv8hi3"
23475   [(set (match_operand:V8HI 0 "register_operand" "=x")
23476         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23477                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23478   "TARGET_SSE2"
23479   "psllw\t{%2, %0|%0, %2}"
23480   [(set_attr "type" "sseishft")
23481    (set_attr "mode" "TI")])
23482
23483 (define_insn "ashlv4si3"
23484   [(set (match_operand:V4SI 0 "register_operand" "=x")
23485         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23486                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23487   "TARGET_SSE2"
23488   "pslld\t{%2, %0|%0, %2}"
23489   [(set_attr "type" "sseishft")
23490    (set_attr "mode" "TI")])
23491
23492 (define_insn "ashlv2di3"
23493   [(set (match_operand:V2DI 0 "register_operand" "=x")
23494         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23495                      (match_operand:SI 2 "nonmemory_operand" "xi")))]
23496   "TARGET_SSE2"
23497   "psllq\t{%2, %0|%0, %2}"
23498   [(set_attr "type" "sseishft")
23499    (set_attr "mode" "TI")])
23500
23501 (define_insn "ashrv8hi3_ti"
23502   [(set (match_operand:V8HI 0 "register_operand" "=x")
23503         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23504                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23505   "TARGET_SSE2"
23506   "psraw\t{%2, %0|%0, %2}"
23507   [(set_attr "type" "sseishft")
23508    (set_attr "mode" "TI")])
23509
23510 (define_insn "ashrv4si3_ti"
23511   [(set (match_operand:V4SI 0 "register_operand" "=x")
23512         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23513                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23514   "TARGET_SSE2"
23515   "psrad\t{%2, %0|%0, %2}"
23516   [(set_attr "type" "sseishft")
23517    (set_attr "mode" "TI")])
23518
23519 (define_insn "lshrv8hi3_ti"
23520   [(set (match_operand:V8HI 0 "register_operand" "=x")
23521         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23522                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23523   "TARGET_SSE2"
23524   "psrlw\t{%2, %0|%0, %2}"
23525   [(set_attr "type" "sseishft")
23526    (set_attr "mode" "TI")])
23527
23528 (define_insn "lshrv4si3_ti"
23529   [(set (match_operand:V4SI 0 "register_operand" "=x")
23530         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23531                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23532   "TARGET_SSE2"
23533   "psrld\t{%2, %0|%0, %2}"
23534   [(set_attr "type" "sseishft")
23535    (set_attr "mode" "TI")])
23536
23537 (define_insn "lshrv2di3_ti"
23538   [(set (match_operand:V2DI 0 "register_operand" "=x")
23539         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23540                        (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23541   "TARGET_SSE2"
23542   "psrlq\t{%2, %0|%0, %2}"
23543   [(set_attr "type" "sseishft")
23544    (set_attr "mode" "TI")])
23545
23546 (define_insn "ashlv8hi3_ti"
23547   [(set (match_operand:V8HI 0 "register_operand" "=x")
23548         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23549                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23550   "TARGET_SSE2"
23551   "psllw\t{%2, %0|%0, %2}"
23552   [(set_attr "type" "sseishft")
23553    (set_attr "mode" "TI")])
23554
23555 (define_insn "ashlv4si3_ti"
23556   [(set (match_operand:V4SI 0 "register_operand" "=x")
23557         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23558                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23559   "TARGET_SSE2"
23560   "pslld\t{%2, %0|%0, %2}"
23561   [(set_attr "type" "sseishft")
23562    (set_attr "mode" "TI")])
23563
23564 (define_insn "ashlv2di3_ti"
23565   [(set (match_operand:V2DI 0 "register_operand" "=x")
23566         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23567                      (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23568   "TARGET_SSE2"
23569   "psllq\t{%2, %0|%0, %2}"
23570   [(set_attr "type" "sseishft")
23571    (set_attr "mode" "TI")])
23572
23573 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
23574 ;; we wouldn't need here it since we never generate TImode arithmetic.
23575
23576 ;; There has to be some kind of prize for the weirdest new instruction...
23577 (define_insn "sse2_ashlti3"
23578   [(set (match_operand:TI 0 "register_operand" "=x")
23579         (unspec:TI
23580          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23581                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23582                                (const_int 8)))] UNSPEC_NOP))]
23583   "TARGET_SSE2"
23584   "pslldq\t{%2, %0|%0, %2}"
23585   [(set_attr "type" "sseishft")
23586    (set_attr "mode" "TI")])
23587
23588 (define_insn "sse2_lshrti3"
23589   [(set (match_operand:TI 0 "register_operand" "=x")
23590         (unspec:TI
23591          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23592                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23593                                 (const_int 8)))] UNSPEC_NOP))]
23594   "TARGET_SSE2"
23595   "psrldq\t{%2, %0|%0, %2}"
23596   [(set_attr "type" "sseishft")
23597    (set_attr "mode" "TI")])
23598
23599 ;; SSE unpack
23600
23601 (define_insn "sse2_unpckhpd"
23602   [(set (match_operand:V2DF 0 "register_operand" "=x")
23603         (vec_concat:V2DF
23604          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23605                         (parallel [(const_int 1)]))
23606          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23607                         (parallel [(const_int 1)]))))]
23608   "TARGET_SSE2"
23609   "unpckhpd\t{%2, %0|%0, %2}"
23610   [(set_attr "type" "ssecvt")
23611    (set_attr "mode" "V2DF")])
23612
23613 (define_insn "sse2_unpcklpd"
23614   [(set (match_operand:V2DF 0 "register_operand" "=x")
23615         (vec_concat:V2DF
23616          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23617                         (parallel [(const_int 0)]))
23618          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23619                         (parallel [(const_int 0)]))))]
23620   "TARGET_SSE2"
23621   "unpcklpd\t{%2, %0|%0, %2}"
23622   [(set_attr "type" "ssecvt")
23623    (set_attr "mode" "V2DF")])
23624
23625 ;; MMX pack/unpack insns.
23626
23627 (define_insn "sse2_packsswb"
23628   [(set (match_operand:V16QI 0 "register_operand" "=x")
23629         (vec_concat:V16QI
23630          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23631          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23632   "TARGET_SSE2"
23633   "packsswb\t{%2, %0|%0, %2}"
23634   [(set_attr "type" "ssecvt")
23635    (set_attr "mode" "TI")])
23636
23637 (define_insn "sse2_packssdw"
23638   [(set (match_operand:V8HI 0 "register_operand" "=x")
23639         (vec_concat:V8HI
23640          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23641          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23642   "TARGET_SSE2"
23643   "packssdw\t{%2, %0|%0, %2}"
23644   [(set_attr "type" "ssecvt")
23645    (set_attr "mode" "TI")])
23646
23647 (define_insn "sse2_packuswb"
23648   [(set (match_operand:V16QI 0 "register_operand" "=x")
23649         (vec_concat:V16QI
23650          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23651          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23652   "TARGET_SSE2"
23653   "packuswb\t{%2, %0|%0, %2}"
23654   [(set_attr "type" "ssecvt")
23655    (set_attr "mode" "TI")])
23656
23657 (define_insn "sse2_punpckhbw"
23658   [(set (match_operand:V16QI 0 "register_operand" "=x")
23659         (vec_merge:V16QI
23660          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23661                            (parallel [(const_int 8) (const_int 0)
23662                                       (const_int 9) (const_int 1)
23663                                       (const_int 10) (const_int 2)
23664                                       (const_int 11) (const_int 3)
23665                                       (const_int 12) (const_int 4)
23666                                       (const_int 13) (const_int 5)
23667                                       (const_int 14) (const_int 6)
23668                                       (const_int 15) (const_int 7)]))
23669          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23670                            (parallel [(const_int 0) (const_int 8)
23671                                       (const_int 1) (const_int 9)
23672                                       (const_int 2) (const_int 10)
23673                                       (const_int 3) (const_int 11)
23674                                       (const_int 4) (const_int 12)
23675                                       (const_int 5) (const_int 13)
23676                                       (const_int 6) (const_int 14)
23677                                       (const_int 7) (const_int 15)]))
23678          (const_int 21845)))]
23679   "TARGET_SSE2"
23680   "punpckhbw\t{%2, %0|%0, %2}"
23681   [(set_attr "type" "ssecvt")
23682    (set_attr "mode" "TI")])
23683
23684 (define_insn "sse2_punpckhwd"
23685   [(set (match_operand:V8HI 0 "register_operand" "=x")
23686         (vec_merge:V8HI
23687          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23688                           (parallel [(const_int 4) (const_int 0)
23689                                      (const_int 5) (const_int 1)
23690                                      (const_int 6) (const_int 2)
23691                                      (const_int 7) (const_int 3)]))
23692          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23693                           (parallel [(const_int 0) (const_int 4)
23694                                      (const_int 1) (const_int 5)
23695                                      (const_int 2) (const_int 6)
23696                                      (const_int 3) (const_int 7)]))
23697          (const_int 85)))]
23698   "TARGET_SSE2"
23699   "punpckhwd\t{%2, %0|%0, %2}"
23700   [(set_attr "type" "ssecvt")
23701    (set_attr "mode" "TI")])
23702
23703 (define_insn "sse2_punpckhdq"
23704   [(set (match_operand:V4SI 0 "register_operand" "=x")
23705         (vec_merge:V4SI
23706          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23707                           (parallel [(const_int 2) (const_int 0)
23708                                      (const_int 3) (const_int 1)]))
23709          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23710                           (parallel [(const_int 0) (const_int 2)
23711                                      (const_int 1) (const_int 3)]))
23712          (const_int 5)))]
23713   "TARGET_SSE2"
23714   "punpckhdq\t{%2, %0|%0, %2}"
23715   [(set_attr "type" "ssecvt")
23716    (set_attr "mode" "TI")])
23717
23718 (define_insn "sse2_punpcklbw"
23719   [(set (match_operand:V16QI 0 "register_operand" "=x")
23720         (vec_merge:V16QI
23721          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23722                            (parallel [(const_int 0) (const_int 8)
23723                                       (const_int 1) (const_int 9)
23724                                       (const_int 2) (const_int 10)
23725                                       (const_int 3) (const_int 11)
23726                                       (const_int 4) (const_int 12)
23727                                       (const_int 5) (const_int 13)
23728                                       (const_int 6) (const_int 14)
23729                                       (const_int 7) (const_int 15)]))
23730          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23731                            (parallel [(const_int 8) (const_int 0)
23732                                       (const_int 9) (const_int 1)
23733                                       (const_int 10) (const_int 2)
23734                                       (const_int 11) (const_int 3)
23735                                       (const_int 12) (const_int 4)
23736                                       (const_int 13) (const_int 5)
23737                                       (const_int 14) (const_int 6)
23738                                       (const_int 15) (const_int 7)]))
23739          (const_int 21845)))]
23740   "TARGET_SSE2"
23741   "punpcklbw\t{%2, %0|%0, %2}"
23742   [(set_attr "type" "ssecvt")
23743    (set_attr "mode" "TI")])
23744
23745 (define_insn "sse2_punpcklwd"
23746   [(set (match_operand:V8HI 0 "register_operand" "=x")
23747         (vec_merge:V8HI
23748          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23749                           (parallel [(const_int 0) (const_int 4)
23750                                      (const_int 1) (const_int 5)
23751                                      (const_int 2) (const_int 6)
23752                                      (const_int 3) (const_int 7)]))
23753          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23754                           (parallel [(const_int 4) (const_int 0)
23755                                      (const_int 5) (const_int 1)
23756                                      (const_int 6) (const_int 2)
23757                                      (const_int 7) (const_int 3)]))
23758          (const_int 85)))]
23759   "TARGET_SSE2"
23760   "punpcklwd\t{%2, %0|%0, %2}"
23761   [(set_attr "type" "ssecvt")
23762    (set_attr "mode" "TI")])
23763
23764 (define_insn "sse2_punpckldq"
23765   [(set (match_operand:V4SI 0 "register_operand" "=x")
23766         (vec_merge:V4SI
23767          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23768                           (parallel [(const_int 0) (const_int 2)
23769                                      (const_int 1) (const_int 3)]))
23770          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23771                           (parallel [(const_int 2) (const_int 0)
23772                                      (const_int 3) (const_int 1)]))
23773          (const_int 5)))]
23774   "TARGET_SSE2"
23775   "punpckldq\t{%2, %0|%0, %2}"
23776   [(set_attr "type" "ssecvt")
23777    (set_attr "mode" "TI")])
23778
23779 (define_insn "sse2_punpcklqdq"
23780   [(set (match_operand:V2DI 0 "register_operand" "=x")
23781         (vec_merge:V2DI
23782          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23783                           (parallel [(const_int 1)
23784                                      (const_int 0)]))
23785          (match_operand:V2DI 1 "register_operand" "0")
23786          (const_int 1)))]
23787   "TARGET_SSE2"
23788   "punpcklqdq\t{%2, %0|%0, %2}"
23789   [(set_attr "type" "ssecvt")
23790    (set_attr "mode" "TI")])
23791
23792 (define_insn "sse2_punpckhqdq"
23793   [(set (match_operand:V2DI 0 "register_operand" "=x")
23794         (vec_merge:V2DI
23795          (match_operand:V2DI 1 "register_operand" "0")
23796          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23797                           (parallel [(const_int 1)
23798                                      (const_int 0)]))
23799          (const_int 1)))]
23800   "TARGET_SSE2"
23801   "punpckhqdq\t{%2, %0|%0, %2}"
23802   [(set_attr "type" "ssecvt")
23803    (set_attr "mode" "TI")])
23804
23805 ;; SSE2 moves
23806
23807 (define_insn "sse2_movapd"
23808   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23809         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23810                      UNSPEC_MOVA))]
23811   "TARGET_SSE2
23812    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23813   "movapd\t{%1, %0|%0, %1}"
23814   [(set_attr "type" "ssemov")
23815    (set_attr "mode" "V2DF")])
23816
23817 (define_insn "sse2_movupd"
23818   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23819         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23820                      UNSPEC_MOVU))]
23821   "TARGET_SSE2
23822    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23823   "movupd\t{%1, %0|%0, %1}"
23824   [(set_attr "type" "ssecvt")
23825    (set_attr "mode" "V2DF")])
23826
23827 (define_insn "sse2_movdqa"
23828   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23829         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23830                        UNSPEC_MOVA))]
23831   "TARGET_SSE2
23832    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23833   "movdqa\t{%1, %0|%0, %1}"
23834   [(set_attr "type" "ssemov")
23835    (set_attr "mode" "TI")])
23836
23837 (define_insn "sse2_movdqu"
23838   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23839         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23840                        UNSPEC_MOVU))]
23841   "TARGET_SSE2
23842    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23843   "movdqu\t{%1, %0|%0, %1}"
23844   [(set_attr "type" "ssecvt")
23845    (set_attr "mode" "TI")])
23846
23847 (define_insn "sse2_movdq2q"
23848   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23849         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23850                        (parallel [(const_int 0)])))]
23851   "TARGET_SSE2 && !TARGET_64BIT"
23852   "@
23853    movq\t{%1, %0|%0, %1}
23854    movdq2q\t{%1, %0|%0, %1}"
23855   [(set_attr "type" "ssecvt")
23856    (set_attr "mode" "TI")])
23857
23858 (define_insn "sse2_movdq2q_rex64"
23859   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23860         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23861                        (parallel [(const_int 0)])))]
23862   "TARGET_SSE2 && TARGET_64BIT"
23863   "@
23864    movq\t{%1, %0|%0, %1}
23865    movdq2q\t{%1, %0|%0, %1}
23866    movd\t{%1, %0|%0, %1}"
23867   [(set_attr "type" "ssecvt")
23868    (set_attr "mode" "TI")])
23869
23870 (define_insn "sse2_movq2dq"
23871   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23872         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23873                          (const_int 0)))]
23874   "TARGET_SSE2 && !TARGET_64BIT"
23875   "@
23876    movq\t{%1, %0|%0, %1}
23877    movq2dq\t{%1, %0|%0, %1}"
23878   [(set_attr "type" "ssecvt,ssemov")
23879    (set_attr "mode" "TI")])
23880
23881 (define_insn "sse2_movq2dq_rex64"
23882   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23883         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23884                          (const_int 0)))]
23885   "TARGET_SSE2 && TARGET_64BIT"
23886   "@
23887    movq\t{%1, %0|%0, %1}
23888    movq2dq\t{%1, %0|%0, %1}
23889    movd\t{%1, %0|%0, %1}"
23890   [(set_attr "type" "ssecvt,ssemov,ssecvt")
23891    (set_attr "mode" "TI")])
23892
23893 (define_insn "sse2_movq"
23894   [(set (match_operand:V2DI 0 "register_operand" "=x")
23895         (vec_concat:V2DI (vec_select:DI
23896                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23897                           (parallel [(const_int 0)]))
23898                          (const_int 0)))]
23899   "TARGET_SSE2"
23900   "movq\t{%1, %0|%0, %1}"
23901   [(set_attr "type" "ssemov")
23902    (set_attr "mode" "TI")])
23903
23904 (define_insn "sse2_loadd"
23905   [(set (match_operand:V4SI 0 "register_operand" "=x")
23906         (vec_merge:V4SI
23907          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23908          (const_vector:V4SI [(const_int 0)
23909                              (const_int 0)
23910                              (const_int 0)
23911                              (const_int 0)])
23912          (const_int 1)))]
23913   "TARGET_SSE2"
23914   "movd\t{%1, %0|%0, %1}"
23915   [(set_attr "type" "ssemov")
23916    (set_attr "mode" "TI")])
23917
23918 (define_insn "sse2_stored"
23919   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23920         (vec_select:SI
23921          (match_operand:V4SI 1 "register_operand" "x")
23922          (parallel [(const_int 0)])))]
23923   "TARGET_SSE2"
23924   "movd\t{%1, %0|%0, %1}"
23925   [(set_attr "type" "ssemov")
23926    (set_attr "mode" "TI")])
23927
23928 (define_insn "sse2_movhpd"
23929   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23930         (vec_merge:V2DF
23931          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23932          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23933          (const_int 2)))]
23934   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23935   "movhpd\t{%2, %0|%0, %2}"
23936   [(set_attr "type" "ssecvt")
23937    (set_attr "mode" "V2DF")])
23938
23939 (define_expand "sse2_loadsd"
23940   [(match_operand:V2DF 0 "register_operand" "")
23941    (match_operand:DF 1 "memory_operand" "")]
23942   "TARGET_SSE2"
23943 {
23944   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
23945                                 CONST0_RTX (V2DFmode)));
23946   DONE;
23947 })
23948
23949 (define_insn "sse2_loadsd_1"
23950   [(set (match_operand:V2DF 0 "register_operand" "=x")
23951         (vec_merge:V2DF
23952          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
23953          (match_operand:V2DF 2 "const0_operand" "X")
23954          (const_int 1)))]
23955   "TARGET_SSE2"
23956   "movsd\t{%1, %0|%0, %1}"
23957   [(set_attr "type" "ssecvt")
23958    (set_attr "mode" "DF")])
23959
23960 (define_insn "sse2_movsd"
23961   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
23962         (vec_merge:V2DF
23963          (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
23964          (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
23965          (const_int 1)))]
23966   "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
23967   "@movsd\t{%2, %0|%0, %2}
23968     movlpd\t{%2, %0|%0, %2}
23969     movlpd\t{%2, %0|%0, %2}"
23970   [(set_attr "type" "ssecvt")
23971    (set_attr "mode" "DF,V2DF,V2DF")])
23972
23973 (define_insn "sse2_storesd"
23974   [(set (match_operand:DF 0 "memory_operand" "=m")
23975         (vec_select:DF
23976          (match_operand:V2DF 1 "register_operand" "x")
23977          (parallel [(const_int 0)])))]
23978   "TARGET_SSE2"
23979   "movsd\t{%1, %0|%0, %1}"
23980   [(set_attr "type" "ssecvt")
23981    (set_attr "mode" "DF")])
23982
23983 (define_insn "sse2_shufpd"
23984   [(set (match_operand:V2DF 0 "register_operand" "=x")
23985         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23986                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
23987                       (match_operand:SI 3 "immediate_operand" "i")]
23988                      UNSPEC_SHUFFLE))]
23989   "TARGET_SSE2"
23990   ;; @@@ check operand order for intel/nonintel syntax
23991   "shufpd\t{%3, %2, %0|%0, %2, %3}"
23992   [(set_attr "type" "ssecvt")
23993    (set_attr "mode" "V2DF")])
23994
23995 (define_insn "sse2_clflush"
23996   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
23997                     UNSPECV_CLFLUSH)]
23998   "TARGET_SSE2"
23999   "clflush\t%a0"
24000   [(set_attr "type" "sse")
24001    (set_attr "memory" "unknown")])
24002
24003 (define_expand "sse2_mfence"
24004   [(set (match_dup 0)
24005         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24006   "TARGET_SSE2"
24007 {
24008   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24009   MEM_VOLATILE_P (operands[0]) = 1;
24010 })
24011
24012 (define_insn "*mfence_insn"
24013   [(set (match_operand:BLK 0 "" "")
24014         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24015   "TARGET_SSE2"
24016   "mfence"
24017   [(set_attr "type" "sse")
24018    (set_attr "memory" "unknown")])
24019
24020 (define_expand "sse2_lfence"
24021   [(set (match_dup 0)
24022         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24023   "TARGET_SSE2"
24024 {
24025   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24026   MEM_VOLATILE_P (operands[0]) = 1;
24027 })
24028
24029 (define_insn "*lfence_insn"
24030   [(set (match_operand:BLK 0 "" "")
24031         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24032   "TARGET_SSE2"
24033   "lfence"
24034   [(set_attr "type" "sse")
24035    (set_attr "memory" "unknown")])
24036
24037 ;; SSE3
24038
24039 (define_insn "mwait"
24040   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24041                      (match_operand:SI 1 "register_operand" "c")]
24042                     UNSPECV_MWAIT)]
24043   "TARGET_SSE3"
24044   "mwait\t%0, %1"
24045   [(set_attr "length" "3")])
24046
24047 (define_insn "monitor"
24048   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24049                      (match_operand:SI 1 "register_operand" "c")
24050                      (match_operand:SI 2 "register_operand" "d")]
24051                     UNSPECV_MONITOR)]
24052   "TARGET_SSE3"
24053   "monitor\t%0, %1, %2"
24054   [(set_attr "length" "3")])
24055
24056 ;; SSE3 arithmetic
24057
24058 (define_insn "addsubv4sf3"
24059   [(set (match_operand:V4SF 0 "register_operand" "=x")
24060         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24061                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24062                      UNSPEC_ADDSUB))]
24063   "TARGET_SSE3"
24064   "addsubps\t{%2, %0|%0, %2}"
24065   [(set_attr "type" "sseadd")
24066    (set_attr "mode" "V4SF")])
24067
24068 (define_insn "addsubv2df3"
24069   [(set (match_operand:V2DF 0 "register_operand" "=x")
24070         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24071                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24072                      UNSPEC_ADDSUB))]
24073   "TARGET_SSE3"
24074   "addsubpd\t{%2, %0|%0, %2}"
24075   [(set_attr "type" "sseadd")
24076    (set_attr "mode" "V2DF")])
24077
24078 (define_insn "haddv4sf3"
24079   [(set (match_operand:V4SF 0 "register_operand" "=x")
24080         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24081                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24082                      UNSPEC_HADD))]
24083   "TARGET_SSE3"
24084   "haddps\t{%2, %0|%0, %2}"
24085   [(set_attr "type" "sseadd")
24086    (set_attr "mode" "V4SF")])
24087
24088 (define_insn "haddv2df3"
24089   [(set (match_operand:V2DF 0 "register_operand" "=x")
24090         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24091                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24092                      UNSPEC_HADD))]
24093   "TARGET_SSE3"
24094   "haddpd\t{%2, %0|%0, %2}"
24095   [(set_attr "type" "sseadd")
24096    (set_attr "mode" "V2DF")])
24097
24098 (define_insn "hsubv4sf3"
24099   [(set (match_operand:V4SF 0 "register_operand" "=x")
24100         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24101                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24102                      UNSPEC_HSUB))]
24103   "TARGET_SSE3"
24104   "hsubps\t{%2, %0|%0, %2}"
24105   [(set_attr "type" "sseadd")
24106    (set_attr "mode" "V4SF")])
24107
24108 (define_insn "hsubv2df3"
24109   [(set (match_operand:V2DF 0 "register_operand" "=x")
24110         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24111                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24112                      UNSPEC_HSUB))]
24113   "TARGET_SSE3"
24114   "hsubpd\t{%2, %0|%0, %2}"
24115   [(set_attr "type" "sseadd")
24116    (set_attr "mode" "V2DF")])
24117
24118 (define_insn "movshdup"
24119   [(set (match_operand:V4SF 0 "register_operand" "=x")
24120         (unspec:V4SF
24121          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
24122   "TARGET_SSE3"
24123   "movshdup\t{%1, %0|%0, %1}"
24124   [(set_attr "type" "sse")
24125    (set_attr "mode" "V4SF")])
24126
24127 (define_insn "movsldup"
24128   [(set (match_operand:V4SF 0 "register_operand" "=x")
24129         (unspec:V4SF
24130          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
24131   "TARGET_SSE3"
24132   "movsldup\t{%1, %0|%0, %1}"
24133   [(set_attr "type" "sse")
24134    (set_attr "mode" "V4SF")])
24135
24136 (define_insn "lddqu"
24137   [(set (match_operand:V16QI 0 "register_operand" "=x")
24138         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
24139                        UNSPEC_LDQQU))]
24140   "TARGET_SSE3"
24141   "lddqu\t{%1, %0|%0, %1}"
24142   [(set_attr "type" "ssecvt")
24143    (set_attr "mode" "TI")])
24144
24145 (define_insn "loadddup"
24146   [(set (match_operand:V2DF 0 "register_operand" "=x")
24147         (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
24148   "TARGET_SSE3"
24149   "movddup\t{%1, %0|%0, %1}"
24150   [(set_attr "type" "ssecvt")
24151    (set_attr "mode" "DF")])
24152
24153 (define_insn "movddup"
24154   [(set (match_operand:V2DF 0 "register_operand" "=x")
24155         (vec_duplicate:V2DF
24156          (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
24157                         (parallel [(const_int 0)]))))]
24158   "TARGET_SSE3"
24159   "movddup\t{%1, %0|%0, %1}"
24160   [(set_attr "type" "ssecvt")
24161    (set_attr "mode" "DF")])